繁体   English   中英

为几个表之一设计外键

[英]Designing foreign keys to one of several tables

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

我希望在CustomersProvidersLocations表中与任意行关联任意数量的Contacts ,所以我最终得到了这样的结果。

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

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

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

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

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

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

如果您不打算查询所有联系人,那么像这样单独存储它们会更有效。 而这三者的架构可能会随着时间的推移而出现分歧。

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

例如

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM