创建表 #

一、表概述 #

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推荐
压实 根据场景选择

最佳实践:

  1. 基于查询模式设计主键
  2. 选择高基数分区键
  3. 合理配置表选项
  4. 使用有意义的表名
  5. 添加表注释

下一步,让我们学习修改表!

最后更新:2026-03-27