创建表 #
一、表概述 #
1.1 什么是表 #
表(Table)是ScyllaDB中存储数据的基本单位,由行和列组成。
text
表结构:
┌─────────────────────────────────────────────────────────┐
│ │
│ Table: users │
│ ┌─────────────┬──────────┬───────────┬──────────────┐ │
│ │ user_id (PK)│ name │ email │ created_at │ │
│ ├─────────────┼──────────┼───────────┼──────────────┤ │
│ │ uuid-1 │ 张三 │ a@ex.com │ 2024-01-15 │ │
│ │ uuid-2 │ 李四 │ b@ex.com │ 2024-01-16 │ │
│ │ uuid-3 │ 王五 │ c@ex.com │ 2024-01-17 │ │
│ └─────────────┴──────────┴───────────┴──────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
1.2 表的特点 #
| 特点 | 说明 |
|---|---|
| 灵活Schema | 可以动态添加列 |
| 分布式存储 | 数据分布在多个节点 |
| 主键驱动 | 查询必须包含分区键 |
| 高性能 | 针对读写优化 |
二、基本语法 #
2.1 CREATE TABLE语法 #
sql
CREATE TABLE [IF NOT EXISTS] [keyspace_name.]table_name (
column_name data_type [PRIMARY KEY],
column_name data_type,
...
[, PRIMARY KEY (partition_key_column, clustering_column...)]
)
[WITH table_options];
2.2 简单示例 #
sql
-- 创建简单表
CREATE TABLE users (
user_id UUID PRIMARY KEY,
name TEXT,
email TEXT,
created_at TIMESTAMP
);
-- 使用IF NOT EXISTS
CREATE TABLE IF NOT EXISTS users (
user_id UUID PRIMARY KEY,
name TEXT,
email TEXT
);
三、主键设计 #
3.1 简单主键 #
sql
-- 单列主键
CREATE TABLE users (
user_id UUID PRIMARY KEY,
name TEXT,
email TEXT
);
-- 等价于
CREATE TABLE users (
user_id UUID,
name TEXT,
email TEXT,
PRIMARY KEY (user_id)
);
3.2 复合主键 #
sql
-- 分区键 + 聚簇列
CREATE TABLE orders (
user_id UUID,
order_id UUID,
order_date TIMESTAMP,
amount DECIMAL,
PRIMARY KEY (user_id, order_id)
);
-- 分区键决定数据分布
-- 聚簇列决定分区内排序
3.3 复合分区键 #
sql
-- 多列组成分区键
CREATE TABLE events (
event_type TEXT,
event_date DATE,
event_id TIMEUUID,
event_data TEXT,
PRIMARY KEY ((event_type, event_date), event_id)
);
-- 分区键: (event_type, event_date)
-- 聚簇列: event_id
3.4 主键设计原则 #
text
主键设计原则:
┌─────────────────────────────────────────────────────────┐
│ │
│ 分区键选择: │
│ ├── 高基数(值多样性高) │
│ ├── 匹配查询模式 │
│ ├── 数据均匀分布 │
│ └── 避免热点 │
│ │
│ 聚簇列选择: │
│ ├── 支持范围查询 │
│ ├── 决定排序顺序 │
│ └── 控制分区大小 │
│ │
└─────────────────────────────────────────────────────────┘
四、聚簇排序 #
4.1 CLUSTERING ORDER BY #
sql
-- 默认升序(ASC)
CREATE TABLE events_asc (
device_id TEXT,
event_time TIMESTAMP,
event_data TEXT,
PRIMARY KEY (device_id, event_time)
);
-- 降序(DESC)- 常用于时间序列
CREATE TABLE events_desc (
device_id TEXT,
event_time TIMESTAMP,
event_data TEXT,
PRIMARY KEY (device_id, event_time)
) WITH CLUSTERING ORDER BY (event_time DESC);
-- 多列排序
CREATE TABLE events_multi (
device_id TEXT,
event_date DATE,
event_time TIMESTAMP,
event_data TEXT,
PRIMARY KEY (device_id, event_date, event_time)
) WITH CLUSTERING ORDER BY (event_date ASC, event_time DESC);
4.2 排序影响查询 #
sql
-- 创建降序表
CREATE TABLE time_series (
device_id TEXT,
timestamp TIMESTAMP,
value DOUBLE,
PRIMARY KEY (device_id, timestamp)
) WITH CLUSTERING ORDER BY (timestamp DESC);
-- 查询最新数据(高效)
SELECT * FROM time_series
WHERE device_id = 'device1'
LIMIT 10; -- 直接返回最新10条
-- 查询最早数据(需要全扫描)
SELECT * FROM time_series
WHERE device_id = 'device1'
ORDER BY timestamp ASC
LIMIT 10;
五、表选项配置 #
5.1 常用表选项 #
sql
CREATE TABLE users (
user_id UUID PRIMARY KEY,
name TEXT,
email TEXT
) WITH
comment = '用户表'
AND gc_grace_seconds = 864000
AND default_time_to_live = 0
AND bloom_filter_fp_chance = 0.01;
5.2 压缩选项 #
sql
CREATE TABLE compressed_data (
id INT PRIMARY KEY,
data TEXT
) WITH compression = {
'sstable_compression': 'LZ4Compressor',
'chunk_length_kb': 64
};
-- 压缩算法选择
-- LZ4Compressor: 快速压缩,推荐
-- SnappyCompressor: 平衡压缩
-- ZstdCompressor: 高压缩比
-- DeflateCompressor: 最高压缩比,最慢
5.3 压实选项 #
sql
-- SizeTieredCompactionStrategy (默认)
CREATE TABLE stcs_table (
id INT PRIMARY KEY,
data TEXT
) WITH compaction = {
'class': 'SizeTieredCompactionStrategy',
'min_threshold': 4,
'max_threshold': 32
};
-- LeveledCompactionStrategy (适合读多写少)
CREATE TABLE lcs_table (
id INT PRIMARY KEY,
data TEXT
) WITH compaction = {
'class': 'LeveledCompactionStrategy',
'sstable_size_in_mb': 160
};
-- TimeWindowCompactionStrategy (适合时间序列)
CREATE TABLE twcs_table (
device_id TEXT,
timestamp TIMESTAMP,
value DOUBLE,
PRIMARY KEY (device_id, timestamp)
) WITH compaction = {
'class': 'TimeWindowCompactionStrategy',
'compaction_window_unit': 'HOURS',
'compaction_window_size': 1
};
5.4 缓存选项 #
sql
CREATE TABLE cached_table (
id INT PRIMARY KEY,
data TEXT
) WITH caching = {
'keys': 'ALL',
'rows_per_partition': '100'
};
-- keys: ALL | NONE
-- rows_per_partition: ALL | NONE | 数字
六、完整创建示例 #
6.1 用户表 #
sql
CREATE TABLE users (
user_id UUID,
username TEXT,
email TEXT,
password_hash TEXT,
created_at TIMESTAMP,
updated_at TIMESTAMP,
status TEXT,
PRIMARY KEY (user_id)
) WITH
comment = '用户信息表'
AND compression = {'sstable_compression': 'LZ4Compressor'}
AND gc_grace_seconds = 864000
AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'};
6.2 订单表 #
sql
CREATE TABLE orders (
user_id UUID,
order_id TIMEUUID,
order_date DATE,
status TEXT,
total_amount DECIMAL,
shipping_address FROZEN<address>,
items LIST<FROZEN<order_item>>,
created_at TIMESTAMP,
PRIMARY KEY (user_id, order_id)
) WITH CLUSTERING ORDER BY (order_id DESC)
AND comment = '订单表'
AND compression = {'sstable_compression': 'LZ4Compressor'}
AND default_time_to_live = 0;
6.3 时间序列表 #
sql
CREATE TABLE sensor_data (
device_id TEXT,
date DATE,
timestamp TIMESTAMP,
temperature DOUBLE,
humidity DOUBLE,
pressure DOUBLE,
PRIMARY KEY ((device_id, date), timestamp)
) WITH CLUSTERING ORDER BY (timestamp DESC)
AND comment = '传感器数据表'
AND compaction = {
'class': 'TimeWindowCompactionStrategy',
'compaction_window_unit': 'HOURS',
'compaction_window_size': 24
}
AND default_time_to_live = 2592000; -- 30天TTL
6.4 日志表 #
sql
CREATE TABLE application_logs (
app_name TEXT,
log_date DATE,
log_time TIMEUUID,
level TEXT,
message TEXT,
metadata MAP<TEXT, TEXT>,
PRIMARY KEY ((app_name, log_date), log_time)
) WITH CLUSTERING ORDER BY (log_time DESC)
AND comment = '应用日志表'
AND compaction = {
'class': 'TimeWindowCompactionStrategy',
'compaction_window_unit': 'HOURS',
'compaction_window_size': 1
}
AND default_time_to_live = 604800; -- 7天TTL
七、查看表信息 #
7.1 查看表结构 #
sql
-- 查看表定义
DESCRIBE TABLE users;
-- 查看详细定义
DESCRIBE FULL TABLE users;
7.2 查询系统表 #
sql
-- 查看所有表
SELECT table_name
FROM system_schema.tables
WHERE keyspace_name = 'my_keyspace';
-- 查看表列
SELECT column_name, type, kind
FROM system_schema.columns
WHERE keyspace_name = 'my_keyspace'
AND table_name = 'users';
-- 查看表选项
SELECT *
FROM system_schema.tables
WHERE keyspace_name = 'my_keyspace'
AND table_name = 'users';
八、表命名规范 #
8.1 命名规则 #
text
命名规则:
├── 只包含字母、数字、下划线
├── 以字母开头
├── 不区分大小写(默认)
├── 最大长度48字符
└── 避免使用保留字
8.2 命名示例 #
sql
-- 好的命名
CREATE TABLE users ...
CREATE TABLE user_profiles ...
CREATE TABLE order_items ...
-- 不好的命名
CREATE TABLE 123table ... -- 数字开头
CREATE TABLE my-table ... -- 包含连字符
CREATE TABLE "Users" ... -- 区分大小写
九、常见错误处理 #
9.1 表已存在 #
sql
-- 错误
CREATE TABLE users ...;
-- Error: Table 'users' already exists
-- 解决
CREATE TABLE IF NOT EXISTS users ...;
9.2 主键重复定义 #
sql
-- 错误
CREATE TABLE bad_table (
id UUID PRIMARY KEY,
name TEXT,
PRIMARY KEY (id)
);
-- Error: Duplicate PRIMARY KEY definition
-- 解决
CREATE TABLE good_table (
id UUID,
name TEXT,
PRIMARY KEY (id)
);
9.3 无效的数据类型 #
sql
-- 错误
CREATE TABLE bad_types (
id INT PRIMARY KEY,
data INVALID_TYPE
);
-- Error: Unknown type
-- 解决:使用有效类型
CREATE TABLE good_types (
id INT PRIMARY KEY,
data TEXT
);
十、最佳实践 #
10.1 设计检查清单 #
text
设计检查清单:
├── [ ] 主键是否匹配查询模式?
├── [ ] 分区键是否高基数?
├── [ ] 是否避免了热点分区?
├── [ ] 分区大小是否合理?
├── [ ] 聚簇排序是否正确?
├── [ ] 压缩策略是否合适?
├── [ ] TTL设置是否合理?
└── [ ] 表名是否有意义?
10.2 表选项建议 #
| 选项 | 建议 |
|---|---|
| compression | LZ4Compressor |
| gc_grace_seconds | 864000 (10天) |
| default_time_to_live | 根据业务需求 |
| compaction | 根据数据类型选择 |
十一、总结 #
创建表要点:
| 要点 | 说明 |
|---|---|
| 主键设计 | 匹配查询模式 |
| 聚簇排序 | 支持范围查询 |
| 压缩 | LZ4推荐 |
| 压实 | 根据场景选择 |
最佳实践:
- 基于查询模式设计主键
- 选择高基数分区键
- 合理配置表选项
- 使用有意义的表名
- 添加表注释
下一步,让我们学习修改表!
最后更新:2026-03-27