2008 г.
Базы данных. Вводный курс
Сергей Кузнецов
Назад Содержание Вперёд
15.2.5. Типы даты и времени
Возможность сохранения в базе данных информации о дате и времени очень важна с практической точки зрения. Достаточно вспомнить взбудоражившую весь мир «проблему 2000 года», одним из основных источников которой было некорректное хранение дат в базах данных. В стандарте SQL поддержке средств работы с датой и временем уделяется большое внимание. В частности, поддерживаются специальные «темпоральные» типы данных DATE
, TIME
, TIMESTAMP
, TIME WITH TIME ZONE
и TIMESTAMP WITH TIME ZONE
. Коротко обсудим эти типы.
Тип даты
- Тип
DATE
. Значения этого типа состоят из компонентов-значений года, месяца и дня некоторой даты. Значение года состоит из четырех десятичных цифр и соответствует летоисчислению от Рождества Христова до 9999 г. Значение месяца состоит из двух десятичных цифр и варьируется от 01 до 12. Значение номера дня месяца состоит из двух десятичных цифр и варьируется от 01 до 31, хотя значение месяца даты может накладывать ограничения на возможность использования значений дня месяца 29, 30 и 31. В стандарте SQL не накладываются какие-либо ограничения на внутренний способ представления дат, используемый в реализации. При определении столбца типа DATE
указывается просто DATE
. - Литералы типа
DATE
представляются в виде строки «’yyyy-mm-dd’
», где символы y
, m
и d
должны изображать десятичные числа. Например, литерал DATE ’1949-04-08’
представляет дату 8 апреля 1949 г.
Типы времени
- Тип
TIME
. Значения этого параметризованного типа состоят из компонентов-значений часа, минуты и секунды некоторого времени суток. Значение часа состоит ровно из двух десятичных цифр и варьируется от 00 до 23. Значение минуты состоит из двух десятичных цифр и варьируется от 00 до 59. Основное значение секунды также состоит из двух цифр, но может включать дополнительные цифры, представляющие доли секунды. Так что в целом значение секунды варьируется от 00 до 61.999... В значении времени присутствуют две лишние секунды, поскольку Всемирная служба времени иногда добавляет две секунды к последней минуте года для синхронизации мирового времени с реальным. Решение о поддержке этих «високосных» секунд принимается на уровне реализации. Число цифр в доле секунды также определяется в реализации. В стандарте требуется только то, чтобы это число было не меньше шести. При определении столбца типа TIME
может указываться TIME (p)
(значение p
задает точность долей секунды) или просто TIME
(в этом случае доли секунды не учитываются). - Литералы типа
TIME
представляются в виде строки TIME ’hh:mm-ss:f...f’
, где символы h
, m
, s
и f
должны изображать десятичные числа. Например, литерал TIME ’16:33-20:333’
представляет время суток 16 часов 33 минуты 20 и 333 тысячных секунды.
Типы временной метки
- Тип
TIMESTAMP
. Значения этого параметризованного типа состоят из компонентов — значений года, месяца и дня некоторой даты, а также компонентов — значений часа, минуты и секунды некоторого времени суток (т. е. каждое значение задает некоторую абсолютную временную метку – отсюда название типа TIMESTAMP
). Число десятичных цифр в значениях-компонентах и ограничения этих значений такие же, как у значений типов DATE
и TIME
. При определении столбца типа TIMESTAMP
может указываться TIMESTAMP (p)
(значение p
задает точность долей секунды) или просто TIMESTAMP
(в этом случае, в отличие от типа данных TIME
, по умолчанию принимается, что в доли секунды используются шесть десятичных цифр). Максимально допустимое значение p
определяется в реализации. - Литералы типа
TIMESTAMP
представляются в виде строки TIMESTAMP ’yyyy-mm-dd hh:mm-ss:f...f’
, где символы y
, m
, d
, h
, m
, s
и f
должны изображать десятичные числа. Например, литерал TIMESTAMP ’1949-04-08 16:33-20:333’
представляет временную метку 16 часов 33 минуты 20 и 333 тысячных секунды 8 апреля 1949 г.
Типы времени и временной метки с временной зоной
- Тип
TIME WITH TIME ZONE
. Этот тип данных похож на тип TIME
с тем лишь отличием, что значения типа TIME WITH TIME ZONE
включают дополнительный компонент — значение, характеризующее смещение соответствующего времени относительно гринвичского времени (теперь его называют UTC – universal time coordinated). Деталей представления этого дополнительного компонента мы касаться не будем. - Тип
TIMESTAMP WITH TIME ZONE
. Этот тип данных отличается от типа TIMESTAMP
тем, что значения типа TIMESTAMP WITH TIME ZONE
включают дополнительный компонент-значение, характеризующее смещение соответствующего времени относительно гринвичского.
Типы временных интервалов
Вообще говоря, временным интервалом называется разность между двумя значениями даты или времени. В SQL определены две категории типов временных интервалов: «год-месяц» и «день-время суток». Временные интервалы языка SQL не привязываются к начальному и/или конечному значению даты/времени, а описывают только протяженность во времени. В общем случае при определении столбца типа временного интервала указывается INTERVAL start (p) [ TO end (q) ]
, где в качестве «start
» и «end
» могут задаваться YEAR
, MONTH
, DAY
, HOUR
, MINUTE
и SECOND
. Параметр p
задает требуемую точность лидирующего поля интервала (число десятичных цифр). Параметр q
может задаваться только в том случае, когда в качестве end
используется SECOND
, и указывает точность долей секунды. Если говорить более точно, возможны следующие вариации типов временных интервалов.
- Типы категории «год-месяц». Можно определить столбцы следующих типов:
INTERVAL YEAR
, INTERVAL YEAR (p)
(значения этих типов – временные интервалы в годах), INTERVAL MONTH
, INTERVAL MONTH (p)
(значения этих типов – временные интервалы в месяцах), INTERVAL YEAR TO MONTH
, INTERVAL YEAR (p) TO MONTH
(значения этих типов – временные интервалы в годах и месяцах). Если значение параметра p
не указывается явно, по умолчанию принимается его значение «2». - Типы категории «день-время суток». При определении столбца можно использовать следующие комбинации (для полноты перечислим все возможности):
INTERVAL DAY (p),
INTERVAL DAY,
INTERVAL DAY (p) TO HOUR,
INTERVAL DAY TO HOUR,
INTERVAL DAY (p) TO MINUTE,
INTERVAL DAY TO MINUTE,
INTERVAL DAY (p) TO SECOND (q),
INTERVAL DAY TO SECOND (q),
INTERVAL DAY (p) TO SECOND,
INTERVAL DAY TO SECOND,
INTERVAL HOUR (p),
INTERVAL HOUR, INTERVAL HOUR (p) TO MINUTE,
INTERVAL HOUR TO MINUTE,
INTERVAL HOUR (p) TO SECOND (q),
INTERVAL HOUR TO SECOND (q),
INTERVAL HOUR TO SECOND,
INTERVAL MINUTE (p),
INTERVAL MINUTE,
INTERVAL MINUTE (p) TO SECOND (q),
INTERVAL MINUTE TO SECOND (q),
INTERVAL MINUTE (p) TO SECOND,
INTERVAL MINUTE TO SECOND,
INTERVAL SECOND (p, q),
INTERVAL SECOND (p),
INTERVAL SECOND.
Если значение параметра p
не указывается явно, по умолчанию принимается его значение «2». Значением параметра q
по умолчанию является «6». - Приведем только один пример литерала одной из разновидностей типа
INTERVAL: INTERVAL ’10:20’ MINUTE TO SECOND
– временной интервал в 10 минут и 20 секунд. - Над значениями темпоральных типов могут выполняться арифметические операции, смысл которых определяется следующей таблицей:
Тип первого операнда | Операция | Тип второго операнда | Тип результата |
---|
Datetime | - | Datetime | Interval |
Datetime | + или - | Interval | Datetime |
Interval | + | Datetime | Datetime |
Interval | + или - | Interval | Interval |
Interval | * или / | Numeric | Interval |
Numeric | * | Interval | Interval |
Значения типов данных временных интервалов образуются при вычитании одного значения типа даты или времени суток из другого значения соответствующего типа. При добавлении интервального значения к значению типа даты/времени образуется новое значение типа даты/времени. Кроме того, значение интервального типа можно умножать и делить на числовые значения, получая новое значение интервального типа.
15.2.6. Булевский тип
При определении столбца булевского типа указывается просто спецификация BOOLEAN
. Булевский тип состоит из трех значений: true
, false
и unknown
(соответствующие литералы обозначаются TRUE
, FALSE
и UNKNOWN
).83) Поддерживается возможность построения булевских выражений, которые вычисляются в трехзначной логике. Таблицы истинности основных логических операций показаны на рис. 15.2.
Рис. 15.2. Таблицы истинности основных логических операций в трехзначной логике
15.2.7. Типы коллекций
Начиная с SQL:1999, в языке поддерживается возможность использования типов данных, значения которых являются коллекциями значений некоторых других типов. Обычно под термином коллекция понимается одно из следующих образований: массив, список, множество и мультимножество. В варианте SQL:1999, принятом в 1999 г., были специфицированы только типы массивов. В новом стандарте SQL:2003 появилась спецификация типа мультимножества.
Типы массивов
Любой возможный тип массива получается путем применения конструктора типов ARRAY
. При определении столбца, значения которого должны принадлежать некоторому типу массива, используется конструкция dt ARRAY [ mc ]
, где dt
специфицирует некоторый допустимый в SQL тип данных, а mc
является литералом некоторого точного числового типа с нулевой длиной шкалы и определяет максимальное число элементов в значении типа массива (в терминологии SQL:1999 это значение называется максимальной кардинальностью массива). В стандарте SQL:1999 многомерные массивы и массивы массивов не поддерживались. Однако в стандарте SQL:2003 это ограничение было снято, и теперь типом элементов любого типа коллекций может быть любой допустимый в SQL тип данных, кроме самого конструируемого типа коллекции.
Элементам каждого значения типа массива соответствуют их порядковые номера, называемые индексами. Значение индекса всегда должно принадлежать отрезку [1, mc]
. Значениями типа массива dt ARRAY [mc]
являются все массивы, состоящие из элементов типа dt
, максимальное значение индекса которых cs
не превосходит значения mc
. При сохранении в базе данных значения типа массива занимает столько памяти, сколько требуется для сохранения cs
элементов. Обеспечивается доступ к элементам массива по их индексам. В частности, можно объявить столбец типа INTEGER ARRAY [10]
и при вставке строки в соответствующую таблицу задать значение только пятого элемента массива. Тогда в строку будет занесен массив из пяти элементов, причем первые четыре элемента будут содержать неопределенное значение (NULL
).
Основными операциями над массивами являются выборка значения элемента массива по его индексу, изменение некоторого элемента массива или массива целиком и конкатенация (сцепление) двух массивов. Кроме того, для любого значения типа массива можно узнать значение его cs
.
Типы мультимножеств
При определении столбца таблицы типа мультимножеств используется конструкция dt MULTISET
, где dt
задает тип данных элементов конструируемого типа мультимножеств. Значениями типа мультимножеств являются мультимножества, т. е. неупорядоченные коллекции элементов одного и того же типа, среди которых допускаются дубликаты. Например, значениями типа INTEGER MULTISET
являются мультимножества, элементами которых — целые числа. Примером такого значения может быть мультимножество {12, 34, 12, 45, -64}
.
В отличие от массива, мультимножество является неограниченной коллекцией; при конструировании типа мультимножеств не указывается предельная кардинальность значений этого типа. Однако это не означает, что возможность вставки элементов в мультимножество действительно не ограничена; стандарт всего лишь не требует явного объявления границы. Ситуация аналогична той, которая возникает при работе с таблицами, для которых в SQL не объявляется максимально допустимое число строк.84)
Для типов мультимножеств поддерживаются операции преобразования типа значения-мультимножества к типу массивов или другому типу мультимножеств с совместимым типом элементов (операция CAST
), для удаления дубликатов из мультимножества (функция SET
), для определения числа элементов в заданном мультимножестве (функция CARDINALITY
), для выборки элемента мультимножества, содержащего в точности один элемент (функция ELEMENT
). Кроме того, для мультимножеств обеспечиваются операции объединения (MULTISET UNION
), пересечения (MULTISET INTERSECT
) и определения разности (MULTISET EXCEPT
). Каждая из операций может выполняться в режиме с сохранением дубликатов (режим ALL
) или с устранением дубликатов (режим DISTINCT
).
Расширенные в SQL:2003 возможности работы с типами коллекций являются принципиально важными. Даже при наличии определяемых пользователями типов данных (см. ниже) и типов массивов SQL:1999 не предоставлял полных возможностей для преодоления исторически присущего реляционной модели данных вообще и SQL в частности ограничения «плоских таблиц». После появления конструктора типов мультимножеств и устранения ограничений на тип данных элементов коллекции это историческое ограничение полностью ликвидировано. Мультимножество, типом элементов которого является анонимный строчный тип (см. ниже), представляет собой полный аналог таблицы. Тем самым, в базе данных допускается произвольная вложенность таблиц. Возможности выбора структуры базы данных безгранично расширяются.
15.2.8. Анонимные строчные типы
Анонимный строчный тип85) – это конструктор типов ROW
, позволяющий производить безымянные типы строк (кортежей). Любой возможный строчный тип получается путем использования конструктора ROW
. При определении столбца, значения которого должны принадлежать некоторому строчному типу, используется конструкция ROW (fld1, fld2, ѕ, fldn )
, где каждый элемент fldi
, определяющий поле строчного типа, задается в виде тройки fldname
, fldtype
, fldoptions
. Подэлемент fldname
задает имя соответствующего поля строчного типа. Подэлемент fldtype
специфицирует тип данных этого поля. В качестве типа данных поля строчного типа можно использовать любой допустимый в SQL тип данных, включая типы коллекций, определяемые пользователями типы и другие строчные типы. Необязательный подэлемент fldoptions
может задаваться для указания применяемого по умолчанию порядка сортировки, если соответствующий подэлемент fldtype
указывает на тип символьных строк, а также должен задаваться, если fldtype
указывает на ссылочный тип (см. ниже). Степенью строчного типа называется число его полей.
15.2.9. Типы, определяемые пользователем
Эта категория типов данных связана с объектными расширениями языка SQL. Более подробно мы обсудим эту тему в лекции 23, а здесь для полноты картины приведем беглый набросок.
- Структурные типы (Structured Types). Соответствующие возможности SQL:1999 позволяют определять долговременно хранимые, именованные типы данных86), включающие один или более атрибутов любого из допустимых в SQL типа данных87), в том числе другие структурные типы, типы коллекций, строчные типы и т. д. Стандарт SQL не накладывает ограничений на сложность получаемой в результате структуры данных, однако не запрещает устанавливать такие ограничения в реализации. Дополнительные механизмы определяемых пользователями методов, функций и процедур позволяют определить поведенческие аспекты структурного типа.
- Индивидуальные типы (Distinct Types). Можно определить долговременно хранимый, именованный тип данных, опираясь на единственный предопределенный тип. Например, можно определить индивидуальный тип данных
PRICE
, опираясь на тип DECIMAL (5, 2)
. Тогда значения типа PRICE
представляются точно так же, как значения типа DECIMAL (5, 2)
. Однако в SQL:1999 индивидуальный тип не наследует от своего опорного типа набор операций над значениями. Например, чтобы сложить два значения типа PRICE
требуется явно сообщить системе, что с этими значениями нужно обращаться как со значениями типа DECIMAL (5, 2)
. Другая возможность состоит в явном определении методов, функций и процедур, связанных с данным индивидуальным типом. Похоже, что в будущих версиях стандарта появятся и другие, более удобные возможности.
15.2.10. Ссылочные типы
Эта категория типов данных связана с объектными расширениями языка SQL, и мы снова отложим подробное обсуждение этого механизма до лекции 23 и рассмотрим его здесь очень коротко. Обеспечивается механизм конструирования типов (ссылочных типов), которые могут использоваться в качестве типов столбцов некоторого вида таблиц (типизированных таблиц). Фактически значениями ссылочного типа являются строки соответствующей типизированной таблицы. Более точно, каждой строке типизированной таблицы приписывается уникальное значение (нечто вроде первичного ключа, назначаемого системой или приложением), которое может использоваться в методах, определенных для табличного типа, для уникальной идентификации строк соответствующей таблицы. Эти уникальные значения называются ссылочными значениями, а их тип – ссылочным типом. Ссылочный тип может содержать только те значения, которые действительно ссылаются на экземпляры указанного типа (т. е. на строки соответствующей типизированной таблицы).
83 В стандарте SQL:2003 имеется следующее уточнение: «В этой спецификации не проводится различие между NULL-значением булевского типа данных и истинностным значением UKNOWN, являющимся результатом вычисления предиката, условия поиска или булевского выражения; они могут использоваться взаимозаменяемо и означают в точности одно и то же». С моей точки зрения такой подход во многом является некорректным, но я не буду здесь на этом останавливаться.
84 Конечно, на практике такие ограничения устанавливаются в документации конкретной используемой СУБД, либо даже администратором конкретной базы данных.
85 В тексте стандарта SQL:1999 используется термин anonymous row type. Следуя соглашениям предыдущего пункта, мы должны были бы использовать термин анонимные типы строк. Но тогда уж точно возникла бы путаница с типами символьных строк. Конечно, можно было бы радикально отказаться от использования термина строка таблицы и вернуться к кортежам отношений. Но, к сожалению, этого сделать нельзя, покольку в SQL таблицы – это не совсем (а иногда и совсем не) отношения, а строки таблиц – не совсем (совсем не) кортежи.
86 Соответствующие определения сохраняются как часть метаданных базы данных (другими словами, являются частью схемы базы данных).
87 Требуется, чтобы в определении структурного типа A
использовались только те типы, которые были определены ранее.
Назад Содержание Вперёд