Разработка внешних ключей для одной из нескольких таблиц - PullRequest
1 голос
/ 26 мая 2020

У меня есть три таблицы: Customers, Providers и Locations. Мне нужно создать четвертую таблицу под названием Contacts.

Я хотел бы, чтобы любое количество Contacts было связано с любой строкой в ​​таблице Customers, Providers и Locations, поэтому я в итоге получилось что-то вроде этого.

CREATE TABLE [dbo].[Contacts] (
    [Id]         INT            IDENTITY (1, 1) NOT NULL,
    [CustomerId] INT            NULL,
    [ProviderId] INT            NULL,
    [LocationId] INT            NULL,
    [Name]       NVARCHAR (80)  NULL,
    [Email]      NVARCHAR (80)  NULL,
    [Phone]      NVARCHAR (80)  NULL,
    [Title]      NVARCHAR (80)  NULL,
    [Address]    NVARCHAR (120) NULL,
);

Я не считаю это очень элегантным. В дополнение к наличию неиспользуемых столбцов мне, вероятно, следует добавить ограничение, чтобы точно одно из CustomerId, ProviderId и LocationId не было NULL.

Другой альтернативой является создание многопользовательского -многие стыковочные столы. Для этого не понадобятся неиспользуемые столбцы. Но это все равно кажется пустой тратой, поскольку ни один контакт никогда не будет связан с более чем одной компанией.

Кто-нибудь знает о каких-либо хитрых решениях?

Ответы [ 3 ]

1 голос
/ 26 мая 2020

В дополнение к предложению @ GMB другой альтернативой является просто наличие других таблиц контактов. То, что у Locations и Customers есть контакты, и только потому, что они изначально имеют одинаковые атрибуты, не означает, что они должны храниться в одной таблице.

Более эффективно хранить их отдельно вот так, если вы не собираетесь запрашивать все контакты. И схема для трех со временем может расходиться.

Они могут даже использовать суперкласс NotMapped для Contact в приложении, если вы хотите писать общие c логики для типов контактов.

EG

CREATE TABLE [dbo].[CustomerContacts] (
    [CustomerId] INT            not null references Customer on delete cascade,
    [Id]         INT            IDENTITY (1, 1) NOT NULL,
    [Name]       NVARCHAR (80)  NULL,
    [Email]      NVARCHAR (80)  NULL,
    [Phone]      NVARCHAR (80)  NULL,
    [Title]      NVARCHAR (80)  NULL,
    [Address]    NVARCHAR (120) NULL,
    constraint pk_CustomerContacts primary key (CustomerId,Id)
);
CREATE TABLE [dbo].[ProviderContacts] (
    [ProviderId] INT            not null references Provider on delete cascade,
    [Id]         INT            IDENTITY (1, 1) NOT NULL,
    [Name]       NVARCHAR (80)  NULL,
    [Email]      NVARCHAR (80)  NULL,
    [Phone]      NVARCHAR (80)  NULL,
    [Title]      NVARCHAR (80)  NULL,
    [Address]    NVARCHAR (120) NULL,
    constraint pk_ProviderContacts primary key (ProviderId,Id)
);
CREATE TABLE [dbo].[LocationContacts] (
    [LocationId] INT            not null references Location on delete cascade,
    [Id]         INT            IDENTITY (1, 1) NOT NULL,
    [Name]       NVARCHAR (80)  NULL,
    [Email]      NVARCHAR (80)  NULL,
    [Phone]      NVARCHAR (80)  NULL,
    [Title]      NVARCHAR (80)  NULL,
    [Address]    NVARCHAR (120) NULL,
    constraint pk_LocationContacts primary key (LocationId,Id)
);
1 голос
/ 26 мая 2020

Альтернативой может быть изменение отношения и создание одной таблицы сопоставления для каждой сущности, к которой может относиться контакт, например:

CREATE TABLE [dbo].[Contacts] (
    [Id]         INT            IDENTITY (1, 1) NOT NULL,
    [Name]       NVARCHAR (80)  NULL,
    [Email]      NVARCHAR (80)  NULL,
    [Phone]      NVARCHAR (80)  NULL,
    [Title]      NVARCHAR (80)  NULL,
    [Address]    NVARCHAR (120) NULL
);

CREATE TABLE [dbo].[ContactCustomers] ( 
    [ContactId]  INT NOT NULL REFERENCES Contacts([ContactId]),
    [CustomerId] INT NOT NULL REFERENCES Customers([CustomerId]),
    PRIMARY KEY([ContactId], [CustomerId])
);

CREATE TABLE [dbo].[ContactProviders] ( 
    [ContactId]  INT NOT NULL REFERENCES Contacts([ContactId]),
    [ProviderId] INT NOT NULL REFERENCES Providers([ProviderId]),
    PRIMARY KEY([ContactId], [ProviderId])      
);

CREATE TABLE [dbo].[ContactLocations] ( 
    [ContactId]  INT NOT NULL REFERENCES Contacts([ContactId]),
    [LocationId] INT NOT NULL REFERENCES Locations([LocationId]),
    PRIMARY KEY([ContactId], [LocationId])      
);

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

0 голосов
/ 27 мая 2020

Контакты - это обобщение клиентов, поставщиков и местоположений. Есть несколько приемов, которые могут вам пригодиться. и .

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