修改表 #
一、ALTER TABLE概述 #
1.1 可修改内容 #
ALTER TABLE支持以下修改:
| 操作 | 支持 | 说明 |
|---|---|---|
| 添加列 | ✓ | 添加新列 |
| 删除列 | ✓ | 删除现有列 |
| 修改列类型 | ✓ | 仅限兼容类型 |
| 修改表属性 | ✓ | 压缩、缓存等 |
| 修改主键 | ✗ | 不支持 |
| 修改表名 | ✗ | 不支持 |
1.2 基本语法 #
sql
-- 添加列
ALTER TABLE table_name ADD (column_name data_type, ...);
-- 删除列
ALTER TABLE table_name DROP column_name;
-- 修改列类型
ALTER TABLE table_name ALTER column_name TYPE new_data_type;
-- 修改表属性
ALTER TABLE table_name WITH option_name = option_value;
二、添加列 #
2.1 添加单列 #
sql
-- 添加单个列
ALTER TABLE users ADD phone TEXT;
-- 添加多个列
ALTER TABLE users ADD (
phone TEXT,
address TEXT,
city TEXT
);
2.2 添加集合类型列 #
sql
-- 添加List列
ALTER TABLE users ADD tags LIST<TEXT>;
-- 添加Set列
ALTER TABLE users ADD email_list SET<TEXT>;
-- 添加Map列
ALTER TABLE users ADD preferences MAP<TEXT, TEXT>;
2.3 添加UDT列 #
sql
-- 先创建UDT
CREATE TYPE address (
street TEXT,
city TEXT,
state TEXT,
zip_code TEXT
);
-- 添加UDT列
ALTER TABLE users ADD home_address FROZEN<address>;
2.4 添加列注意事项 #
text
添加列注意事项:
✓ 可以添加任意数量的列
✓ 新列默认值为NULL
✓ 不影响现有数据
✓ 添加后立即可用
✗ 不能添加主键列
✗ 不能添加与现有列同名的列
三、删除列 #
3.1 删除单列 #
sql
-- 删除单个列
ALTER TABLE users DROP phone;
-- 删除多个列(需要分别执行)
ALTER TABLE users DROP address;
ALTER TABLE users DROP city;
3.2 删除集合列 #
sql
-- 删除List列
ALTER TABLE users DROP tags;
-- 删除Set列
ALTER TABLE users DROP email_list;
-- 删除Map列
ALTER TABLE users DROP preferences;
3.3 删除列注意事项 #
text
删除列注意事项:
✓ 删除后数据不可恢复(除非从备份恢复)
✓ 删除操作创建墓碑(tombstone)
✓ 墓碑在gc_grace_seconds后清除
⚠ 删除后重新添加同名列可能恢复旧数据
⚠ 大量删除可能影响性能
3.4 删除列与墓碑 #
text
删除列的影响:
删除前:
┌─────────────────────────────────────────┐
│ user_id │ name │ phone │ email │
├─────────────────────────────────────────┤
│ 001 │ 张三 │ 138xxxx │ z@ex.com│
└─────────────────────────────────────────┘
删除phone列:
ALTER TABLE users DROP phone;
删除后(创建墓碑):
┌─────────────────────────────────────────┐
│ user_id │ name │ [phone墓碑]│ email │
├─────────────────────────────────────────┤
│ 001 │ 张三 │ <deleted> │ z@ex.com│
└─────────────────────────────────────────┘
gc_grace_seconds后:
┌─────────────────────────────────────────┐
│ user_id │ name │ │ email │
├─────────────────────────────────────────┤
│ 001 │ 张三 │ │ z@ex.com│
└─────────────────────────────────────────┘
四、修改列类型 #
4.1 兼容类型转换 #
sql
-- INT → BIGINT
ALTER TABLE users ALTER age TYPE BIGINT;
-- TEXT → VARCHAR(相同类型)
ALTER TABLE users ALTER name TYPE VARCHAR;
-- FLOAT → DOUBLE
ALTER TABLE products ALTER price TYPE DOUBLE;
4.2 兼容类型列表 #
text
允许的类型转换:
数值类型
├── TINYINT → SMALLINT → INT → BIGINT → VARINT
├── FLOAT → DOUBLE
└── 以上类型 → DECIMAL
文本类型
├── TEXT ↔ VARCHAR
└── ASCII → TEXT
时间类型
└── 各种时间类型之间有限转换
4.3 不兼容类型转换 #
sql
-- 不兼容的类型转换会失败
ALTER TABLE users ALTER age TYPE TEXT;
-- 错误:Cannot convert type int to text
-- 解决方案:
-- 1. 创建新列
ALTER TABLE users ADD age_text TEXT;
-- 2. 迁移数据
-- 3. 删除旧列
五、修改表属性 #
5.1 修改压缩策略 #
sql
-- 修改压缩策略
ALTER TABLE users
WITH compaction = {
'class': 'LeveledCompactionStrategy',
'sstable_size_in_mb': 160
};
-- 修改压缩算法
ALTER TABLE users
WITH compression = {
'sstable_compression': 'LZ4Compressor'
};
-- 禁用压缩
ALTER TABLE users
WITH compression = {
'sstable_compression': ''
};
5.2 修改缓存配置 #
sql
-- 修改缓存配置
ALTER TABLE users
WITH caching = {
'keys': 'ALL',
'rows_per_partition': '100'
};
5.3 修改其他属性 #
sql
-- 修改注释
ALTER TABLE users WITH comment = '更新后的用户表';
-- 修改gc_grace_seconds
ALTER TABLE users WITH gc_grace_seconds = 172800;
-- 修改默认TTL
ALTER TABLE users WITH default_time_to_live = 86400;
-- 修改多个属性
ALTER TABLE users
WITH comment = '用户表'
AND gc_grace_seconds = 172800
AND caching = {'keys': 'ALL', 'rows_per_partition': '50'};
5.4 修改压缩策略的影响 #
text
修改压缩策略的影响:
SizeTiered → Leveled
├── 后台逐步转换
├── 短期增加IO
└── 最终更高效的读取
Leveled → SizeTiered
├── 后台逐步转换
├── 可能增加空间使用
└── 适合写入密集场景
六、重命名列 #
6.1 重命名语法 #
sql
-- 重命名列
ALTER TABLE users RENAME old_name TO new_name;
-- 重命名多个列
ALTER TABLE users
RENAME old_col1 TO new_col1
AND old_col2 TO new_col2;
6.2 重命名限制 #
text
重命名限制:
✓ 仅支持主键列重命名
✓ 重命名不影响数据
✓ 重命名后查询需要使用新名称
✗ 不能重命名普通列
✗ 不能改变列的顺序
6.3 重命名示例 #
sql
-- 重命名主键列
ALTER TABLE orders
RENAME order_id TO order_uuid;
-- 重命名复合主键列
ALTER TABLE events
RENAME device_id TO sensor_id
AND event_time TO timestamp;
七、验证修改 #
7.1 查看表结构 #
sql
-- 查看修改后的表结构
DESCRIBE TABLE users;
-- 查看列信息
SELECT column_name, type, kind
FROM system_schema.columns
WHERE keyspace_name = 'my_app' AND table_name = 'users';
7.2 查看表属性 #
sql
-- 查看表属性
SELECT * FROM system_schema.tables
WHERE keyspace_name = 'my_app' AND table_name = 'users';
八、最佳实践 #
8.1 修改时机 #
text
最佳修改时机:
推荐
├── 业务低峰期
├── 有充足监控
└── 已备份数据
避免
├── 业务高峰期
├── 大型活动期间
└── 无备份状态
8.2 修改建议 #
text
修改建议:
添加列
├── 可以随时添加
├── 不影响现有数据
└── 无性能影响
删除列
├── 谨慎操作
├── 考虑数据备份
└── 注意墓碑影响
修改类型
├── 确保类型兼容
├── 测试环境验证
└── 准备回滚方案
修改属性
├── 了解影响范围
├── 监控修改效果
└── 必要时回滚
九、常见问题 #
9.1 添加列失败 #
sql
-- 问题:列已存在
ALTER TABLE users ADD name TEXT;
-- 错误:Invalid column name name because it conflicts with an existing column
-- 解决:检查列是否存在
DESCRIBE TABLE users;
9.2 类型转换失败 #
sql
-- 问题:类型不兼容
ALTER TABLE users ALTER age TYPE TEXT;
-- 错误:Cannot alter column "age" type: it cannot be converted from int to text
-- 解决:创建新列迁移数据
ALTER TABLE users ADD age_text TEXT;
9.3 删除列后恢复 #
sql
-- 问题:误删列后想恢复
ALTER TABLE users DROP phone;
-- 解决方案1:从备份恢复
nodetool refresh my_app users
-- 解决方案2:重新添加列(可能恢复旧数据)
ALTER TABLE users ADD phone TEXT;
-- 注意:可能恢复旧数据,但不保证
十、总结 #
修改表要点:
- 添加列:随时可添加,不影响现有数据
- 删除列:谨慎操作,创建墓碑
- 修改类型:仅限兼容类型
- 修改属性:压缩、缓存等可随时修改
- 重命名列:仅支持主键列
- 低峰期操作:减少对业务影响
下一步,让我们学习删除表!
最后更新:2026-03-27