### 3.6.6 使用外鍵
在 MySQL 中, `InnoDB` 表支持檢查外鍵約束. 參閱 [Chapter 15, InnoDB 存儲引擎](https://dev.mysql.com/doc/refman/8.0/en/innodb-storage-engine.html), 和 [Section 1.8.2.3, “外鍵差異”](https://dev.mysql.com/doc/refman/8.0/en/ansi-diff-foreign-keys.html).
外鍵約束不僅僅用于連接兩個表. 除了 `InnoDB` 存儲引擎, 在定義列時使用 `REFERENCES tbl_name(col_name)` 子句, 該句沒有實際的效果, *只是作為一個備忘錄或者注釋告訴你當前定義的列是指的另外一張表的列*. 使用這種語法時, 認識到這一點非常重要:
- MySQL 不執行任何檢查來確保 *col_name* 確實存在于 *tbl_name* (甚至 *tbl_name* 本身是否存在).
- MySQL 不會對 *tbl_name* 執行任何類型的操作, 例如刪除行以響應對你定義的表中的行的響應; 換句話講, 這個語法不會對 `ON DELETE or ON UPDATE` 行為產生任何影響. (雖然你可以將 `ON DELETE` 或者 `ON UPDATE` 子句作為 `REFERENCES` 子句的一部分, 但它被忽略.)
- 該語法創建一個*列*; 它***不***會創建任何索引或者鍵.
你可以創建列作為連接列, 如下所示:
```sql
CREATE TABLE person (
id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
name CHAR(60) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE shirt (
id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
style ENUM('t-shirt', 'polo', 'dress') NOT NULL,
color ENUM('red', 'blue', 'orange', 'white', 'black') NOT NULL,
owner SMALLINT UNSIGNED NOT NULL REFERENCES person(id),
PRIMARY KEY (id)
);
INSERT INTO person VALUES (NULL, 'Antonio Paz');
SELECT @last := LAST_INSERT_ID();
INSERT INTO shirt VALUES
(NULL, 'polo', 'blue', @last),
(NULL, 'dress', 'white', @last),
(NULL, 't-shirt', 'blue', @last);
INSERT INTO person VALUES (NULL, 'Lilliana Angelovska');
SELECT @last := LAST_INSERT_ID();
INSERT INTO shirt VALUES
(NULL, 'dress', 'orange', @last),
(NULL, 'polo', 'red', @last),
(NULL, 'dress', 'blue', @last),
(NULL, 't-shirt', 'white', @last);
SELECT * FROM person;
+----+---------------------+
| id | name |
+----+---------------------+
| 1 | Antonio Paz |
| 2 | Lilliana Angelovska |
+----+---------------------+
SELECT * FROM shirt;
+----+---------+--------+-------+
| id | style | color | owner |
+----+---------+--------+-------+
| 1 | polo | blue | 1 |
| 2 | dress | white | 1 |
| 3 | t-shirt | blue | 1 |
| 4 | dress | orange | 2 |
| 5 | polo | red | 2 |
| 6 | dress | blue | 2 |
| 7 | t-shirt | white | 2 |
+----+---------+--------+-------+
SELECT s.* FROM person p INNER JOIN shirt s
ON s.owner = p.id
WHERE p.name LIKE 'Lilliana%'
AND s.color <> 'white';
+----+-------+--------+-------+
| id | style | color | owner |
+----+-------+--------+-------+
| 4 | dress | orange | 2 |
| 5 | polo | red | 2 |
| 6 | dress | blue | 2 |
+----+-------+--------+-------+
```
當以這種方式使用時, `REFERENCES` 子句不會顯示在 [SHOW CREATE TABLE](https://dev.mysql.com/doc/refman/8.0/en/show-create-table.html) or [DESCRIBE](https://dev.mysql.com/doc/refman/8.0/en/describe.html) 的輸出中:
```sql
SHOW CREATE TABLE shirt\G
*************************** 1. row ***************************
Table: shirt
Create Table: CREATE TABLE `shirt` (
`id` smallint(5) unsigned NOT NULL auto_increment,
`style` enum('t-shirt','polo','dress') NOT NULL,
`color` enum('red','blue','orange','white','black') NOT NULL,
`owner` smallint(5) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4
```
按這種方式使用 `REFERENCES` 作為注釋或者 “提示” 創建列適用于 `MyISAM` 表.
- 簡介
- 前言和法律條款
- 安裝和更新 MySQL
- 在 Linux 上安裝 MySQL
- 在 Linux 上使用 APT 庫安裝 MySQL
- 在 Linux 上使用 Docker 部署 MySQL
- 使用 Docker 部署 MySQL 服務器的基本步驟
- 使用 Docker 部署 MySQL 服務器的更多主題
- 教程
- 連接到服務器和從服務器斷開
- 輸入查詢
- 創建和使用數據庫
- 創建和選擇數據庫
- 創建表
- 將數據加載到表中
- 從表中檢索數據
- 選擇所有數據
- 選擇特定行
- 選擇指定列
- 行排序
- 日期計算
- 處理 NULL 值
- 模式匹配
- 計算行數
- 使用多個表
- 獲取數據庫和表的信息
- 在批處理模式使用 mysql
- 常見查詢示例
- 列的最大值
- 包含某一行最大值的記錄
- 每組中列的最大值
- 擁有某個字段的組間最大值的行
- 使用用戶自定義變量
- 使用外鍵
- 兩個鍵上搜索
- 計算每日訪問量
- 使用 AUTO_INCREMENT
- 在 Apache 中使用 MySQL
- MySQL 程序
- MySQL 客戶端程序
- mysql — MySQL 命令行客戶端
- 優化
- 優化概述
- 優化 SQL 語句
- 優化和索引
- 優化數據庫結構
- 優化 InnoDB 表
- 優化 MyISAM 表
- 優化 MEMORY 表
- 理解查詢執行計劃
- 控制查詢優化器
- 緩沖和緩存
- 優化鎖操作
- 優化 MySQL 服務器
- 測量性能 (Benchmarking)
- 檢查線程信息