[英]SQL - One very long table with several foreign keys VS several short tables
[英]Designing foreign keys to one of several tables
我有三个表: Customers
、 Providers
和Locations
。 我需要创建第四个名为Contacts
的表。
我希望在Customers
、 Providers
和Locations
表中与任意行关联任意数量的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,
);
我不觉得这很优雅。 除了有未使用的列之外,我可能应该添加一个约束以确保CustomerId
、 ProviderId
和LocationId
中的一个不是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)
);
联系人是客户、提供商和位置的概括。 您可能会在这里发现一些有用的技术。 shared-primary-key和class-table-inheritance 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.