【问题标题】:Can a junction table (join table) also be used for a one-to-many relationship?联结表(join table)也可以用于一对多关系吗?
【发布时间】:2010-10-25 00:47:25
【问题描述】:

根据定义,Junction Table(桥表/链接表)用于多对多关系,如下使用:

CREATE TABLE Users
(
UserLogin varchar(50) PRIMARY KEY,
UserPassword varchar(50) NOT NULL,
UserName varchar(50) NOT NULL
)


CREATE TABLE Permissions
(
PermissionKey varchar(50) PRIMARY KEY,
PermissionDescription varchar(500) NOT NULL
)


--This is the junction table.
CREATE TABLE UserPermissions
(
UserLogin varchar(50) REFERENCES Users (UserLogin),
PermissionKey varchar(50) REFERENCES Permissions (PermissionKey),
PRIMARY KEY (UserLogin, PermissionKey)
)

但它是否也可以轻松地用于一对多关系,就像在这个示例中,一个用户与多个订单相关联:

(我不太了解数据库,所以如果我有误解,请纠正我。)

CREATE TABLE Users
(
UserLogin varchar(50) PRIMARY KEY,
UserPassword varchar(50) NOT NULL,
UserName varchar(50) NOT NULL
)


CREATE TABLE Orders
(
OrderKey varchar(50) PRIMARY KEY,
OrderDescription varchar(500) NOT NULL
)


--This is the junction table.
CREATE TABLE UserOrders
(
UserLogin varchar(50) REFERENCES Users (UserLogin),
OrderKey varchar(50) REFERENCES Orders (OrderKey),
PRIMARY KEY (UserLogin, OrderKey)
)

【问题讨论】:

    标签: many-to-many database one-to-many junction-table


    【解决方案1】:

    没有任何理由不能将联结表用于一对多关系。问题通常是性能之一。为什么在不需要时让数据库加入一个额外的表?

    【讨论】:

    • 在外键大多为 NULL 的情况下怎么办?如果联结表或这些表之间的关联很少被查询或连接,那么拥有一个节省空间的联结表会更好吗?
    【解决方案2】:

    是的,仍然可以在联结表中存储和强制执行一对多关系。

    在您的示例中,您没有对 UserOrders 联结表实施任何约束,因此单个订单可以属于两个用户(假设这是不正确的)。为了强制您可以使OrderKey 成为UserOrders 联结表的主键(或对该列具有唯一约束)。从技术上讲,这将成为UserOrdersUsers 之间的多对一 关系,而Orders 和@987654327 之间具有一对一 关系@。

    我只能考虑使用联结表设计 多对一 关系的一个原因 - 如果您打算允许 多对多 关系在未来,不想处理数据迁移。但与此同时,您将支付存储和加入额外表的费用。

    【讨论】:

    • 有时如果您想拥有相同的数据库表结构但决定应用程序中的关系类型:一对多或多对多,这可能会很方便。 (作为一个参数)有时候,当您开发一对多关系时,知道它很可能会变为多对多。
    • 我明白了。如果您想在数据库中强制执行一对多或多对多,您可以使用某种类型的约束吗?
    • @jt 如果您在谈论联合表,那么您不能仅使用表来强制执行一对多关系。否则,您的意思是通过“外键”约束来执行它。在一对多关系中,“多”方有一个带有约束的字段,这意味着每一行都必须指向“一”方(在外键列中有一方的 id 并且它不允许那里有其他值)。
    • 在联结表中,您可以轻松地在 1 或 2 列上分别执行一对多或一对一的唯一约束。
    • 这个答案是错误的。 PK/UNIQUE 约束强制执行 1:many。
    【解决方案3】:

    这将是多对多:

    CREATE TABLE UserOrders
    (UserLogin varchar(50) REFERENCES Users (UserLogin),
    OrderKey varchar(50) REFERENCES Orders (OrderKey),
    PRIMARY KEY (UserLogin, OrderKey));
    

    这将是一对多的(一个用户有很多订单):

    CREATE TABLE UserOrders
    (UserLogin varchar(50) REFERENCES Users (UserLogin),
    OrderKey varchar(50) REFERENCES Orders (OrderKey),
    PRIMARY KEY (OrderKey));
    

    注意 PRIMARY KEY 约束的区别。

    【讨论】:

      【解决方案4】:

      一旦你建立了一个表,它就没有“Junction”表、“associative”表、“join”表的类型——它只是一个表。

      我们使用这些术语来描述最初创建实体(和结果表)的具体原因。最初创建关联实体是为了解决多对多的情况。但是这些表通常都有自己的属性(例如关联的时间、关联的原因等)。所以 SQL Server、Oracle 或您的代码没有理由知道为什么要创建一个表……只是因为它是一个表。

      从技术的角度来看,关联表和任何其他表之间确实没有任何区别。

      因此,这些表可以充当任何其他表可以履行的任何角色。没有关于其他表如何与它们关联的规则。

      【讨论】:

        【解决方案5】:

        您可以在连接/连接表中强制执行“一个”约束,向作为外键的列添加唯一约束(或使其成为连接表的主键,因为该属性本身标识关系)到“多”的一面。那是因为您希望多方中的 rwos 只有一个关系,并且关系在联接/联结表中说明。

        【讨论】:

          【解决方案6】:

          我认为您的概念有误 - 如果有帮助,这里有一个简单的解释: 要实现两个表(比如 A 和 B)之间的多对多关系,我们需要借助一个与两个表都具有一对多关系的联结表(比如表 c) A 和 B。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-03-06
            • 1970-01-01
            • 2019-11-07
            • 2019-11-21
            • 2022-01-19
            • 2016-08-21
            • 2019-04-29
            • 2017-01-18
            相关资源
            最近更新 更多