我正在从头开始为新应用程序构建数据库模式,我的两个目标是松散耦合(可伸缩性)和性能(但性能是最重要的)。我不确定在中心表中包含外键列是否是个好主意。用一个例子可能最好理解我的问题(请记住这个例子纯粹是假设的):
我们有一张桌子,我们称之为“动物”。在此表中,我们有几个条目,用于定义存储在数据库中的各种类型“Animal”的属性。 我们还有另一个名为“AnimalName”的表,其目的是将每个Animal的名称与“语言ID”一起存储在“Animal”表中(因此我们有一个表存储每个动物的名称在“动物“每种语言的表格。”
我有两种实现上表的方法:
动物表:AnimalID(PK)
AnimalName表:AnimalNameID(PK),AnimalID(FK),LanguageID(FK),名称
并且查询看起来像这样:
SELECT * FROM Animal a JOIN AnimalName an ON an.AnimalID = a.AnimalID and an.LanguageID = ? WHERE a.AnimalID = ?
动物表:AnimalID(PK),AnimalNameID(FK)
AnimalName表:AnimalNameID(PK),LanguageID(FK),名称
并且查询看起来像这样:
SELECT * FROM Animal a JOIN AnimalName an ON an.AnimalNameID = a.AnimalNameID and an.LanguageID = ? WHERE a.AnimalID = ?
对于第二种方式,如果我要在AnimalName表中添加“AnimalID”FK列,那么它也支持以第一种方式表达的查询。
上述哪种方法可以提供最快的性能(这是至关重要的!)? 根据您的经验,您通常会推荐上述哪种方法?
非常感谢所有回答的人!
答案 0 :(得分:4)
只有第一种方式才能正确模拟您描述的问题:动物有很多名字,每种语言都有一个。第二种方式根据动物的某些方式建模,其中一个名称恰好位于语言foo 中,与您的问题描述完全不同。
对于你所描述的这种查询,AnimalNames表必须由(AnimalId, LanguageId)
唯一地聚类,并将主键作为非聚集约束,或者甚至更好地处理AnimalLanguageID
PK和模型复合PK为(AnimalID, LanguageID)
。
此外,您必须阅读Designing Indexes
答案 1 :(得分:2)
第一种方式为您提供了动物和AnimalName之间的标准一对多关系,为每个动物提供了许多名称,这是有道理的。
使用第二种方式,每个动物只有一个名称,并且可以为许多动物分配一个名称,这是没有意义的。
答案 2 :(得分:1)
第二种方法更好。 AnimalName和Animal将具有1对多的关系,这在这里更有意义。