在 SQLite 中,ALTER TABLE 命令用于 修改已存在的表结构,但功能 非常有限(相比 MySQL/PostgreSQL)。
SQLite 设计理念:简单、稳定,因此
ALTER只能做 改名 或 加列,不能直接删除/修改列。
一、ALTER TABLE 支持的 4 种操作
| 操作 | 语法 | 说明 |
|---|---|---|
| 1. 重命名表 | ALTER TABLE 旧表名 RENAME TO 新表名; | 改表名 |
| 2. 重命名列 (v3.25.0+) | ALTER TABLE 表名 RENAME COLUMN 旧列 TO 新列; | 改列名 |
| 3. 添加列 | ALTER TABLE 表名 ADD COLUMN 列定义; | 新增列 |
| 4. 重命名表(带 schema) | ALTER TABLE schema.旧名 RENAME TO 新名; | 跨 schema |
不支持:
DROP COLUMN、MODIFY COLUMN、ALTER COLUMN TYPE
二、详细示例
1. 重命名表
ALTER TABLE users RENAME TO customers;
→ 表名从 users 改为 customers
2. 重命名列(SQLite 3.25.0 及以上)
ALTER TABLE customers RENAME COLUMN email TO email_address;
→ 列 email 改名为 email_address
注意:旧版本不支持!需重建表(见下文)
3. 添加新列
ALTER TABLE customers ADD COLUMN phone TEXT;
-- 带默认值
ALTER TABLE customers ADD COLUMN created_at DATETIME DEFAULT CURRENT_TIMESTAMP;
-- 带 CHECK 约束
ALTER TABLE customers ADD COLUMN age INTEGER CHECK(age >= 18);
新列加在表 最后,不能指定位置
三、【不支持】删除列 / 修改列类型?
SQLite 不允许直接:
ALTER TABLE customers DROP COLUMN phone; -- 不支持!
ALTER TABLE customers MODIFY COLUMN age TEXT; -- 不支持!
正确做法:重建表(三步法)
步骤 1:创建新表(目标结构)
CREATE TABLE customers_new (
id INTEGER PRIMARY KEY,
name TEXT,
email_address TEXT,
created_at DATETIME
-- phone 列被删除了
);
步骤 2:复制数据(转换列)
INSERT INTO customers_new (id, name, email_address, created_at)
SELECT id, name, email AS email_address, created_at
FROM customers;
步骤 3:替换旧表
DROP TABLE customers;
ALTER TABLE customers_new RENAME TO customers;
注意:需重新创建索引、触发器、视图!
四、完整重建表脚本(自动化)
-- 开启外键(安全)
PRAGMA foreign_keys = OFF;
-- 开始事务
BEGIN TRANSACTION;
-- 1. 创建新表
CREATE TABLE customers_bak (
id INTEGER PRIMARY KEY,
name TEXT,
email TEXT NOT NULL,
status TEXT DEFAULT 'active'
);
-- 2. 复制数据
INSERT INTO customers_bak SELECT id, name, email, 'active' FROM customers;
-- 3. 删除旧表
DROP TABLE customers;
-- 4. 改名
ALTER TABLE customers_bak RENAME TO customers;
-- 5. 重建索引(如果有)
CREATE INDEX idx_customers_email ON customers(email);
COMMIT;
PRAGMA foreign_keys = ON;
五、查看当前表结构
-- 查看建表语句
SELECT sql FROM sqlite_master WHERE name = 'customers';
-- 或
PRAGMA table_info(customers);
输出示例:
cid | name | type | notnull | dflt_value | pk
----|---------------|---------|---------|----------------|----
0 | id | INTEGER | 0 | NULL | 1
1 | name | TEXT | 0 | NULL | 0
2 | email_address | TEXT | 0 | NULL | 0
六、版本要求总结
| 功能 | 最低版本 |
|---|---|
RENAME TO | 所有版本 |
ADD COLUMN | 所有版本 |
RENAME COLUMN | 3.25.0+ (2018-09-15) |
DROP COLUMN | 不支持 |
检查版本:
SELECT sqlite_version();
七、最佳实践建议
| 场景 | 推荐做法 |
|---|---|
| 改表名 | 直接 ALTER TABLE ... RENAME TO |
| 改列名 | v3.25+ 用 RENAME COLUMN,否则重建 |
| 加列 | 直接 ADD COLUMN |
| 删列 / 改类型 | 必须重建表 |
| 频繁改结构 | 考虑用 JSON 字段存灵活数据 |
八、工具推荐(图形化)
| 工具 | 支持重建表 |
|---|---|
| DB Browser for SQLite | 一键“修改表” |
| DBeaver | 支持可视化编辑 |
| SQLiteStudio | 强大重建功能 |
总结:ALTER TABLE 能力一览
| 操作 | 是否支持 | 命令 |
|---|---|---|
| 改表名 | ✅ | RENAME TO 新名 |
| 改列名 | ✅ (3.25+) | RENAME COLUMN 旧 TO 新 |
| 加列 | ✅ | ADD COLUMN ... |
| 删列 | ❌ | 需重建表 |
| 改列类型 | ❌ | 需重建表 |
| 改约束 | ❌ | 需重建表 |
需要我帮你生成一个「从旧表 → 新表」的完整迁移脚本?
把你的 旧表结构 + 目标结构 发我!