代码之家  ›  专栏  ›  技术社区  ›  Andrey

与多个表相关的一对多关系

  •  1
  • Andrey  · 技术社区  · 14 年前

    我有一个场景,其中: 有两个(或更多)表表示独立项。比如说用户和公司

    这两个表都需要存储地址。每个可以有一个或多个地址

    在普通的1对多方案地址表中,woudl只有一个userid或companyid来创建普通的1对多关系。

    在这种情况下,我可以想到一些方法

    1. 地址表可以同时具有用户ID和公司ID,并且每个记录只能使用一个。

    2. 可以使用2个键object id和objecttype,以便object id具有user id或company id,objecttype woudl是user或company

    3. 创建一个objecttable并向用户和公司添加objectid。地址将有一个OjBectID

    我真的不喜欢这些解决方案。我想知道这里最好的方法是什么。

    另一个注意事项是,我很可能会为我的数据访问层使用linqtosql。

    4 回复  |  直到 14 年前
        1
  •  2
  •   Adam Crossland    14 年前

    我不确定Linq to SQL的含义,但是解决这个问题的一个模型是使用多个 Junction Tables .

    在您的示例中,您将拥有一个名为AddressUsers的表,该表有两列:AddressID和UserID,以及一个名为AddressCompanies的表,该表具有AddressID和CompanyID列。

        2
  •  1
  •   tpdi    14 年前

    多对多:

    地址表,具有唯一的合成ID(例如,自动增量)。

    用户地址表,具有唯一的合成ID(例如,自动增量)、用户ID外键和地址外键。

    公司地址表,具有唯一的合成ID(例如,自动增量)、公司ID外键和地址外键。

    (请注意,如果用户(或公司)可以 只有 在一个地址中,用户表(或公司表)中只有一个地址\id外键。这不是您的用例。)

        3
  •  1
  •   Marcus Adams    14 年前

    你所拥有的是一种多态性关联。我不熟悉linqtosql,但是如果它支持这种关系的引用完整性,那么不要害怕,做任何映射。

    在标准实践中,多态关联通常可以通过逆转来克服。您应该为用户和公司分别使用一个交叉点(连接)表来连接到地址。这类似于多对多关系,其中交叉表中的每一行引用一个用户和一个地址。

    如果使用交叉表,为了避免多对多(但保持一对多),请对交叉表中的地址键施加唯一约束。

    如果有ORM问题,请使用与useraddress和companyaddress联接的父地址表。

        4
  •  1
  •   Tony    14 年前

    我建议遵循TPDI的建议,但在用户/公司和地址之间使用一对多的关系;至少这样,您的所有关键数据类型都是相同的。

    添加我的答案的主要原因是为了响应您存储ObjectId和ObjectType的第二个建议—属性拆分是一个坏主意,请避免!

    请阅读此Celko文章: http://www.tdan.com/view-featured-columns/9852