Pull to refresh

Comments 9

Трэш какой-то с манипулированием значениями datetime через внутреннее представление — в качестве туториала я бы порекомендовал так делать в последнюю очередь! Если отрезать time от datetime, то лучше всего convert(datetime, convert(date, X)), проверка на диапазон, если уж нужен between — тоже переводом в date и включительным сравнением. Если нужно хранить datetime, а проверять эффективно по индексу чисто дату — делаем computed persisted поле типа date, и в формуле пишем convert(date, XXX, 1) — и по нему уже строим индекс. Вот этому учить надо с самого начала. А бойким авторам, которые дергают откуда-то слаборелевантный материал и публикуют его — совет: отдавать на статью просмотр/редактирование сначала специалистам в той области, откуда статья
Все по делу, но не судите строго автора, перевод ведь…
Я бы не судил, если бы это было мнение физического лица. Автор представляет компанию со слоганом «Цифровые навыки от ведущих экспертов» — и при этом публикует перевод материала, абсолютно оторванного от контекста, и, главное, неспособного научить правильным приемам работы с датами в MS-SQL. Я не поленился, зашел на отзовик посмотреть про этот Отус — результат на двойку с плюсом, собственно, как и эта статья
1. Robert Sheldon — довольно известный специалист по MS SQL.
2. Внутреннее представление здесь приведено всего лишь для изучения, а не для использования в коде.
3. «Если нужно хранить datetime, а проверять эффективно по индексу чисто дату — делаем computed persisted поле типа date, и в формуле пишем convert(date, XXX, 1) — и по нему уже строим индекс. Вот этому учить надо с самого начала. „
Как раз так не надо.
Проверка на диапазон с начала по конец суток — типовая задача, городить на каждое поле datetime вычисляемый столбец с индексом — ненужный overhead.
Ну-ну, если разовый запрос то соглашусь. Но если это типовая операция — выборка данных за конкретные сутки, и таких 100500 запросов в день, то без индекса будет очень тяжко.
Что именно тяжко?
пусть есть поле MyDate datetime с индексом по нему.
select .. where MyDateTime >= '20200211' and MyDateTime < '20200212'
Сорри, пропустил «вычисляемый» столбец. Сильно тяжко да, конечно не будет, но справедливости ради размер индекса будет все-таки меньше. И при очень большом количестве запросов к этому индексу и большом количестве данных, размер будет иметь значение, но 100% нужно это или нет может показать только конкретная нагрузка на конкретном железе.
Он может быть суперизвестным, но акцент в статье (намеренно, или это просто вырвано из контекста) сделан не на том. Ко всему прочему, статья старая — как минимум 10-летней давности, если в ней говорится, что специфические для MS SQL 2008 типы данных могут быть нам недоступны.

Учить нужно не биты переставлять в двоичном представлении, которое, к тому же, может поменяться в очередной версии RDBMS, а общим принципам работы с этим типом данных в контексте тех преимуществ и особенностей, которые дает именно СУБД — то есть работы с данными, как с множеством. Здесь же в основном идет жонглирование скалярами — что по сути не отличается от методов работы с соответствующими типами данных процедурных ЯП.

А вот особенности применения временных типов данных в контексте множеств — это действительно полезная тема именно для разработчиков СУБД. Например:
1. могу ли я сделать поле datetime/datetime2 первичным ключом? Чем это мне грозит?
2. могу ли я использовать datetime2 в качестве метки времени для детекции конкурентного изменения значений строк? Где здесь подводные камни? Почему когда мы говорим про временные типы данных в MS SQL, мы не упоминаем timestamp?
3. как эффективно сделать группировку по части даты/времени? Например, в логе событий сгруппировать их по году/неделе/дню/часу?
4. какие засады будут меня поджидать, если для хранения чисто дат я буду по привычке/незнанию использовать datetime? Как можно защититься встроенными средствами валидации данных MS SQL от таких ситуаций, если тип поля в таблице изменить нельзя?
5. как можно выровнять произвольную дату на первое или последнее число месяца?
6. как построить модель с историей данных и эффективно их выбирать на любую дату/дату-время в прошлом?
7. как в цепочке событий, отмеченных датой-временем, эффективно выбирать следующее/предыдущее событие?
8. как эффективно хранить, например, производственный календарь определенной страны, и быстро считать количество рабочих дней в произвольном диапазоне?
9. каким образом можно эффективно сериализовать массив дат?
10. каким образом записывать предикат выборки по диапазону дат, чтобы выборка была эффективной?
11. каким образом сгенерировать, например, ось дат для использования в разных выборках — скажем, 100 месяцев начиная с 1 января 2000 года?
Наиболее проработана система учета даты у Oracle. Учитывает всякие переходы с одного календаря на другой.

select date '1582-10-31' — date '1582-10-01' + 1 «Дней в октябре 1582г» from dual;
Выдаёт число 21

Но к сожалению добавленные секунды никто корректно не учитывает
wiki

select to_date('30.06.2016 23:59:60','dd.mm.yyyy hh24:mi:ss') from dual
ORA-01852: секунды должны изменяться от 0 до 59
Sign up to leave a comment.