📄 一句话概括
AUTO_INCREMENT 让数据库自动发号:插入时不用给编号,数据库自己按 1、2、3……往下排——编号这种「程序最不该手工管」的事,交给机器最稳当。
📝 本节和前面几节的关系
编号列就是 4-12 主键最常用的形状。本节还带一个环境注记:AUTO_INCREMENT 是 MySQL 的写法,前面三章一直在用的在线 SQLite 环境里对应的是 AUTOINCREMENT(或干脆用 INTEGER PRIMARY KEY 的隐式发号)——Demo 里两种都给。
一、为什么编号不该手工管
自己维护编号的问题:两个人同时插入怎么办?删掉一条后号怎么补?手工管迟早出乱子。数据库的答案:
-- MySQL 写法
CREATE TABLE students (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20)
);
INSERT INTO students (name) VALUES ('张三'); -- 不给 id
INSERT INTO students (name) VALUES ('李四'); -- 也不给
-- id 自动是 1、2
二、SQLite 环境的对应写法
本课 Demo 用的在线 SQLite 环境:
-- SQLite 写法(三选一)
CREATE TABLE s1 (id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(20));
CREATE TABLE s2 (id INTEGER PRIMARY KEY, name VARCHAR(20)); -- 隐式自增(推荐)
INTEGER PRIMARY KEY 在 SQLite 里天生就是自动发号——插 NULL 或省略都行,编号从 1 开始递增。名字不同、脾气一样。
三、发号规则三件事
- 只增不补:删掉 id=3,下一条还是从最大号 +1 开始发,不会回头填 3
- 并发安全:两人同时插入,数据库保证各拿各的号,绝不撞车
- 不要依赖连续性:删除、事务回滚(4-16)都会留空洞;业务若要求「发票号必须连续」,用别的机制,别指望自增列
四、动手 Demo:删了不回头
CREATE TABLE t (id INTEGER PRIMARY KEY, name VARCHAR(20));
INSERT INTO t (name) VALUES ('甲'); -- id=1
INSERT INTO t (name) VALUES ('乙'); -- id=2
INSERT INTO t (name) VALUES ('丙'); -- id=3
DELETE FROM t WHERE id = 3;
INSERT INTO t (name) VALUES ('丁'); -- id=4,不是 3!
SELECT * FROM t;
id name
1 甲
2 乙
4 丁
3 号位永远空着——发号器只前进,不回头。
五、30 秒实验
显式插一个超大号 INSERT INTO t VALUES (100, '大号'),再省略 id 插一条——下一条自动是 101:计数器以最大值为准。(有些实现允许插入指定号并会更新计数器,视数据库而定。)
六、常见误区
- 「自增编号可以用作业务编号」:订单号、发票号要求连续或有格式,别用自增列硬凑
- 「删了记录,号会回收复用」:不会,只增不减;空洞是正常现象,别慌
自测三问
1. MySQL 和 SQLite 的自动编号分别怎么写?(AUTO_INCREMENT / INTEGER PRIMARY KEY 隐式自增) 2. 删掉 3 号后下一条是几号?(最大号 +1,不是 3) 3. 为什么不能拿自增列当发票号?(不保证连续——删除与回滚都留洞)- ☐ 下一节(4-12 PRIMARY KEY、主关键字、主键-使记录可以进行唯一识别)
相关笔记
- UNIQUE-避免输入与其他记录重复的值 —— 上一节:不重复的另一员
- PRIMARY KEY、主关键字、主键-使记录可以进行唯一识别 —— 下一节:自增列最常服务的对象
- 回滚-取消一组已经执行的处理 —— 回滚也会留编号空洞
- 🗄️ 数据库基础 · 索引 —— 全课路线图