多对多关系设计 - 交叉表设计

Dan*_*ain 22 sql t-sql database-design

我想知道对于多对多关系的交叉表有什么更好的设计.

我正在考虑的两种方法是:

CREATE TABLE SomeIntersection 
(
     IntersectionId UNIQUEIDENTIFIER PRIMARY KEY,
     TableAId UNIQUEIDENTIFIER REFERENCES TableA NOT NULL,
     TableBId UNIQUEIDENTIFIER REFERENCES TableB NOT NULL,
     CONSTRAINT IX_Intersection UNIQUE(TableAId, TableBId )
) 
Run Code Online (Sandbox Code Playgroud)

要么

CREATE TABLE SomeIntersection 
(
     TableAId UNIQUEIDENTIFIER REFERENCES TableA NOT NULL,
     TableBId UNIQUEIDENTIFIER REFERENCES TableB NOT NULL,
     PRIMARY KEY(TableAId, TableBId )
) 
Run Code Online (Sandbox Code Playgroud)

一个人对另一个人有好处吗?
编辑2:****请注意:我计划使用Entity Framework为数据库提供API.考虑到这一点,一个解决方案在EF中的效果是否优于另一个?

编辑:在相关的说明中,对于两列引用同一个表的交集表(下面的示例),是否有办法使两个字段在记录上不同?

CREATE TABLE SomeIntersection 
(
     ParentRecord INT REFERENCES TableA NOT NULL,
     ChildRecord INT REFERENCES TableA NOT NULL,
     PRIMARY KEY(TableAId, TableBId )
)
Run Code Online (Sandbox Code Playgroud)

我想阻止以下情况

ParentRecord          ChildRecord
=================================
      1                    1         --Cyclical reference! 
Run Code Online (Sandbox Code Playgroud)

cha*_*aos 13

这是一个争论的话题.我更喜欢第一种形式,因为我认为能够通过单个值查找映射行更好,并且喜欢强制执行一个可能 - 愚蠢的一致性,即在每个表中都可以使用单列主键.其他人则认为拥有该专栏是对空间的愚蠢浪费.

我们每隔几个月在新泽西州的一家酒吧见面几轮裸肩拳击.

  • 我同意行标识可以派上用场,特别是如果有时候你需要直接参考相关性.赤裸裸的拳击+1,DBA搏击俱乐部的第一个规则...... (3认同)
  • @ chaos @很好.我更喜欢后者,但仍然投票给你.开采啤酒,谢谢:) (2认同)

van*_*van 10

如果您的"交集"实际上是一个实体,则使用版本1,这意味着:

  • 它有其他属性
  • 你可以搜索那些对象(而不是导航关系)

用户版本-2,如果它是纯粹的NM关系表.在这种情况下还要确保:

  • 你有PK(CLUSTERED)与你的搜索表相关的第一列更频繁:例如,如果你的表是人员地址,那么我会假设你会更频繁地搜索一个人的所有地址然后为所有人在这个地址.所以你应该先把你的PK包含在PersonID中
  • 你仍然可以有另一个单列UNIQUE标识符,但只是:

    1. 或者不要把它变成PK
    2. 或者使它成为PK,但指定NON CLUSTERED,以便您可以使用CLUSTERED作为覆盖两个引用列的UNIQUE索引
    3. 除非您的设计使用GUID,否则您可以坚持使用INT IDENTITY列类型

在这两种情况下,您可能想要创建另一个覆盖2列的INDEX,但是在另一个顺序中,如果您经常从关系的另一侧进行搜索.


tek*_*ues 9

第二个版本对我来说是最好的,它避免了创建额外的索引.