首页 文章

复合主键与附加“ID”列?

提问于
浏览
37

如果我们有这样一个表:

书籍(假装“ISBN”不存在)

  • 作者

  • Headers

  • 出版年份

  • 价格

有人可能会说{Author,Title,Edition}可能是候选/主键 .

是什么决定候选/主键应该是{Author,Title,Edition}还是应该使用ID列,{Author,Title,Edition}是唯一的索引/键约束?

也是

  • 作者(PK)

  • Headers (PK)

  • 版(PK)

  • 出版年份

  • 价格

更好,或:

  • ID(PK)

  • 作者

  • Headers

  • 出版年份

  • 价格

其中{Author,Title,Edition}是一个额外的唯一索引/约束?

4 回答

  • 35

    假设 {Author,Title,Edition} 唯一地标识一本书,则以下内容成立:

    • 它是一个(超级)键 - 唯一标识元组(行) .

    • 这是不可简化的 - 删除任何列都不会使它成为关键 .

    • 这是候选键 - 不可缩减的键是候选键 .

    现在让我们考虑ID(整数)

    我可以推断, Book 表键将在少数其他表中显示为外键,也可以在少数索引中显示 . 因此,它将占用相当多的空间 - 比如三列×40个字符(或者其他......) - 在每个表中加上匹配的索引 .

    为了使这些"other"表和索引更小,我可以在 Book 表中添加一个唯一整数列,以用作将作为外键引用的键 . 说出类似的话:

    alter table `Book` add `BookID` integer not null identity;
    

    由于 BookID (也必须)是唯一的, Book 表现在有两个候选键 .

    现在我可以选择 BookID 作为主键 .

    alter table Book add constraint pk_Book primary key (BookID);
    

    但是, {Author,Title,Edition} must 保持一个键(唯一),以便 prevent 这样的东西:

    BookID  Author      Title           Edition
    ----------------------------------------------- 
      1      C.J.Date  Database Design     1
      2      C.J.Date  Database Design     1
    

    总结一下,添加 BookID 并选择它作为主要 - 并没有阻止 {Author,Title,Edition} 成为(候选)键 . 它仍然必须有自己唯一的约束,通常是匹配的索引 .

    另请注意,从设计角度来看,此决定是在"physical level"上完成的 . 通常,在设计的逻辑层面上,这个 ID 不存在 - 它是在考虑列大小和索引时引入的 . 因此物理模式源于逻辑模式 . 根据数据库大小,RDBMS和使用的硬件,这些大小推理都不会产生可测量的影响 - 所以使用 {Author,Title,Edition} 作为PK可能是非常好的设计 - 直到证明不同 .

  • 6

    通常,您不希望主键更改值 . 这就是使用盲或替代主键的原因 .

    假设您使用Author作为主键的一部分创建了Book表 .

    假设你在大约一年后发现你拼错了“Ray Bradbury” . 或者更糟糕的是,你拼错了“Rachael Bloom” . 想象一下,您需要修改多少个数据库行来纠正拼写错误 . 想象一下,必须更改多少个索引引用 .

    但是,如果您有一个带有代理键的Author表,则只需更正一行 . 不需要更改索引 .

    最后,数据库表名通常是单数(Book),而不是复数(Books) .

  • 3

    使用代理主键方案的另一个好理由是,如果未来唯一性约束应该更改(例如,需要添加ISBN以使书籍唯一) . 重新输入数据会更容易 .

  • 14

    有很多与此相关的文章 . 您案例中复合键的问题:

    • 很难将书籍与其他实体联系起来

    • 很难在网格中编辑它们,因为大多数网格不支持复合键(例如kendo grid,jqgrid)

    • 你可能会拼错作者, Headers ,版本

    标准化您的数据并将一个ID存储到作者(如建议的dasblinkenlight)也是很好的 . 在最糟糕的情况下,他/她将改变他/她的名字(例如,她已经结婚,并且她喜欢她的新名字) .

相关问题