【问题标题】:Can the same column have primary key & foreign key constraint to another column同一列可以对另一列有主键和外键约束吗
【发布时间】:2010-09-23 02:04:21
【问题描述】:

同一列可以对另一列有主键和外键约束吗?

Table1: ID - Primary column, foreign key constraint for Table2 ID
Table2: ID - Primary column, Name 

如果我尝试删除 table1 数据,这会是一个问题吗?

Delete from table1 where ID=1000;

谢谢。

【问题讨论】:

标签: sql mysql foreign-keys


【解决方案1】:

将主键和外键分配给表中的同一列:

create table a1 (
    id1 int not null primary key 
);
insert into a1 values(1),(2),(3),(4);

create table a2 (
    id1 int not null primary key foreign key references a1(id1)
);
insert into a2 values(1),(2),(3);

【讨论】:

    【解决方案2】:

    应该没有问题。考虑以下示例:

    CREATE TABLE table2 (
       id int PRIMARY KEY,
       name varchar(20)
    ) ENGINE=INNODB;
    
    CREATE TABLE table1 (
       id int PRIMARY KEY, 
       t2_id int, 
       FOREIGN KEY (t2_id) REFERENCES table2 (id)
    ) ENGINE=INNODB;
    
    INSERT INTO table2 VALUES (1, 'First Row');
    INSERT INTO table2 VALUES (2, 'Second Row');
    
    INSERT INTO table1 VALUES (1, 1);
    INSERT INTO table1 VALUES (2, 1);
    INSERT INTO table1 VALUES (3, 1);
    INSERT INTO table1 VALUES (4, 2);
    

    这些表格现在包含:

    SELECT * FROM table1;
    +----+-------+
    | id | t2_id |
    +----+-------+
    |  1 |     1 |
    |  2 |     1 |
    |  3 |     1 |
    |  4 |     2 |
    +----+-------+
    4 rows in set (0.00 sec)
    
    SELECT * FROM table2;
    +----+------------+
    | id | name       |
    +----+------------+
    |  1 | First Row  |
    |  2 | Second Row |
    +----+------------+
    2 rows in set (0.00 sec)
    

    现在我们可以像这样成功删除行了:

    DELETE FROM table1 WHERE id = 1;
    Query OK, 1 row affected (0.00 sec)
    
    DELETE FROM table1 WHERE t2_id = 2;
    Query OK, 1 row affected (0.00 sec)
    

    但是我们无法删除以下内容:

    DELETE FROM table2 WHERE id = 1;
    ERROR 1451 (23000): A foreign key constraint fails
    

    如果我们在table1 上使用CASCADE 选项定义外键,我们将能够删除父级,并且所有子级都将被自动删除:

    CREATE TABLE table2 (
       id int PRIMARY KEY,
       name varchar(20)
    ) ENGINE=INNODB;
    
    CREATE TABLE table1 (
       id int PRIMARY KEY, 
       t2_id int, 
       FOREIGN KEY (t2_id) REFERENCES table2 (id) ON DELETE CASCADE
    ) ENGINE=INNODB;
    
    INSERT INTO table2 VALUES (1, 'First Row');
    INSERT INTO table2 VALUES (2, 'Second Row');
    
    INSERT INTO table1 VALUES (1, 1);
    INSERT INTO table1 VALUES (2, 1);
    INSERT INTO table1 VALUES (3, 1);
    INSERT INTO table1 VALUES (4, 2);
    

    如果我们要重复之前失败的DELETEtable1 中的子行以及table2 中的父行将被删除:

    DELETE FROM table2 WHERE id = 1;
    Query OK, 1 row affected (0.00 sec)
    
    SELECT * FROM table1;
    +----+-------+
    | id | t2_id |
    +----+-------+
    |  4 |     2 |
    +----+-------+
    1 row in set (0.00 sec)
    
    SELECT * FROM table2;
    +----+------------+
    | id | name       |
    +----+------------+
    |  2 | Second Row |
    +----+------------+
    1 row in set (0.00 sec)
    

    【讨论】:

    • 如果我错了,请纠正我,但我看不出这是如何回答问题的。 (以及为什么它已被接受。)问题是我们是否可以让同一列对另一列具有主键和外键约束。接受的答案引入了第二列(t2_id)作为外键,它没有显示既是主键又是外键的列。
    • 我想我会在这里找到答案:/
    • 这个答案与所提问题无关。不知道为什么被接受。考虑到这是公认的答案,我阅读了完整的答案(很长),然后发现它没有相关性。
    【解决方案3】:

    是的,可以。

    不,不会。

    附注但是如果不删除相应的table1行,您将无法删除table2数据。

    P.P.S.我已经在 Postgres 中实现了这样的结构,但是对于 MySQL 来说它必须是类似的。

    【讨论】:

      【解决方案4】:

      Jason 提供的答案可能在过去一段时间内有效,但当我在 2021 年尝试将此答案用于 MySQL 5.7 服务器时,它会抱怨。我用来完成这项工作的语法是;

      CREATE TABLE a1 (
          id1 INT NOT NULL PRIMARY KEY
      );
      INSERT INTO a1 VALUES (1),(2),(3),(4);
      
      CREATE TABLE a2 (
          id1 INT NOT NULL,
          PRIMARY KEY (id1),
          CONSTRAINT `fk_id1` FOREIGN KEY (id1) REFERENCES a1(id1)
      );
      INSERT INTO a2 VALUES (1),(2),(3);
      

      对于这种类型的一对一关系,我也强烈建议您将外键创建为;

      CONSTRAINT `fk_id1` FOREIGN KEY (id1) REFERENCES a1(id1) ON DELETE CASCADE
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-24
        • 1970-01-01
        • 2015-06-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多