###3.6.9 使用 AUTO_INCREMENT
`AUTO_INCREMENT` 屬性可用于為新記錄生成唯一標識:
```sql
CREATE TABLE animals (
id MEDIUMINT NOT NULL AUTO_INCREMENT,
name CHAR(30) NOT NULL,
PRIMARY KEY (id)
);
INSERT INTO animals (name) VALUES
('dog'),('cat'),('penguin'),
('lax'),('whale'),('ostrich');
SELECT * FROM animals;
```
返回結果為:
```sql
+----+---------+
| id | name |
+----+---------+
| 1 | dog |
| 2 | cat |
| 3 | penguin |
| 4 | lax |
| 5 | whale |
| 6 | ostrich |
+----+---------+
```
`AUTO_INCREMENT` 列沒有指定值, 所以 MySQL 會自動分配序列號. 你也可以顯式的為列分配0來生成序列號, 除非啟用了 [`NO_AUTO_VALUE_ON_ZERO`](https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html#sqlmode_no_auto_value_on_zero) 模式. 例如:
```sql
INSERT INTO animals (id,name) VALUES(0,'groundhog');
```
如果列被聲明為 `NOT NULL`, 也可以將 `NULL` 賦給列以生成序列號. 例如:
```sql
INSERT INTO animals (id,name) VALUES(NULL,'squirrel');
```
當你插入其它的值到 `AUTO_INCREMENT` 列, 列會被設置為該值, 序列會被重置, 以便下一個自動生成的值按照最大列值的順序生成. 例如:
```sql
INSERT INTO animals (id,name) VALUES(100,'rabbit');
INSERT INTO animals (id,name) VALUES(NULL,'mouse');
SELECT * FROM animals;
+-----+-----------+
| id | name |
+-----+-----------+
| 1 | dog |
| 2 | cat |
| 3 | penguin |
| 4 | lax |
| 5 | whale |
| 6 | ostrich |
| 7 | groundhog |
| 8 | squirrel |
| 100 | rabbit |
| 101 | mouse |
+-----+-----------+
```
更新已有的 `AUTO_INCREMENT` 列的值也會重置 `AUTO_INCREMENT` 序列.
你可以使用 [`LAST_INSERT_ID()`](https://dev.mysql.com/doc/refman/8.0/en/information-functions.html#function_last-insert-id) SQL 函數或者 [`mysql_insert_id()`](https://dev.mysql.com/doc/refman/8.0/en/mysql-insert-id.html) C API 函數檢索最近自動生成的 `AUTO_INCREMENT` 值. 這些函數是基于連接的, 所以它們的返回值不受其他執行插入的連接的影響.
對 `AUTO_INCREMENT` 列使用最小的整數數據類型, 該列要足夠大, 可以容納所需的最大序列值. 當列達到數據類型的上限時, 嘗試生成下一個序列號將會失敗. 使用 `UNSIGNED` 屬性允許更大的范圍. 例如, 如果你使用 [`TINYINT`](https://dev.mysql.com/doc/refman/8.0/en/integer-types.html), 最大允許的序列號時 127. 對于 [`TINYINT UNSIGNED`](https://dev.mysql.com/doc/refman/8.0/en/integer-types.html), 最大值為 255. 參閱 [Section 11.2.1, “整數類型(精確值) - INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT”](https://dev.mysql.com/doc/refman/8.0/en/integer-types.html) 獲取所有整數類型的范圍.
> **[warning] 注意**
>
> 對于多行插入, [`LAST_INSERT_ID()`](https://dev.mysql.com/doc/refman/8.0/en/information-functions.html#function_last-insert-id) 和 [`mysql_insert_id()`](https://dev.mysql.com/doc/refman/8.0/en/mysql-insert-id.html) 實際上從插入的*第一行*返回 `AUTO_INCREMENT` 鍵. 這允許在復制設置中其他服務器上正確的復制多行插入.
`AUTO_INCREMENT` 從超過 1 的值開始, 使用 [`CREATE TABLE`](https://dev.mysql.com/doc/refman/8.0/en/create-table.html) 或者 [`ALTER TABLE`](https://dev.mysql.com/doc/refman/8.0/en/alter-table.html) 設置值, 像這樣:
```sql
mysql> ALTER TABLE tbl AUTO_INCREMENT = 100;
```
#### InnoDB Notes
有關在 InnoDB 中關于 `AUTO_INCREMENT` 特定用法, 參閱 [Section 15.6.1.4, “InnoDB 中的 AUTO_INCREMENT 處理”](https://dev.mysql.com/doc/refman/8.0/en/innodb-auto-increment-handling.html).
#### MyISAM Notes
- 對于 `MyISAM` 表, 你可以指定在多列索引的第二列上指定 `AUTO_INCREMENT`. 在本例中, `AUTO_INCREMENT` 列生成的值計算為 [`MAX(auto_increment_column) + 1 WHERE prefix=given-prefix`](https://dev.mysql.com/doc/refman/8.0/en/group-by-functions.html#function_max). 對于你想將數據放入到有序組中時, 非常有用.
```sql
CREATE TABLE animals (
grp ENUM('fish','mammal','bird') NOT NULL,
id MEDIUMINT NOT NULL AUTO_INCREMENT,
name CHAR(30) NOT NULL,
PRIMARY KEY (grp,id)
) ENGINE=MyISAM;
INSERT INTO animals (grp,name) VALUES
('mammal','dog'),('mammal','cat'),
('bird','penguin'),('fish','lax'),('mammal','whale'),
('bird','ostrich');
SELECT * FROM animals ORDER BY grp,id;
```
返回結果為:
```sql
+--------+----+---------+
| grp | id | name |
+--------+----+---------+
| fish | 1 | lax |
| mammal | 1 | dog |
| mammal | 2 | cat |
| mammal | 3 | whale |
| bird | 1 | penguin |
| bird | 2 | ostrich |
+--------+----+---------+
```
在本例中 (當 `AUTO_INCREMENT` 列是多列索引中的一部分時), 如果刪除了任何組中 `AUTO_INCREMENT` 值最大的記錄, 那么會重復使用 `AUTO_INCREMENT` 值. 即便是 `MyISAM` 表也會發生這種親口光, `AUTO_INCREMENT` 值通常不會被重復使用.
- 如果 `AUTO_INCREMENT` 列是多列索引的一部分, MySQL 使用 `AUTO_INCREMENT` 列作為索引的開始(如果有的話)生成序列值. 例如, 如果 `animals` 表保存索引 `PRIMARY KEY (grp, id)` 和 `INDEX (id)`, MySQL 將會忽略用于生成序列值的 `PRIMARY KEY`. 因此, 該表將包含單個序列, 而不是每個 `grp` 值的序列.
#### 進一步閱讀
有關 `AUTO_INCREMENT` 的更多信息請點擊這里:
- 如何為列分配 `AUTO_INCREMENT` 屬性: [Section 13.1.20, “CREATE TABLE 語法”](https://dev.mysql.com/doc/refman/8.0/en/create-table.html), 和 [Section 13.1.9, “ALTER TABLE 語法”](https://dev.mysql.com/doc/refman/8.0/en/alter-table.html).
- `AUTO_INCREMENT` 的行為取決于 `NO_AUTO_VALUE_ON_ZERO` SQL 模式: [Section 5.1.11, “服務器 SQL 模式](https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html).
- 如何使用 [`LAST_INSERT_ID()`](https://dev.mysql.com/doc/refman/8.0/en/information-functions.html#function_last-insert-id) 函數找出包含最新 `AUTO_INCREMENT` 值的記錄: [Section 12.15, “信息函數”](https://dev.mysql.com/doc/refman/8.0/en/information-functions.html).
- 設置要使用的 `AUTO_INCREMENT` 的值: [Section 5.1.8, “服務器系統變量”](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html).
- [Section 15.6.1.4, “InnoDB 中的 AUTO_INCREMENT 處理”](https://dev.mysql.com/doc/refman/8.0/en/innodb-auto-increment-handling.html)
- `AUTO_INCREMENT` 和復制: [Section 17.4.1.1, “復制和 AUTO_INCREMENT”](https://dev.mysql.com/doc/refman/8.0/en/replication-features-auto-increment.html).
- 與復制相關的服務器系統變量 `AUTO_INCREMENT` ([`auto_increment_increment`](https://dev.mysql.com/doc/refman/8.0/en/replication-options-master.html#sysvar_auto_increment_increment) 和 [`auto_increment_offset`](https://dev.mysql.com/doc/refman/8.0/en/replication-options-master.html#sysvar_auto_increment_offset)) : [`Section 5.1.8, “服務器系統變量”`](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html).
- 簡介
- 前言和法律條款
- 安裝和更新 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)
- 檢查線程信息