Выделение нулей в стилевых отношениях - PullRequest
1 голос
/ 15 декабря 2008

С учетом схемы

PERSON { name, spouse }

где PERSON.spouse является внешним ключом для PERSON.name, значения NULL будут необходимы, когда человек не женат или у нас нет никакой информации.

Если исходить из аргументов против нулей, как их избежать в этом случае?

У меня есть альтернативная схема

PERSON { name }
SPOUSE { name1, name2 }

, где SPOUSE.name * - FK для ЧЕЛОВЕКА. Проблема, которую я вижу здесь, состоит в том, что нет способа гарантировать, что у кого-то есть только один супруг (даже при всех возможных УНИКАЛЬНЫХ ограничениях, возможно будет иметь двух супругов).

Каков наилучший способ выделить нули в отношениях в стиле ведомостей материалов?

Ответы [ 7 ]

2 голосов
/ 15 декабря 2008

Я думаю, что принудительное отсутствие NULL и дубликатов для этого типа отношений делает определение схемы более сложным, чем на самом деле. Даже если вы разрешите пустые значения, для человека все равно будет возможно иметь более одного супруга или иметь конфликтующие записи, например:

PERSON { A, B }
PERSON { B, C }
PERSON { C, NULL }

Вам нужно будет ввести больше данных, таких как пол (или «номера супругов» для однополых браков?), Чтобы гарантировать, что, например, только лица одного типа могут иметь супруга. Супруга другого лица будет определяться по записи первого лица. E.g.:

PERSON { A, FEMALE, B }
PERSON { B, MALE, NULL }
PERSON { C, FEMALE, NULL }

... Так что только ЖЕНЩИНЫ, являющиеся ЖЕНЩИНАМИ, могут иметь ненулевой SPOUSE.

Но ИМХО, это слишком сложно и не интуитивно понятно даже с NULL. Без NULL это еще хуже. Я бы избегал таких ограничений схемы, если бы у вас буквально не было выбора.

1 голос
/ 15 декабря 2008

Я не уверен, почему никто еще не указал на это, но на самом деле довольно легко убедиться, что у человека есть только один супруг, используя почти ту же модель, что и у вас в вашем вопросе.

На данный момент я собираюсь игнорировать использование имени в качестве первичного ключа (оно может меняться, и дубликаты встречаются довольно часто, так что это плохой выбор), и я также собираюсь исключить возможную необходимость историческое отслеживание (вы можете добавить какую-нибудь эффективную дату, чтобы вы знали, КОГДА они были супругами - Джо Селко написал несколько хороших статей о временном моделировании, но я не помню, в какой книге это было в данный момент) , В противном случае, если я разведусь и снова выйду замуж, вы потеряете, что у меня был другой супруг в другое время - возможно, это не важно для вас.

Кроме того, вы можете разбить имя на имя, отчество, фамилию, префикс, суффикс и т. Д.

Учитывая эти предостережения ...

CREATE TABLE People
(
     person_name     VARCHAR(100),
     CONSTRAINT PK_People PRIMARY KEY (person_name)
)
GO
CREATE TABLE Spouses
(
     person_name     VARCHAR(100),
     spouse_name     VARCHAR(100),
     CONSTRAINT PK_Spouses PRIMARY KEY (person_name),
     CONSTRAINT FK_Spouses_People FOREIGN KEY (person_name) REFERENCES People (person_name)
)
GO

Если вы хотите, чтобы супруги также появлялись в таблице «Люди», вы можете добавить для этого также FK. Однако в этот момент вы имеете дело с двунаправленной ссылкой, которая становится немного более сложной.

1 голос
/ 15 декабря 2008

Ну, во-первых, я бы использовал идентификаторы с автоинкрементным увеличением, поскольку, конечно, кто-то может иметь такое же имя. Но, я полагаю, вы намерены это сделать и не будете об этом говорить. Однако, как именно идет аргумент против NULL? У меня нет проблем с NULL, и я думаю, что это подходящее решение этой проблемы.

0 голосов
/ 15 декабря 2008

Для определения взаимосвязи необходим личный стол TABLE и отдельная таблица Partner_Off.

Персона (имя, фамилия и т. Д.);

Partner_Off (id, partner_id, отношения);

Чтобы справиться с более сложной социальной ситуацией, вам, вероятно, понадобятся некоторые даты там, плюс, чтобы упростить sqls, вам нужна одна запись для (Фред, Вильма, муж) и соответствующая запись для (Вильма, Фред, жена) ).

0 голосов
/ 15 декабря 2008

Хорошо, используйте авто-идентификаторы, а затем используйте проверку ограничений. Столбец «Имя1» (который будет только int ID) будет принудительно иметь только пронумерованные идентификаторы ODD, а Name2 будет иметь только ДАЖЕ.

Затем создайте уникальное ограничение для столбца 1 и столбца 2.

0 голосов
/ 15 декабря 2008

Вы можете использовать триггер, чтобы применить ограничение. В PostgreSQL есть триггеры ограничений , что особенно удобно для того, чтобы отложить оценку ограничений до подходящего времени в транзакции.

Из практических вопросов Фабиана Паскаля по управлению базами данных , с. 66-67:

Хранимые процедуры - запущенные или нет - предпочтительнее применения код целостности уровня, но они практически уступает и более рискованный чем декларативная поддержка, потому что они более обременительно писать, ошибка склонны и не могут извлечь выгоду из полного Оптимизация СУБД.

...

Выбирайте СУБД с лучшей декларативной поддержка целостности. Учитывая значительные пробелы в такой поддержке со стороны продукты, знающие пользователи будут по крайней мере, в состоянии подражать правильно - хотя и с процедурным и / или прикладным кодом - ограничения не поддерживается СУБД.

0 голосов
/ 15 декабря 2008

Ну, начните с использования ключа, отличного от name, возможно, int seed. Но чтобы кто-то не мог иметь более одного супруга, просто добавьте уникальный индекс к родителю (name1) в таблице супругов. это не позволит вам когда-либо вставить одно и то же имя1 дважды.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...