本阶段介绍 StarRocks 在运维和复杂场景下的高级功能。
1. Schema Change
- 文件 :
01_schema_change.sql - StarRocks 支持Light Schema Change,加减列、修改列类型等操作非常快,通常不需要重写数据文件。
2. Colocate Join
- 文件 :
02_colocate_join.sql - 解决大表 Join 大表的性能瓶颈。
- 原理:将 Join Key 相同的表分片(Tablet)放置在同一个 BE 节点上,避免网络 Shuffle。
3. JSON 半结构化分析
- 文件 :
03_json_analysis.sql - StarRocks 使用优化的二进制 JSON 格式存储。
- 相比将 JSON 存为 String,原生 JSON 类型的解析和查询速度有数量级的提升。
- 支持
->操作符和丰富的 JSON 函数 (get_json_string,json_query等)。
sql
-- Phase 5: 高级特性
-- 01_schema_change.sql
-- 表结构变更 (Schema Change)
USE learn_starrocks;
-- 创建一个初始表
CREATE TABLE IF NOT EXISTS schema_demo (
id INT,
v1 INT
)
ENGINE=OLAP
DUPLICATE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 3
PROPERTIES ("replication_num" = "1");
INSERT INTO schema_demo VALUES (1, 10), (2, 20);
-- 1. 加列 (Add Column)
-- StarRocks 支持 Light Schema Change,加列操作通常是秒级的(只修改元数据)
ALTER TABLE schema_demo ADD COLUMN v2 INT DEFAULT "0" AFTER v1;
-- 2. 修改列类型 (Modify Column)
ALTER TABLE schema_demo MODIFY COLUMN v2 BIGINT;
-- 3. 删除列 (Drop Column)
ALTER TABLE schema_demo DROP COLUMN v1;
-- 4. 建立 rollup (本质上也是一种 Schema Change)
-- ALTER TABLE schema_demo ADD ROLLUP ...
-- 查看 Schema Change 进度
SHOW ALTER TABLE COLUMN;
SELECT * FROM schema_demo;
sql
-- Phase 5: 高级特性
-- 02_colocate_join.sql
-- Colocate Join 优化
USE learn_starrocks;
-- 场景:表A 和 表B 经常需要根据 user_id 进行 Join。
-- 如果这两个表的数据分布不一致,Join 时需要进行 Shuffle (网络传输),开销大。
-- Colocate Join 强制让两个表拥有相同的分桶策略和副本分布,使 Join 在本地完成。
-- 1. 创建 Group (可选,也可以隐式创建)
-- 只要两个表的 `DISTRIBUTED BY HASH` 列和桶数一致,且指定相同的 `colocate_with` 组名即可。
-- 表 A
CREATE TABLE IF NOT EXISTS tbl_user (
user_id INT,
username VARCHAR(20)
)
ENGINE=OLAP
DUPLICATE KEY(user_id)
DISTRIBUTED BY HASH(user_id) BUCKETS 3
PROPERTIES (
"replication_num" = "1",
"colocate_with" = "group_user_data" -- 指定组名
);
-- 表 B
CREATE TABLE IF NOT EXISTS tbl_order (
order_id BIGINT,
user_id INT, -- Join Key
amount DECIMAL
)
ENGINE=OLAP
DUPLICATE KEY(order_id)
DISTRIBUTED BY HASH(user_id) BUCKETS 3 -- 必须与 tbl_user 的分桶列和数量一致
PROPERTIES (
"replication_num" = "1",
"colocate_with" = "group_user_data" -- 同一个组
);
-- 验证
INSERT INTO tbl_user VALUES (1, 'Alice'), (2, 'Bob');
INSERT INTO tbl_order VALUES (101, 1, 99.0), (102, 2, 199.0);
-- 执行 Join
-- EXPLAIN 中应该看不到 `EXCHANGE` 节点(或者 Cost 很低),说明是本地 Join
EXPLAIN SELECT * FROM tbl_user u JOIN tbl_order o ON u.user_id = o.user_id;
sql
-- Phase 5: 高级特性
-- 02_colocate_join.sql
-- Colocate Join 优化
USE learn_starrocks;
-- 场景:表A 和 表B 经常需要根据 user_id 进行 Join。
-- 如果这两个表的数据分布不一致,Join 时需要进行 Shuffle (网络传输),开销大。
-- Colocate Join 强制让两个表拥有相同的分桶策略和副本分布,使 Join 在本地完成。
-- 1. 创建 Group (可选,也可以隐式创建)
-- 只要两个表的 `DISTRIBUTED BY HASH` 列和桶数一致,且指定相同的 `colocate_with` 组名即可。
-- 表 A
CREATE TABLE IF NOT EXISTS tbl_user (
user_id INT,
username VARCHAR(20)
)
ENGINE=OLAP
DUPLICATE KEY(user_id)
DISTRIBUTED BY HASH(user_id) BUCKETS 3
PROPERTIES (
"replication_num" = "1",
"colocate_with" = "group_user_data" -- 指定组名
);
-- 表 B
CREATE TABLE IF NOT EXISTS tbl_order (
order_id BIGINT,
user_id INT, -- Join Key
amount DECIMAL
)
ENGINE=OLAP
DUPLICATE KEY(order_id)
DISTRIBUTED BY HASH(user_id) BUCKETS 3 -- 必须与 tbl_user 的分桶列和数量一致
PROPERTIES (
"replication_num" = "1",
"colocate_with" = "group_user_data" -- 同一个组
);
-- 验证
INSERT INTO tbl_user VALUES (1, 'Alice'), (2, 'Bob');
INSERT INTO tbl_order VALUES (101, 1, 99.0), (102, 2, 199.0);
-- 执行 Join
-- EXPLAIN 中应该看不到 `EXCHANGE` 节点(或者 Cost 很低),说明是本地 Join
EXPLAIN SELECT * FROM tbl_user u JOIN tbl_order o ON u.user_id = o.user_id;
sql
-- Phase 5: 高级特性
-- 03_json_analysis.sql
-- 半结构化数据 (JSON) 分析
USE learn_starrocks;
-- StarRocks 提供了原生的 JSON 类型,存储为二进制格式,查询极快。
-- 适用于日志分析、用户画像等 Schema 不固定的场景。
CREATE TABLE IF NOT EXISTS json_logs (
id BIGINT,
ts DATETIME,
payload JSON -- JSON 类型
)
ENGINE=OLAP
DUPLICATE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 3
PROPERTIES ("replication_num" = "1");
-- 插入 JSON 数据
INSERT INTO json_logs VALUES
(1, NOW(), parse_json('{"city": "Beijing", "score": 90, "tags": ["A", "B"]}')),
(2, NOW(), parse_json('{"city": "Shanghai", "score": 85, "tags": ["C"]}')),
(3, NOW(), parse_json('{"city": "Beijing", "extra": {"k": "v"}}'));
-- 查询 JSON 字段
-- 1. 使用 -> 访问属性
SELECT
id,
payload->'city' AS city,
payload->'score' AS score
FROM json_logs;
-- 2. 过滤
-- 需先转为特定类型再比较,或者直接比较
SELECT * FROM json_logs
WHERE cast(payload->'score' as INT) > 80;
-- 3. 提取数组
SELECT payload->'tags' FROM json_logs;