SQL Primary Key & Foreign Key
1. 定義
維基百科:
主鍵
(Primary Key)是數據表中每條記錄唯一且完整的標識;外鍵
(Foreign Key),又稱外來鍵,是另一個數據表中的字段。
慕課解釋:
主鍵
十分重要,每一張表都應有一個主鍵,且主鍵只能有一個,主鍵不能為空;外鍵
用來表示表與表之間的關系,是關系數據庫的核心,一般使用另一張表的主鍵作為外鍵。
2. 前言
本小節,我們將學習 SQL 中的主鍵
和外鍵
。
在前面的學習中,我們一直聚焦在 SQL 增刪查改等操作。對于關系數據庫,最核心的東西莫過于關系
二字,在開發中,表 A 的主鍵一般會作為表 B 的外鍵,來表示表 A 與表 B 之間的關系。
注意: 在前面的小節中,新建數據庫時均未指定主鍵,但實際上應該為每一張表都指定一個主鍵,后面的例子中將踐行這條原則。
3. SQL Primary Key
在 SQL CREATE2 一節中,我們介紹了主鍵的基本用法。在實際的開發中,主鍵至關重要,所以一般還需加上其它約束,如 unsigned、auto_increment 等。
3.1 例1 創建用戶表
請書寫 SQL 語句,創建imooc_user
表,共有 id,username 和 age 三個字段,其中 id 為主鍵,數據類型為 unsigned int 且自增,username 為 varchar 類型,age 表示年齡,為 int 類型。
分析:
新建數據表使用 Create 指令,username 和 age 為基本類型字段,id 作為主鍵,字段類型為無符號整型,且自增,故該字段需要添加 auto_increment 約束。
語句:
整理可得語句如下:
CREATE TABLE imooc_user
(
id int unsigned PRIMARY KEY AUTO_INCREMENT,
username varchar(20),
age int
);
(MySQL數據庫)創建成功后,imooc_user表信息如下:
+----------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | <null> | auto_increment |
| username | varchar(20) | YES | | <null> | |
| age | int(11) | YES | | <null> | |
+----------+------------------+------+-----+---------+----------------+
不同的數據庫對于自增的支持是不同的,有些數據庫甚至不支持自增主鍵,PostgreSQL 中使用 serial 類型來支持自增,如下:
CREATE TABLE imooc_user
(
id serial PRIMARY KEY,
username varchar(20),
age int
);
4. SQL Foreign Key
外鍵
是一類頗為特殊的字段,既可以像其它普通字段一樣存儲數據,更可以用來表示表與表之間的聯系,這正是關系數據庫的核心所在。
因為主鍵可以唯一標識一條記錄,所以一張表的外鍵字段一般是另一張表的主鍵
。
外鍵是一種約束,其語法如下:
FOREIGN KEY ([col1]) REFERENCES [table_name]([col2])
其中col1
表示當前表的外鍵字段名,table_name
是另一張數據表名稱,col2
表示另一張表的字段名稱。
4.1 例2 創建用戶積分表
請書寫 SQL 語句,創建imooc_user_score
表,共有 id,user_score 和 user_id 三個字段,其中 id 字段為主鍵且自增,user_score 表示用戶積分,數據類型為整形,user_id
為外鍵指向 imooc_user 的主鍵 id。
分析:
新建數據表使用 Create 指令,user_score 為基本類型字段,id 作為主鍵,user_id 為外鍵。
語句:
整理可得語句如下:
CREATE TABLE imooc_user_score
(
id int unsigned PRIMARY KEY AUTO_INCREMENT,
user_score int,
user_id int unsigned,
FOREIGN KEY (user_id) REFERENCES imooc_user(id)
);
SQL 語句中,user_id 是 imooc_user_score 的字段,同時它也是外鍵,它的值來源于表 imooc_user 的 id 字段。
(MySQL)新建成功后,信息如下:
+------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | <null> | auto_increment |
| user_score | int(11) | YES | | <null> | |
| user_id | int(10) unsigned | YES | MUL | <null> | |
+------------+------------------+------+-----+---------+----------------+
若使用 PostgreSQL,新建語句如下:
CREATE TABLE imooc_user_score
(
id serial PRIMARY KEY,
user_score int,
user_id int,
FOREIGN KEY (user_id) REFERENCES imooc_user(id)
);
5. 小結
- PostgreSQL 的整型字段不支持 unsigned 無符號,且無自增約束,但有自增數據類型 serial。
- 大部分場景中,主鍵一般都為自增字段,當然也有選擇
uuid
作為主鍵的,但自增主鍵性能更加優異。 - 外鍵是體現數據表關系的核心功能點,但主流的外鍵方式卻都是
弱外鍵
。