Мне интересно узнать, как NULL хранятся в базе данных?
Это, безусловно, зависит от сервера базы данных, но я хотел бы иметь общее представление об этом.
Первая попытка:
Предположим, что сервер поместил неопределенное значение (может быть что угодно) в поле для значения NULL.
Может быть, вам очень повезет, и вы получите значение NULL с помощью
...WHERE field = 'the undefined value (remember, could be anything...)'
Вторая попытка:
Есть ли на сервере флаг или какие-либо метаданные, указывающие, что это поле равно NULL?
Затем сервер должен прочитать эти метаданные, чтобы проверить поле.
Если в метаданных указано значение NULL и если в запросе нет "поле IS NULL", запись игнорируется.
Это кажется слишком легким...
Ответ 1 · рейтинг 5 · CesarB
В PostgreSQL используется необязательное растровое изображение с одним битом на столбец (0 - нуль, 1 - не нуль). Если растровое изображение отсутствует, все столбцы не равны нулю.
Это полностью отделено от хранилища самих данных, но находится на той же странице, что и строка (поэтому и строка, и растровое изображение считываются вместе).
Рекомендации:
Ответ 2 · рейтинг 10 · Thomas Jones-Low
MySql использует второй метод. Он хранит массив битов (по одному на столбец) с данными для каждой строки, чтобы указать, какие столбцы пусты, а затем оставляет данные для этого поля пустыми. Я почти уверен, что это верно и для всех других баз данных.
Проблема с первым методом заключается в том, уверены ли вы, что любое значение, которое вы выберете для своих данных, не будет отображаться как действительные данные? Для некоторых значений (таких как даты или числа с плавающей запятой) это верно. Для других (например, целых чисел) это неверно.
Ответ 4 · рейтинг 1 · Jonathan Leffler
IBM Informix Dynamic Server использует специальные значения для обозначения пустых значений. Например, допустимый диапазон значений для SMALLINT (16-разрядный, со знаком) - от -32767 до +32767. Другое значение, -32768, зарезервировано для обозначения NULL. Аналогично для INTEGER (4 байта, со знаком) и BIGINT (8 байт, со знаком). Для других типов используются другие специальные представления (например, все биты 1 для SQL FLOAT и SMALLFLOAT - также известные как C double и float соответственно). Это означает, что ему не нужно использовать дополнительное пространство.
IBM DB2 для Linux, Unix, Windows использует дополнительные байты для хранения нулевых индикаторов; Насколько я знаю, он использует отдельный байт для каждого поля, допускающего значение NULL, но я могу ошибаться в этой детали.
Итак, как было указано, механизмы различаются в зависимости от СУБД.
Ответ 5 · рейтинг 1 · Bjarke Ebert
Проблема со специальными значениями для обозначения NULL заключается в том, что рано или поздно это специальное значение будет вставлено. Например, он будет вставлен в таблицу с указанием специальных индикаторов NULL для разных серверов баз данных.
| DBServer | SpecialValue |
+--------------+--------------+
| 'Oracle' | 'Glyph' |
| 'SQL Server' | 'Redmond' |
;-)