Работает ли обнуляемый внешний ключ? - PullRequest
0 голосов
/ 26 марта 2019

Рассмотрим следующие таблицы для создания простого заказа:

Customer(CustomerId, Name)
Order(OrderId, CustomerId)
OrderLine(OrderLineId, OrderId, CatalogItemId)

Приведенные выше таблицы являются типичными. Однако следующее не является типичным, поскольку включает в себя CustomerId:

CatalogItem(CatalogItemId, Description, CustomerId)

Другими словами, каждый элемент каталога предназначен только для одного клиента. Однако на самом деле необходимо, чтобы элемент каталога был назначен конкретному клиенту или ЛЮБОМУ клиенту.

Как лучше всего это смоделировать? (Это может быть так же просто, как позволить CustomerId быть нулевым, но я не уверен, и это не так, как это делается в настоящее время.)

Это будет затем использоваться при отображении списка CatalogItem доступных для клиента:

 select * from CatalogItems ci where (ci.customerId is null or ci.Customerid = @customerid);

Текущая система использует 0 для CustomerId, чтобы указать, что он доступен для всех клиентов, но это кажется мне нестандартным.

1 Ответ

1 голос
/ 26 марта 2019

Я считаю, что эти проекты в порядке. Важно то, что когда-то вы выбираете дизайн, чтобы придерживаться его. В базе данных, над которой я работаю ежедневно, используется много разных конструкций. Иногда существуют нули, нули или 1 или -1, которые представляют, что объект предназначен для ВСЕХ сущностей или для них нет. Возможно, имеется другое значение, которое выводится, что просто зависит от того, как таблица базы данных была первоначально реализована, и от того, соответствуют ли данные, помещаемые в эту таблицу, исходному дизайну.

Так что я говорю: «Да» - это, конечно, нормально.

Дизайн, который вы упомянули в своем вопросе, заключается в том, как мое приложение определяет клиентов по умолчанию. Это используется во многих различных разделах моего приложения.

Например - чтобы показать системные элементы каталога по умолчанию, доступные для всех клиентов:

SELECT * FROM CatalogItems ci WHERE ci.customerId is null;

Чтобы найти пользовательские «элементы каталога» для конкретного клиента:

SELECT * FROM CatalogItems ci WHERE ci.customerId = @customerid;

И, как вы указали, если вы хотите найти ВСЕ доступные «элементы каталога» для клиента:

SELECT * FROM CatalogItems ci WHERE ci.customerId is null or ci.Customerid = @customerid;
...