StarRocks模型表(一)

主键表

  • 优势:支撑实时数据更新的同时,也能保证高效的复杂即席查询性能
  • 主键表中的主键具有唯一非空约束,用于唯一标识数据行,如果新数据的主键值与表中原数据的主键值相同,则存在唯一约束冲突,此时新数据会替代原数据

应用场景

  • 实时对接事务型数据至StarRocks。事务型数据库中,除了插入数据外,一般还会涉及较多更新和删除数据的操作,因此事务型数据库的数据同步至StarRocks时,建议使用主键表
  • 利用部分列更新轻松实现多流JOIN。在用户画像等分析场景中,一般会采用大宽表方式来提升多维分析的性能,同时简化数据分析师的使用模型。而这种场景中的上游数据,往往可能来自于多个不同业务或系统,主键表的部分列更新功能就很好地满足这种需求,不同业务直接各自按需更新与业务相关的列即可

工作原理

  • 主键表采用了Delete+Insert策略,借助主键索引配合DelVector的方式实现,保证在查询时只需要读取具有相同主键值的数据中的最新数据,StarRocks会加载导入数据对应Tablet的主键索引至内存中

数据写入

  • 数据写入是通过StarRocks内部的Loadjob实现,包含一批数据变更操作(包括Insert、Update、Delete),并且会更新主键索引中变更的数据行现在所在的数据文件和行号

Delete操作:通过主键索引找到数据行原来所在的数据文件以及行号,在DelVector(用于存储和管理数据导入时生成数据行对应的删除标记)中把该条数据标记为删除
Update操作:除了在DelVector中将原先数据行标记为删除,还会把最新数据写入新的数据文件,相当于把Update改写为Delete+Insert

数据读取

  • 由于写入数据时各个数据文件中历史重复数据已经标记为删除,同一个主键值下仅需要读取最新的一条数据,无需在线Merge多个版本的数据文件来去重以找到最新的数据

使用说明

  • 在CREATE TABLE语句通过PRIMARY KEY定义主键,即可创建一个主键表

建表示例

CREATE TABLE orders1 (
    order_id bigint NOT NULL,
    dt date NOT NULL,
    user_id INT NOT NULL,
    good_id INT NOT NULL,
    cnt int NOT NULL,
    revenue int NOT NULL
)
PRIMARY KEY (order_id)
DISTRIBUTED BY HASH (order_id)
;
  • 假设经常根据订单日期和商户组合维度查询商品销售情况,可以通过ORDER BY(dt,merchant_id)指定排序键为dt和merchant_id
  • 如果使用了数据分布策略,由于目前主键表要求主键必须包括分区列和分桶列,假设采用的数据分布策略是将dt作为分区列并且merchant_id作为哈希分桶列,则主键还需要包括dt和merchant_id
CREATE TABLE orders2 (
    order_id bigint NOT NULL,
    dt date NOT NULL,
    merchant_id int NOT NULL,
    user_id int NOT NULL,
    good_id int NOT NULL,
    good_name string NOT NULL,
    price int NOT NULL,
    cnt int NOT NULL,
    revenue int NOT NULL,
    state tinyint NOT NULL
)
PRIMARY KEY (order_id,dt,merchant_id)
PARTITION BY date_trunc('day', dt)
DISTRIBUTED BY HASH (merchant_id)
ORDER BY (dt,merchant_id)
PROPERTIES (
    "enable_persistent_index" = "true"
);

主键

  • 主键用于唯一标识表中的每一行数据,组成主键的一个或多个列在PRIMARY KEY中定义,具有非空唯一性约束
1、在建表语句中,主键列必须定义在其他列之前
2、主键必须包含分区列和分桶列
3、主键列支持以下数据类型:数值(包括整型和布尔)、日期和字符串
4、默认设置下,单条主键值编码后的最大长度为128字节
5、建表后不支持修改主键
6、主键列的值不能更新,避免破坏数据一致性

主键索引

  • 保存主键值和其标识的数据行所在位置的映射
  • 通常只有在导入数据(包含一批数据变更)的时候会将导入数据相关Tablet的主键索引加载至内存
  • enable_persistent_index:设置为true(默认),表示持久化主键索引,通常情况下,持久化主键索引后,查询和更新性能几乎接近全内存索引
  • StarRocks存算分离集群支持基于本地磁盘上的持久化索引,可以通过将主键表persistent_index_type设置为CLOUD_NATIVE启用该功能

排序键

  • 排序键由ORDER BY定义的排序列组成,可以为任意列的排列组合,只要列的数据类型满足排序键的要求
  • 排序键还用于构建前缀索引,能够加速查询
  • 建表后支持通过ALTER TABLE ... ORDER BY ...修改排序键,不支持删除排序键,不支持修改排序列的数据类型

明细表

  • 明细表是默认创建的表类型,如果在建表时未指定任何key,默认创建的是明细表
  • 建表时支持定义排序键,如果查询的过滤条件包含排序键,则StarRocks能够快速地过滤数据,提高查询效率
  • 支持追加新数据,不支持修改历史数据

适用场景

  • 分析原始数据,例如原始日志、原始操作记录等
  • 查询方式灵活,不需要局限于预聚合的分析方式
  • 导入日志数据或者时序数据,主要特点是旧数据不会更新,只会追加新的数据

创建表

  • 分析某时间范围的某一类事件的数据,则可以将事件时间(event_time)和事件类型(event_type)作为排序键
CREATE TABLE detail (
    event_time DATETIME NOT NULL COMMENT "datetime of event",
    event_type INT NOT NULL COMMENT "type of event",
    user_id INT COMMENT "id of user",
    device_code INT COMMENT "device code",
    channel INT COMMENT "")
ORDER BY (event_time, event_type);
  • 如果同时使用ORDER BY和DUPLICATE KEY,则DUPLICATE KEY无效,如果未使用ORDER BY和DUPLICATE KEY,则默认选择表的前三列作为排序键
  • 如果导入两行完全相同的数据,则明细表会将这两行数据视为两行,而不是一行
posted @   一年都在冬眠  阅读(231)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示