Опции для устранения столбцов NULLable из модели DB (для предотвращения трехзначной логики SQL)?

Некоторые, в то время как назад, я прочитывал книгу SQL и Реляционная Теория C. J. Дата. Автор известен за критику трехзначной логики SQL (3VL).1),

Автор делает некоторые сильные стороны того, почему 3VL должен избежаться в SQL, однако он не обрисовывает в общих чертах, как модель базы данных была бы похожа, если бы nullable столбцы не были позволены. Я думал на этом некоторое время и предложил следующие решения. Если бы я пропустил другие проектные решения, то я хотел бы услышать о них!

1) Критический анализ даты SQL 3VL был в свою очередь подвергнут критике также: посмотрите данная статья Claude Rubinson (включает исходный критический анализ C. J. Дата).


Таблица Example:

Как пример, возьмите следующую таблицу, где у нас есть один nullable столбец (DateOfBirth):

#  +-------------------------------------------+
#  |                   People                  |
#  +------------+--------------+---------------+
#  |  PersonID  |  Name        |  DateOfBirth  |
#  +============+--------------+---------------+
#  |  1         |  Banana Man  |  NULL         |
#  +------------+--------------+---------------+

Опция 1: эмуляция NULL через флаг и значение по умолчанию:

Вместо того, чтобы делать столбец nullable, указано любое значение по умолчанию (например. 1900-01-01). Дополнительное BOOLEAN столбец укажет ли значение в DateOfBirth должен просто быть проигнорирован или содержит ли это на самом деле данные.

#  +------------------------------------------------------------------+
#  |                              People'                             |
#  +------------+--------------+----------------------+---------------+
#  |  PersonID  |  Name        |  IsDateOfBirthKnown  |  DateOfBirth  |
#  +============+--------------+----------------------+---------------+
#  |  1         |  Banana Man  |  FALSE               |  1900-01-01   |
#  +------------+--------------+----------------------+---------------+

Опция 2: Превращение nullable столбца в отдельную таблицу:

nullable столбец заменяется новой таблицей (DatesOfBirth). Если запись не будет иметь данных для того столбца, то в новой таблице не будет записи:

#  +---------------------------+ 1    0..1 +----------------------------+
#  |         People'           | <-------> |         DatesOfBirth       |
#  +------------+--------------+           +------------+---------------+
#  |  PersonID  |  Name        |           |  PersonID  |  DateOfBirth  |
#  +============+--------------+           +============+---------------+
#  |  1         |  Banana Man  |
#  +------------+--------------+

В то время как это походит на лучшее решение, это возможно привело бы ко многим таблицам, к которым нужно присоединиться для единого запроса. С тех пор OUTER JOINs не будет позволен (потому что они представили бы NULL в набор результатов), все необходимые данные больше не могли возможно выбираться только с единым запросом как прежде.


Вопрос: Есть ли любые другие опции для устранения NULL (и если так, каковы они)?

8
задан stakx supports GoFundMonica 21 June 2010 в 20:23
поделиться

4 ответа

Я видел, как коллега Дейта Хью Дарвен обсуждал этот вопрос в отличной презентации «Как обрабатывать отсутствующую информацию без использования NULL», которая доступна на веб-сайте Третьего манифеста .

Его решение является вариантом вашего второго подхода. Это шестая нормальная форма с таблицами, содержащими как дату рождения, так и идентификаторы, где она неизвестна:

#  +-----------------------------+ 1    0..1 +----------------------------+
#  |         People'             | <-------> |         DatesOfBirth       |
#  +------------+----------------+           +------------+---------------+
#  |  PersonID  |  Name          |           |  PersonID  |  DateOfBirth  |
#  +============+----------------+           +============+---------------+
#  |  1         |  Banana Man    |           ! 2          | 20-MAY-1991   |
#  |  2         |  Satsuma Girl  |           +------------+---------------+
#  +------------+----------------+
#                                  1    0..1 +------------+
#                                  <-------> | DobUnknown |
#                                            +------------+
#                                            |  PersonID  |
#                                            +============+
#                                            | 1          |
#                                            +------------+

Выбор из людей требует объединения всех трех таблиц, включая шаблон для указания неизвестных дат рождения.

Конечно, это несколько теоретически. Состояние SQL в наши дни все еще недостаточно развито, чтобы справиться со всем этим. Презентация Хью покрывает эти недостатки. Одна вещь, которую он упоминает, не совсем верна: некоторые разновидности SQL действительно поддерживают множественное присваивание - например, синтаксис Oracle INSERT ALL .

4
ответ дан 5 December 2019 в 21:16
поделиться

Я не читал, но есть статья под названием Как обрабатывать недостающую информацию с помощью S-by-C в Третьем манифесте веб-сайт, которым руководят Хью Дарвен и Си Джей Дэйт. Это написано не Си Джей Дейтом, но я предполагаю, что, поскольку это одна из статей на этом веб-сайте, она, вероятно, похожа на его мнение.

1
ответ дан 5 December 2019 в 21:16
поделиться

Альтернативой может быть модель значение атрибута объекта :

 entity  attribute    value
 1       name         Banana Man
 1       birthdate    1968-06-20

Если дата рождения неизвестна, вы просто опустите ее строку.

0
ответ дан 5 December 2019 в 21:16
поделиться

Вариант 3: Обязанность автора записи:

CREATE TABLE Person
(
  PersonId int PRIMARY KEY IDENTITY(1,1),
  Name nvarchar(100) NOT NULL,
  DateOfBirth datetime NOT NULL
)

Зачем искажать модель, чтобы разрешить нулевое представление, если ваша цель - их устранить?

0
ответ дан 5 December 2019 в 21:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: