簡體   English   中英

同一列可以對另一列有主鍵和外鍵約束嗎

[英]Can the same column have primary key & foreign key constraint to another column

同一列可以對另一列具有主鍵和外鍵約束嗎?

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

如果我嘗試刪除 table1 數據,這會是一個問題嗎?

Delete from table1 where ID=1000;

謝謝。

將主鍵和外鍵分配給表中的同一列:

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

應該沒有問題。 考慮以下示例:

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)

是的,它可以。

不,不會。

PS但是如果不刪除相應的table1行,您將無法刪除table2數據。

PPS 我已經在 Postgres 中實現了這樣的結構,但它對於 MySQL 必須是類似的。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM