Доброго времени суток, читатели, зрители моего канала programmer's notes. Не забывайте подписываться и писать свои комментарии к моим статьям и видео.
Статья является приложением к видео
PostgreSQL, NULL и типы данных
В видеоуроке я рассмотрел достаточно простые вопросы, связанные с некоторыми типами данных в СУБД PostgreSQL. Несколько более сложный вопрос связан с понятие NULL. В данной статье я постараюсь немного систематизировать представленную в видео информацию.
Следует иметь в виду, что в стандартах языка SQL, а их было несколько, указываются и команды (языка SQL) и типы данных, которые должны поддерживаться СУБД. Однако ситуация такова, что разработчики СУБД не всегда следуют требованиям стандартов. Во-первых, добавляют своё. Во-вторых, далеко не всегда выполняют требования стандарта. И это нормальное явление. Как я уже сказал в начале курса по базам данных, всё будет касаться конкретных реализаций, я буду излагать на основе СУБД PostgreSQL.
Типы данных, о которых я здесь пишу, далеко не все, которые есть в Postgres. Но довольно часто этого вполне достаточно для типовых задач.
Замечание
Я не пытаюсь изложить документацию по PostgreSQL, какие то детали буду добавлять в последующих статьях.
Целые типы
К целым типам, которые стоит сейчас упомянуть, следует отнести тип integer и тип bigint. integer 4-байтовыё целый тип, bigint - 8-байтовый целый. Конечно, существует ещё smallint, который занимает 2 байта, но его употребление довольно ограничено.
Замечание
Типы serial и bigserial в действительности отдельными типами не являются. На самом деле это integer и bigint. Это макроопределения для столбца с автоинкрементированием.
Вещественные типы
Это тип real, который хранится в четырёх байтах и соответствует типу, поддерживаемому на аппаратном (процессорном) уровне. Поскольку внутри процессора эти числа представляются в двоичном виде, то изначально такое представление предполагает приближенность таких чисел.
Тип decimal (или numeric) называется типом с произвольной точностью. Число 100.11 можно рассматривать как число с точностью 5 и с масштабом 2. Когда мы указываем тип столбца таблицы, то можем указать сразу максимальную точность и масштаб: decimal(5, 2). При этом масштаб может и отрицательным и положительным, тогда как точность всегда положительна.
Точность определяет количество цифр в числе, а масштаб то, как нужно округлять. Примеры
decimal (3, 4) задаёт числа от 999.9999 до -999.9999
decimal (3, -1) задаёт числа от 9990 до -9990
decimal (3, 4) задаёт числа от 0.0999 до -0.0999
Строковые типы
PostgreSQL поддерживает три типа строковых данных.
- character(n) - строка фиксированной длины. Недостающие символы справа заполняются пробелами.
- varchar(n) - строка переменной длины. У такого типа пробелы справа отбрасываются.
- text - строка произвольной длины.
Замечание
Есть разные рассуждения по поводу того, какой из типов даёт большую производительность. В некоторых СУБД утверждается что character(n) дают большую производительность, чем varchar(n). Думаю, что для начала это не принципиально.
Типы по дате и времени
Четыре типа по заданию даты и времени.
- date - дата без указании времени суток. Занимает 4 бата.
- time - время суток, 8 байтов без часового пояса, 12 с часовым поясом. Точность до микросекунд.
- interval - интервал времени с точностью до микросекунд. Занимает 16 байтов.
- timestamp - дата и время в одном данном. 8 байтов.
Значение даты и времени принимается в самых разных форматах. Я не буду пока на этом останавливаться.
Понятие NULL
В принципе в любом языке программирования возникает необходимость обозначать отсутствие чего-то. На самом деле всё не так просто. Надо различать ситуации
- когда переменная есть, а её значение не определено;
- когда функция ничего не возвращает;
- когда одна переменная должна указывать на другую переменную, но она никуда не указывает;
- когда переменная указывает на не существующую переменную (т.е. переменная была, но её удалили);
- когда результат операции не определён.
Обычно в языке есть одно обозначение, которое означает, что данных нет. Например, в Python есть обозначение None, в C есть null, но это уже нечто отличное от None в Python.
В базах данных также возникает проблема, что писать в поле строки, если значение неизвестно. Для это используется NULL.
Но получается, что NULL всё таки значение и нужно решить, что с ним делать в конкретных операциях. Если в бинарные операции одно из значений NULL, то результат всей операции равен NULL. С этим нужно быть очень осторожным, так как в результате можно вообще потерять значимое данное.
В случае операций сравнения, где есть значение NULL, результат также считается NULL. По сути мы получаем трех-значную логику и с ней нужно быть очень осторожным.
Самое главное, что мы должны запомнить.
- По возможности следует избегать значение NULL в таблице.
- Предусмотрены операторы IS NULL и IS NOT NULL для проверко того, что значение NULL.
- Нужно понимать, как работают различные операции над строками, где есть NULL. Например, как работают агрегирующие функции, как работает группировка и сортировка c NULL. Я буду оговаривать эти особенности в своё время.
Мы будем снова и снова возвращаться к NULL, когда будем рассматривать те или иные операции в реляционных базах данных.
Ну, пока всё!
Пишите свои предложения и замечания и занимайтесь программированием, а также проектированием баз данных, хотя бы для поддержания уровня интеллекта.