Как создать альтернативный ключ из нескольких обнуляемых столбцов - PullRequest
0 голосов
/ 28 октября 2019

У меня есть база данных с тремя таблицами, назовите их Sale, Store и Hub. Каждый экземпляр Store ссылается на экземпляр Hub, хотя могут быть экземпляры Hub, на которые нет ссылок в таблице Store. В большинстве случаев экземпляр Sale будет ссылаться на экземпляр Store (и, следовательно, может отображаться на экземпляр Hub.) Однако в некоторых случаях Sale будет напрямую ссылаться на таблицу Hub.

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

В упрощенной версии, где отношения Sale - Hub не существуют, я легко могу сделать StoreID частью первичного ключа для таблицы Sale, что я и сделаюкак здесь, за исключением того, что StoreID иногда будет нулевым (когда продажа происходит в хабе, а не в магазине).

Поэтому пример из таблицы Sale может выглядеть следующим образом:

SaleID    SaleDate    StoreID    HubID    Quantity
     1  2012-05-16          1     NULL         100
     2  2014-09-27          2     NULL          99
     3  2018-02-01       NULL        9          30
     4  2019-11-12         17     NULL         207

Таблицы Store и Hub будут содержать информацию о местонахождении вместе с некоторыми полями, относящимися к магазину и концентратору.

Проблема заключается в том, как справиться с созданием хорошего альтернативного ключа для Sale таблица (SaleID - мой суррогатный первичный ключ.) Теоретически продажа должна определяться датой и местоположением. Однако у меня есть два поля местоположения, и они оба обнуляются. Мне интересно, могу ли я справиться с этим, используя уникальные индексы? Или я могу как-то использовать контрольные ограничения? Или промежуточная таблица местоположений?

Кроме того, предположим, что у меня также есть таблица SuperHub (представьте, Hub означает SuperHub, что Store означает Hub.) Если я хочу добавить SuperHubID поле к моей Sale таблице, как это повлияет на вещи? С 3+ пустыми полями не проверять ограничения / уникальные индексы начинают выходить из-под контроля?

Здесь потенциально может выглядеть ERD для этого:

Possible ERD

Редактировать: Чтобы уточнить, я пытаюсь понятьлучший способ включить информацию о местоположении как часть альтернативного ключа для таблицы Sale, учитывая, что «информация о местоположении» разделена между несколькими различными таблицами (первичный ключ для таблицы Sale - это просто суррогатный ключ SaleID.) Попытка включить все таблицы расположений в альтернативном ключе приводит к появлению пустых значений в ключе (см. Пример из таблицы Sale выше.) Как лучше всего решить эту проблему?

Редактировать 2: Хорошо, вот еще несколько уточнений. Я включаю определения таблиц и т. Д.

--Table Defs
CREATE TABLE Sale (
SaleID int NOT NULL IDENTITY(1, 1),
SaleDate date NOT NULL,
StoreID int NULL,
HubID int NULL,
Quantity int NOT NULL);
-- StoreID and HubID are nullable since a sale can occur at one or the other
-- Is there a better way to organize this?
-- @PeterHe mentioned Category/Subcategory model

CREATE TABLE Store (
StoreID int NOT NULL IDENTITY(1, 1),
StoreNumber int NOT NULL,
Customer nvarchar(20) NOT NULL,
Address nvarchar(50) NOT NULL,
HubID int NOT NULL);

CREATE TABLE Hub (
HubID int NOT NULL IDENTITY(1, 1),
HubNumber int NOT NULL,
Customer nvarchar(20) NOT NULL,
Address nvarchar(50) NOT NULL);

--PKs
ALTER TABLE Sale 
    ADD CONSTRAINT PK_Sale PRIMARY KEY CLUSTERED (SaleID);

ALTER TABLE Store 
    ADD CONSTRAINT PK_Store PRIMARY KEY CLUSTERED (StoreID);

ALTER TABLE Hub  
    ADD CONSTRAINT PK_Hub PRIMARY KEY CLUSTERED (HubID);

--FKs
ALTER TABLE Sale 
    ADD CONSTRAINT FK_Sale_Store 
        FOREIGN KEY (StoreID) REFERENCES Store (StoreID)
            ON UPDATE NO ACTION
            ON DELETE NO ACTION;

ALTER TABLE Sale 
    ADD CONSTRAINT FK_Sale_Hub 
        FOREIGN KEY (HubID) REFERENCES Hub (HubID)
            ON UPDATE NO ACTION
            ON DELETE NO ACTION;

ALTER TABLE Store 
    ADD CONSTRAINT FK_Store_Hub 
        FOREIGN KEY (HubID) REFERENCES Hub (HubID)
            ON UPDATE NO ACTION
            ON DELETE NO ACTION;

--AKs
ALTER TABLE Store
    ADD CONSTRAINT AK_Store UNIQUE (StoreNumber, Customer);

ALTER TABLE Hub
    ADD CONSTRAINT AK_Hub UNIQUE (HubNumber, Customer);

ALTER TABLE Sale
    ADD CONSTRAINT AK_Sale UNIQUE (SaleDate, StoreID, HubID); 
    --issue here is StoreID and HubID are nullable since sale could occur at either

1 Ответ

1 голос
/ 28 октября 2019

Лучше определить сущность, включающую в себя все организации, которые могут совершить продажу, например, sale_org (sale_org_id int, не null, sale_org_type tinyint, ни null, - 1, store; 2, hub, 3, super super hub address). .) Вы можете иметь таблицы Store, Hub и т. Д. (Без адреса) для определения отношений. Или только одна таблица для иерархии sale_org_hierarchy, чтобы определить отношение: sale_org_id и parent_sale_org_id

Только для таблицы продажи ссылка на таблицу store_hierarchy.

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