代码之家  ›  专栏  ›  技术社区  ›  Dan McClain

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

  •  22
  • Dan McClain  · 技术社区  · 17 年前

    我想知道对于多对多关系来说,交集表的更好设计是什么。

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

    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 )
    ) 
    

    CREATE TABLE SomeIntersection 
    (
         TableAId UNIQUEIDENTIFIER REFERENCES TableA NOT NULL,
         TableBId UNIQUEIDENTIFIER REFERENCES TableB NOT NULL,
         PRIMARY KEY(TableAId, TableBId )
    ) 
    

    一个比另一个有好处吗?
    编辑2:***请注意:

    编辑:

    CREATE TABLE SomeIntersection 
    (
         ParentRecord INT REFERENCES TableA NOT NULL,
         ChildRecord INT REFERENCES TableA NOT NULL,
         PRIMARY KEY(TableAId, TableBId )
    )
    

    ParentRecord          ChildRecord
    =================================
          1                    1         --Cyclical reference! 
    
    11 回复  |  直到 17 年前
        1
  •  14
  •   chaos    17 年前

    这是一个有争议的话题。我更喜欢第一种形式,因为我认为最好能用一个值查找映射行,并希望在每一个表中都有一个单列主键,这是愚蠢的一致性。另一些人认为拥有那个专栏是对空间的愚蠢浪费。

    我们每隔两个月就在新泽西的一家酒吧举行几轮裸指关节拳击比赛。

        2
  •  10
  •   van    17 年前

    使用 第1版 如果您的“交叉点”实际上是一个单独的实体,则意味着:

    • 您可以搜索这些对象(而不是导航关系)

    使用者 版本2 如果它是纯N-M关系表。在这种情况下,还应确保:

    • 您的PK(集群)与第一列相关,该列与您的搜索频率更高:例如,如果您的表是Person Address,那么我假设您将更频繁地搜索一个人的所有地址,而不是该地址的所有人。所以你应该把你的PK放在包括PersonID的第一位
    • 您仍然可以拥有另一个单列唯一标识符,但只需:

      1. 除非您在设计中使用guid,否则您可以坚持使用INT-IDENTITY列类型

    在这两种情况下,如果您经常从关系的另一端搜索,您可能希望创建另一个覆盖这两列的索引,但顺序不同。

        3
  •  9
  •   tekBlues    17 年前

        4
  •  4
  •   KM.    17 年前

    如果使用第一种方法,只需在PK上使用标识,就不需要使用唯一标识浪费空间(磁盘和内存缓存)。

        5
  •  4
  •   Joel Coehoorn    17 年前

    我清楚地记得我在学校的数据库教授说过,交叉关系几乎总是一个实体,因此通常值得为它分配空间。这表明前者更“正确”。

    尽管如此,我个人倾向于选择后者。这实际上取决于您是否会直接检索其中一条记录,或者是否只在连接原始表时使用该表。

        6
  •  3
  •   dance2die    17 年前

    从开发人员的角度来看,我更喜欢前者。 在处理它时,编写和测试更容易。

        7
  •  3
  •   Tim Sullivan    17 年前

    如果交集表中没有任何其他字段,那么它实际上不需要自己的ID,添加一个也不会带来任何好处。但是,如果要将其他字段放入该表中,并且在许多情况下会这样做,则该表应该有自己的ID作为主键。

    当然是经验法则,但你看吧。

        8
  •  3
  •   empz    17 年前

    回答你的第二个问题。。。

    CREATE TABLE SomeIntersection 
    (
         ParentRecord INT REFERENCES TableA NOT NULL,
         ChildRecord INT REFERENCES TableA NOT NULL,
         PRIMARY KEY(TableAId, TableBId),
         CHECK (ParentRecord <> ChildRecord)
    )
    
        9
  •  1
  •   Shane Fulmer Lasse V. Karlsen    17 年前

    第一种方法的好处:

    通过单个值查找联接表的功能。这使得客户端的一些查找操作更加简单。

    第二种方法的好处:

    更简单的数据模型,无需创建额外的索引。

    所需内存更少。

        10
  •  1
  •   Walter Mitty    17 年前

    第二个更好。它将接线盒(交叉盒)约束为同一对的外观不超过一个。如果接线盒中没有其他列,则无论如何都不会查找此表,除非通过两个外键。

        11
  •  0
  •   James Conigliaro    17 年前

    鉴于TableAId TableBId组合是唯一的,并且该表仅用于实现多对多关系,我将选择第二个选项。从纯逻辑的角度来看,第一个含义简化为第二个含义。从结构的角度来看,您的数据库需要维护主键/索引以及第一个实现的约束,而第二个实现只需要维护主键/索引。