StarRocks 的核心在于选择正确的表模型。不同的模型决定了数据在存储引擎中的组织方式,直接影响查询性能和数据导入行为。
三种核心模型
1. 明细模型 (Duplicate Key)
- 文件 :
01_duplicate_key.sql - 特点: 数据不聚合,不去重,按 Key 排序。
- 适用: 原始日志、流水账单。
- 关键字 :
DUPLICATE KEY
2. 聚合模型 (Aggregate Key)
- 文件 :
02_aggregate_key.sql - 特点: 导入时自动聚合相同 Key 的数据。
- 适用: 报表统计、指标汇总 (Sum/Max/Min/BitmapUnion)。
- 关键字 :
AGGREGATE KEY
3. 主键模型 (Primary Key)
- 文件 :
03_primary_key.sql - 特点: 保证主键唯一,支持高性能的实时更新和删除。
- 适用: 类似于 MySQL 的事务表,订单状态变更、用户资料更新。
- 关键字 :
PRIMARY KEY - 注意: 这是 StarRocks 相比其他 OLAP 引擎的一大优势(Merge-on-Write 机制)。
1、Duplicate Key
sql
-- Phase 2: 表模型详解
-- 01_duplicate_key.sql
-- 明细模型 (Duplicate Key Model)
USE learn_starrocks;
-- 场景:
-- 适用于只追加数据,不需要预聚合,也不需要主键去重的场景。
-- 例如:原始日志存储、埋点数据、订单明细流水。
CREATE TABLE IF NOT EXISTS access_log (
event_time DATETIME NOT NULL COMMENT "事件时间",
event_type VARCHAR(50) NOT NULL COMMENT "事件类型",
user_id INT COMMENT "用户ID",
device_id VARCHAR(100) COMMENT "设备ID",
ip VARCHAR(20) COMMENT "IP地址"
)
ENGINE=OLAP
DUPLICATE KEY(event_time, event_type) -- 指定排序键 (Sort Key)
-- 注意:排序键的选择对查询性能影响很大。将查询中最常用于过滤的列放在前面。
DISTRIBUTED BY HASH(user_id) BUCKETS 3
PROPERTIES (
"replication_num" = "1"
);
-- 插入重复数据
INSERT INTO access_log VALUES
('2023-10-01 10:00:00', 'login', 1001, 'dev_001', '192.168.1.1'),
('2023-10-01 10:00:00', 'login', 1001, 'dev_001', '192.168.1.1');
-- 查询结果:你会看到两条完全一样的数据
SELECT * FROM access_log;
2、AGGREGATE KEY
sql
-- Phase 2: 表模型详解
-- 02_aggregate_key.sql
-- 聚合模型 (Aggregate Key Model)
USE learn_starrocks;
-- 场景:
-- 适用于数据导入时自动进行预聚合的场景。
-- 键列 (Key) 相同的数据,会根据指标列 (Value) 定义的聚合函数进行合并。
-- 优点:减少存储空间,加速聚合查询。
-- 缺点:无法查询到明细数据,只能查到聚合后的结果。
CREATE TABLE IF NOT EXISTS site_visit_stats (
site_id INT NOT NULL COMMENT "站点ID",
visit_date DATE NOT NULL COMMENT "访问日期",
city VARCHAR(20) NOT NULL COMMENT "城市",
-- 指标列,必须指定聚合函数
pv BIGINT SUM DEFAULT "0" COMMENT "页面浏览量 (Sum)",
uv BIGINT SUM DEFAULT "0" COMMENT "独立访客数 (Sum)",
last_visit_time DATETIME MAX DEFAULT "1970-01-01 00:00:00" COMMENT "最后访问时间 (Max)"
)
ENGINE=OLAP
AGGREGATE KEY(site_id, visit_date, city) -- 这里的列是 Key (维度),其他列是 Value (指标)
DISTRIBUTED BY HASH(site_id) BUCKETS 3
PROPERTIES (
"replication_num" = "1"
);
-- 模拟数据导入
-- 第一批数据
INSERT INTO site_visit_stats VALUES
(1, '2023-10-01', 'Beijing', 10, 5, '2023-10-01 10:00:00');
-- 第二批数据:Key (site_id=1, date='2023-10-01', city='Beijing') 相同
-- PV 会累加 (10+20=30), UV 会累加 (5+10=15), Time 取最大值
INSERT INTO site_visit_stats VALUES
(1, '2023-10-01', 'Beijing', 20, 10, '2023-10-01 12:00:00');
-- 查询结果
-- 应该只有一行数据:PV=30, UV=15, Time='2023-10-01 12:00:00'
SELECT * FROM site_visit_stats;
3、Primary Key
sql
-- Phase 2: 表模型详解
-- 03_primary_key.sql
-- 主键模型 (Primary Key Model)
USE learn_starrocks;
-- 场景:
-- StarRocks 推荐的"去重"模型,替代旧的 Unique Key 模型。
-- 适用于需要实时更新 (Upsert)、部分列更新、删除操作的业务表(如订单状态表、用户画像表)。
-- 特点:基于 Delete+Insert 实现 Merge-on-Write,查询性能极佳(不需要 Merge-on-Read)。
CREATE TABLE IF NOT EXISTS order_state (
order_id BIGINT NOT NULL COMMENT "订单ID",
user_id INT NOT NULL COMMENT "用户ID",
-- 状态列,可以被更新
order_status VARCHAR(20) COMMENT "订单状态",
payment_amt DECIMAL(10, 2) COMMENT "支付金额",
update_time DATETIME COMMENT "更新时间"
)
ENGINE=OLAP
PRIMARY KEY(order_id) -- 指定主键,主键必须唯一且非空
DISTRIBUTED BY HASH(order_id) BUCKETS 3
PROPERTIES (
"replication_num" = "1",
"enable_persistent_index" = "true" -- 开启持久化索引,加速主键查找 (推荐)
);
-- 1. 插入初始数据 (Create)
INSERT INTO order_state VALUES
(1001, 101, 'Pending', 99.00, '2023-10-01 10:00:00');
-- 2. 更新数据 (Update)
-- 主键(1001)已存在,这行数据会覆盖旧数据
INSERT INTO order_state VALUES
(1001, 101, 'Paid', 99.00, '2023-10-01 10:05:00');
-- 3. 查询结果
-- 应该只有一行,Status='Paid'
SELECT * FROM order_state;
-- 4. 演示部分列更新 (Partial Update) - 仅 StarRocks 2.2+ 支持
-- 假设只更新状态,不知道金额
-- 注意:在 SQL 中通常通过 Stream Load 或特定语法实现,INSERT INTO 覆盖必须提供全列
-- 下面是一个逻辑演示,实际部分更新通常用于 Stream Load CSV 导入时指定 columns
-- 或者是 UPDATE 语句(主键模型支持 UPDATE)
UPDATE order_state SET order_status = 'Shipped', update_time = '2023-10-01 12:00:00' WHERE order_id = 1001;
SELECT * FROM order_state;