【问题标题】:How to insert a row with a foreign key that references a composite key如何插入具有引用复合键的外键的行
【发布时间】:2019-05-25 18:06:43
【问题描述】:

我有一个带有复合主键的 mysql 表,以及一个使用外键引用第一个的子表。

插入一行子表的正确语法是什么?

如何在插入语句中给出组合键的两个部分?

我有这些表;

CREATE TABLE IF NOT EXISTS parent (
    p_id    INT NOT NULL,
    p_org   INT NOT NULL,
    PRIMARY KEY(p_id, p_org),
    p_name  VARCHAR(12))
ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS child (
    c_id    INT NOT NULL PRIMARY KEY,
    c_org   INT NOT NULL,
    c_p_id  INT NOT NULL, FOREIGN KEY(c_p_id, c_org) REFERENCES parent(p_id, p_org),
    c_info  VARCHAR(12))
ENGINE=InnoDB;

向父级插入两行后;

insert into parent values(100, 1, 'name-1'), (100, 2, 'name-2');

我想在 child 中插入一行。

insert into child values(1000, 2, 100, 'info-for-2');

但我不知道如何指定复合键。我想指定 (100 和 2) 而不是 100,以便我的子行仅使用 (100 2) 引用父行。

使用上面的插入语句,我的查询返回两行而不是一行;

select * from parent join child on c_p_id = p_id;

返回;

p_id    p_org   p_name  c_id    c_org   c_p_id  c_info
100     1       name-1  1000    2       100     info-for-2
100     2       name-2  1000    2       100     info-for-2

但想只获得 (100 2) 的行。

我真的必须在连接上指定 c_org 吗?

【问题讨论】:

    标签: mysql sql foreign-keys sql-insert composite-primary-key


    【解决方案1】:

    是的,您必须在连接上指定 c_org:

     select * from parent join child on c_p_id = p_id && c_org = p_org;
    

    您的外键是“c_p_id”和“c_org”,而不仅仅是“c_p_id”。您必须在所有外键列上进行连接。

    【讨论】:

      【解决方案2】:

      是的,你需要在join中指定c_org,你的查询变成这样:

      select * from parent join child on c_p_id = p_id and c_org = p_org;
      

      这可以在fiddle看到

      您需要这样做,因为您有一个复合外键。

      【讨论】:

        【解决方案3】:

        您应该开始养成在INSERT 语句中明确提及目标列的习惯。

        然后,如果你在parent 中插入一行

        INSERT INTO parent
                    (p_id,
                     p_org)
                    VALUES (2,
                            100,
                            'name-2');
        

        您在child 中插入一行引用parent 中的行,方法是将parent 的主键元组的确切值插入childs 外键元组的列中

        INSERT INTO child
                    (c_id,
                     c_org,
                     c_p_id,
                     c_info)
                    VALUES (1000,
                            2,
                            100,
                            'info-for-2');
        

        要连接行,您需要检查主键中的所有值是否与ON 子句中的外键值匹配。这里可以使用AND

        SELECT *
               FROM parent p
                    INNER JOIN child c
                               ON c.c_p_id = p.p_id
                                  AND c.c_org = p.p_org;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-02-06
          • 1970-01-01
          • 2022-11-21
          • 2019-06-23
          • 2018-02-02
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多