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

时间:2010-09-23 02:04:21

标签: sql mysql foreign-keys

同一列是否有主键和&外键约束到另一列?

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

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

Delete from table1 where ID=1000;

感谢。

4 个答案:

答案 0 :(得分:20)

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

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

如果我们使用CASCADE选项在table1上定义了外键,我们就可以删除父项,并且所有子项都会自动删除:

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

如果我们要重复之前失败的DELETE,则会删除table1中的子行以及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)

答案 1 :(得分:9)

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

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 :(得分:0)

是的,它可以。

不,它不会。

P.S。但是,如果不删除相应的table1行,你将无法删除table2数据。

P.P.S。我在Postgres中实现了这样的结构,但它必须与MySQL类似。

答案 3 :(得分:0)

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