为几个表之一设计外键

Designing foreign keys to one of several tables

我有三个 table:CustomersProvidersLocations。我需要创建第四个 table,名为 Contacts

我希望有任意数量的 ContactsCustomersProvidersLocations table 中的任何行相关联,所以我结束了想出这样的东西。

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,
);

我觉得这不是很优雅。除了有未使用的列外,我可能应该添加一个约束以确保 CustomerIdProviderIdLocationId 中的一个恰好不是 NULL.

另一种方法是创建多对多连接 table。这不需要任何未使用的列。但这似乎仍然是一种浪费,因为任何联系人都不会与不止一家公司相关。

有人知道任何更巧妙的解决方案吗?

另一种方法是恢复关系,并为联系人可能涉及的每个实体创建一个映射 table,例如:

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 table 专注于其主要目的:存储与此实体相关的数据。

除了@GMB 的建议外,另一种选择是简单地使用不同的联系人 table。仅仅因为 Locations 和 Customers 都有联系人,并且仅仅因为它们最初具有相同的属性,并不意味着它们必须存储在相同的 table 中。

如果您不打算查询所有联系人,像这样单独存储它们会更有效。随着时间的推移,这三者的模式可能会有所不同。

如果您想在联系人类型上编写通用逻辑,他们甚至可以在应用程序中共享联系人的 NotMapped 超类。

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)
);

联系人是客户、提供商和位置的概括。您可能会发现这里有一些有用的技巧。 and .