【问题标题】:Composite foreign key in SQL ServerSQL Server 中的复合外键
【发布时间】:2012-03-07 02:37:45
【问题描述】:

我有一个名为 Books 的表,其中包含 3 列。

TableName: Books
Columns: BookId (PK), BookName, Book_Publisher_XRef_Id (FK), IsInternal

我有两个包含发布者信息的表。这两个表都有不同的列集。

TableName: InternalPublishers
Columns: PublisherId (PK), PublisherName, ....

TableName: ExternalPublishers
Columns: PublisherId (PK), PublisherName, ....

我有一个链接表,其中包含有关哪本书属于哪个出版商的信息。一本书可以有多个出版商。

TableName: Books_Publishers_XRef
Columns: Book_Publisher_XRef_Id (PK), PublisherId

如果我想在 PublisherId 上创建外键约束,我需要创建一种我不确定是否可以创建的复合外键约束。

那么在这种情况下,对 Books_Publishers_XRef 表中的 PublisherId 实现 FK 的最佳方法是什么?

  1. 将 Books_Publishers_XRef 表分成 2 个表,即一个用于内部出版商,另一个用于外部出版商,并且在 Books_Internal_Publishers_XRef 和 Books_External_Publishesr_XRef 表的 Books 表中有 2 列?

  2. 不要在 Publisher_Id 列上创建 FK 并保持设计不变?

  3. 通过在 Books 表和 Books_Publishers_XRef 表中添加 Publisher_Type_Id 列来创建复合外键,其中如果 Publisher_Type_Id = 1,它属于 Internal_Publishers 表,而 Publisher_Type_Id = 2,它属于 External_Publishers 表? (不确定这是否可能)

  4. 其他一些架构设计?

请指教。

【问题讨论】:

  • 您真的需要两张表供发布者使用吗?你可以有一个表和一个额外的列来指定它是内部的还是外部的。
  • 它们都有不同的字段,我不确定我是否应该根据 PublisherType 将某些字段中的值保留为 NULL
  • 您可以拥有一个 Publisher 表和另外两个与 Publisher 具有 1:1 关系的表,其中包含每种发布者类型的特定字段。
  • ...或者允许列可以为空 - NULL 不是魔鬼。您甚至可以根据发布者类型设置可空约束。

标签: sql-server database sql-server-2005 database-design


【解决方案1】:

不要将您的数据分成两个表:InternalPublishersExternalPublishers。创建一个表并有一个bit 字段来确定它们是内部的还是外部的。像这样的:

create table Publisher
(
    PublisherId int not null primary key clustered,
    PublisherName varchar(100) not null,
    IsInternal bit not null
)
go

这样您就可以轻松创建外键引用。毕竟,Books 似乎也有同样的设计,让出版商继续这样做。

【讨论】:

  • 两个表的发布者表中的字段不同。根据发布者类型,我将在该表中有很多 NULL 值
  • 如果您知道永远不会,永远有一天会出现其他类型的发布者,请仅将其设为位列。 (另外,您不能索引位列,这可能是个问题。)
  • 经典类型/子类型问题。一个表用于 Publisher,然后是内部和外部的子类型表(具有特定于主题的列)。其他任何事情似乎都是一种解决办法。
  • 我为什么不应该将外部参照表分成两个表,就像我在问题中提到的选项 1 一样?有什么缺点吗?
  • @Asdfg 如果您想运行忽略发布者类型的报告或搜索,那么查询真的很丑。
【解决方案2】:
  • 保留Publisher 表中的所有常用列。
  • 子类型表只有每个特定的列。

【讨论】:

  • 感谢您的意见。我以同样的方式创建了表格。
猜你喜欢
  • 1970-01-01
  • 2012-03-21
  • 1970-01-01
  • 2013-05-10
  • 1970-01-01
  • 1970-01-01
  • 2013-07-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多