说我有一个对书籍进行分类的系统,我想将它们归类,并且有一个联合国基金会元组:
BookId (PK): number
BookTitle: string
Blurb: string
Genres: string[]
(... everything else)
[归一化后,必须将流派设为原子,也需要将其置于自己的关系中,以免引起重复。我的第一个直觉是执行以下操作:
BOOK
BookId (PK): number
BookTitle: string
Blurb: string
GENRE
GenreId (PK): number
GenreName: string
BOOKGENRE
BookId (CK): number
GenreId (CK): number
但是我想到了另一个主意,但是感觉有些不对劲。但是我的想法是通过仅使GenreName字段为主键并仅使用BOOKGENRE来摆脱GENRE表。由于GenreName作为复合键的一部分仍将被索引,因此仍将被索引并高效执行操作,例如使用Genre“ X”获取所有书籍。
BOOK
BookId (PK): number
BookTitle: string
Blurb: string
BOOKGENRE
BookId (CK): number
GenreName (CK): string
这是可接受的做法,还是要求我将流派作为带有键的单独表保留?
我建议坚持使用三个单独的表和一个整数主键的原始设计。原因之一是您想要无意义的键,即没有业务含义的键。
使用您正在考虑的替代设计,如果您想重命名类型,例如从科幻小说到科幻小说,该怎么办?您将需要更新bookgenre
表中的每一行,这不必要地复杂。
主键永远不应该更新,因此,如果存在可能需要更改类型值的风险,则应该使用代理键:从长远来看,这将使您的生活更轻松。