第2.2章 StarRocks表设计——排序键和数据模型

 该篇文章介绍StarRocks-2.5.4版本的数据模型相关内容,有误请指出~

目录

一、数据模型概述

1.1 四种模型

1.2 排序键

1.2.1 概述

1.2.2 分类

1.2.3 注意事项

二、明细模型

2.1 概述

2.2 适用场景

2.3 建表语句及说明

三、聚合模型

3.1 概述

3.2 适用场景

3.3 聚合原理

3.3 建表语句及说明

四、更新模型

4.1 概述

4.2 适用场景

4.3 更新原理

4.4 建表语句及说明

五、主键模型

5.1 概述

5.2 适用场景

5.3 更新原理

5.4 建表语句及说明

一、数据模型概述

     在 StarRocks中,数据以表(Table)的形式进行逻辑上的描述。 一张表包括行(Row)和列(Column)。Row 即用户的一行数据,Column 用于描述一行数据中不同的字段。

     Column可以分为两大类:Key和Value,从业务角度看,Key 和 Value分别对应维度列和指标列。StarRocks的key列是建表语句中指定的列,建表语句中的关键字 'duplicate key'、'aggregate key'、'unique key'、' primary key' 后面的列就是Key列除了 Key列剩下的就是Value列

1.1 四种模型

  • Duplicate Key Model:明细模型
  • Aggregate Key Model:聚合模型
  • Unique Key Model:更新模型
  • Primary Key Model:主键模型

1.2 排序键

1.2.1 概述

   StarRocks在创建表的时候,可以指定一个列或者多个列(一般来说前三列)作为这个表的排序键(Sort Key),当数据导入时,数据会按照排序键的定义,按照顺序存储在磁盘空间上,当查询根据这些排序字段进行查询时,就能够根据已经排好序的数据,快速定位到你要查询的对应数据集所对应的磁盘地址,在scan阶段就能够大面积减少无关数据,加速查询。

    直观来看,各个模型的排序键就是建表语句中duplicate key、aggregate key、unique key或primary key后面指定的列。但是四种模型的排序键还是有一些区别:

1.2.2 分类

  • 明细模型:明细模型排序键写法比较灵活,可以指定部分的维度列为排序键。可以使用duplicate key()显式定义排序键。如果省略duplicate key(列1,列2……)时,默认选择表的前三列作为排序键。在建表语句中,排序键必须定义在其他列之前。指定排序键的时候,列的顺序要和建表语句中的相同,否则建表语句会报错。
#建表语句:
create table if not exists test1 (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",channel int comment ""
)
duplicate key(event_time, event_type,user_id)
distributed by hash(user_id) buckets 10;#===如果使用duplicate key()显式定义排序键,单从建表不报错的角度,可以有四种组合:
event_time
event_time, event_type
event_time, event_type, user_id
event_time, event_type, user_id, channel#===如果省略duplicate key(列1,列2……),默认选择表的前三列作为排序键。
create table if not exists test1 (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",channel int comment ""
)
distributed by hash(user_id) buckets 10;
#等价于:
create table if not exists test1 (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",channel int comment ""
)
duplicate key(event_time, event_type,user_id)
distributed by hash(user_id) buckets 10;
  • 聚合表:据按照排序键aggregate key聚合后排序,排序键需要满足唯一性约束,并且需要按建表顺序指定所有的维度列。
#建表语句:
create table if not exists test2(site_id largeint not null comment "id of site",date date not null comment "time of event",city_code varchar(20) comment "city_code of user",pv bigint sum default "0" comment "total page views"
)
aggregate key(site_id, date, city_code)
distributed by hash(site_id)
properties (
"replication_num" = "3"
);#排序键必须满足唯一性约束,并且需要按建表顺序指定所有的维度列
#上述的排序键是site_id, date, city_code,指标键是pv #  上述的建表语句可以简写为:
create table if not exists test2(site_id largeint not null comment "id of site",date date not null comment "time of event",city_code varchar(20) comment "city_code of user",pv bigint sum default "0" comment "total page views"
)
distributed by hash(site_id)
properties (
"replication_num" = "3"
);
  • 更新模型: 更新模型的排序键(也称主键)只有一种写法,就是在unique key()的括号中指定,并且排序键需要满足唯一性约束。
#建表语句:
create table if not exists test3(create_time date not null comment "create time of an order",order_id bigint not null comment "id of an order",order_state int comment "state of an order",total_price bigint comment "price of an order"
)
unique key(create_time, order_id)
distributed by hash(order_id) buckets 8
properties (
"replication_num" = "3"
); #上述代码,排序键是create_time, order_id
将经常使用的过滤字段订单创建时间create_time、订单编号order_id 作为主键(也是排序键),其余列订单状态 order_state和订单总价total_price作为指标列

更新模型和主键模型的排序键只有一种写法,就是在UNIQUE KEY()的括号中指定。以table04为例,建表时排序键语句为UNIQUE KEY(create_time, order_id),则用于排序的列就是create_time和order_id。更新模型/主键模型的排序键必需显式指定,不能省略不写。

  • 主键模型:主键模型的排序键在primary key()括号中指定,并且排序键需要满足唯一性约束。

1.2.3 注意事项

  • 在建表语句中,排序键必须定义在其他列之前
  • 指定排序键的时候,列的顺序要和建表语句中的相同,否则建表语句会报错
  • 在创建表时,可以将一个或多个列定义为排序键。排序键在建表语句中的出现次序,为数据存储时多重排序的次序
  • 排序键不要包含过多的列。如果选择了大量的列用于排序,那么排序的开销会导致数据导入的时间和资源使用增加
  • 排序键的选择需要结合查询业务场景,建表时可以将经常作为查询条件的列指定为排序键。当排序键涉及多个列的时候,我们要将区分度高、经常查询的列建议放在前面。

二、明细模型

2.1 概述

     明细模型是StarRocks中最常用的数据模型,适用于既没有聚合需求,又没有主键唯一性约束的原始数据的存储。在该模型下,即便导入两条完全相同的数据,StarRocks也会将数据原封不动的保存进表。

2.2 适用场景

   明细模型通常用于追加式的数据写入,比较适合:

  • 查询方式灵活,不需要局限于预聚合的分析方式
  • 旧数据不会更新,只会追加新的数据

2.3 建表语句及说明

#  建表语句如下
create table if not exists 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 ""
)
duplicate key(event_time, event_type)
distributed by hash(user_id)
properties (
"replication_num" = "3"
);#使用duplicate keY(event_time, event_type,user_id )显式的说明采用明细模型
#指定event_time、event_type和user_id 作为排序键
#user_id作为分桶键,全表只有一个分区

建表说明:

  • 建表时必须使用distributed by hash子句指定分桶键,否则建表失败
  • 在建表语句中,排序键必须定义在其他列之前,上述建表语句中排序键为 event_time和 event_type

  • 明细模型中的排序键可以为部分或全部维度列;
  • 在省略duplicate key(列1,列2……)时,默认选择表的前三列作为排序键
#  上述的建表语句可以简写为:
create table if not exists 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 ""
)
distributed by hash(user_id)
properties (
"replication_num" = "3"
);

三、聚合模型

3.1 概述

    建表时定义排序键(维度列key)和指标列(指标列value),并为指标列指定聚合函数。聚合模型会在数据导入时将维度列相同的数据,根据指标列设定的聚合函数进行聚合,最终表格中只会保留聚合后的数据。

3.2 适用场景

  • 分析统计和汇总数据,例如:用户的访问总时长、访问总次数
  • 不需要查询原始的明细数据

3.3 聚合原理

   数据的聚合,在StarRocks中有如下三个阶段发生,聚合模型的实现方式是读时合并(merge on read)。

   ps: 这种实现方式的表简称为Mor 表,Mor 表是指在导入数据时,不会对数据进行合并,而是在查询时动态合并数据。这种方式可以提高导入速度,但是会增加查询开销。虽然写入时处理简单高效,但是查询时需要在线聚合多版本。并且由于 Merge 算子的存在,谓词和索引无法下推,严重影响了查询性能。

  • 每一批次数据导入的 ETL 阶段:每一个批次的数据形成一个版本version,在一个版本中,同一个排序键的数据内部进行聚合
  • 底层BE进行数据 Compaction 的阶段:BE 会对已导入的多版本的文件定期合并成一个大版本文件
  • 数据查询阶段:对于查询涉及到的数据,所有版本的同一排序键的数据进行聚合,然后再返回查询最终结果

3.3 建表语句及说明

#分析某一段时间内,来自不同城市的用户,访问不同网页的总次数
create table if not exists aggregate_tbl (site_id largeint not null comment "id of site",date date not null comment "time of event",city_code varchar(20) comment "city_code of user",pv bigint sum default "0" comment "total page views"
)
aggregate key(site_id, date, city_code)
distributed by hash(site_id)
properties (
"replication_num" = "3"
);#排序键必须满足唯一性约束,并且需要按建表顺序指定所有的维度列
#上述的排序键是site_id, date, city_code

 建表说明:

  • 建表时必须使用distributed by hash子句指定分桶键,否则建表失败。
  • 排序键:在建表语句中,排序键必须定义在其他列之前。排序键可以通过aggregate key显式定义,上述建表语句中排序键为site_id、date和city_code ,指标列是pv。
  • 如果不通过aggregate key显示定义排序键,则默认除指标列之外的列均为排序键。
#  上述的建表语句可以简写为:
create table if not exists aggregate_tbl (site_id largeint not null comment "id of site",date date not null comment "time of event",city_code varchar(20) comment "city_code of user",pv bigint sum default "0" comment "total page views"
)
distributed by hash(site_id)
properties (
"replication_num" = "3"
);
  • 指标列:通过在列名后指定聚合函数,定义该列为指标列,一般为需要汇总统计的数据。

  • 聚合函数:指标列使用的聚合函数,例如sum,max等。

  • 查询时,排序键的过滤在多版本的聚合之前进行,而指标列的过滤在多版本的聚合之后。因此建表可以将频繁使用的过滤字段作为排序键,这样在对数据聚合之前,就可以先过滤一批数据,提升查询性能。

四、更新模型

4.1 概述

     建表时,支持定义主键和指标列,查询时返回主键相同的一组数据中的最新数据。

     明细模型会将所有写入的数据保留,聚合模型是对写入的数据进行聚合处理,而更新模型的特点是只保留相同主键下最新导入的数据。在更新模型中,排序键构成表的唯一性约束,成为我们常说的“主键”。

4.2 适用场景

    实时和频繁更新的业务场景,例如电商场景中,订单状态经常变化,每天的订单更新量可能会突破上亿。

4.3 更新原理

   更新模型本质上是聚合模型的一个特例, 更新模型的指标列指定的聚合函数为replace,返回具有相同主键的一组数据中的最新数据。聚合模型的实现方式是读时合并(merge on read),Unique模型新的实现方式也是读时合并(merge on read)。 

     ps: 这种实现方式的表简称为Mor 表,Mor 表是指在导入数据时,不会对数据进行合并,而是在查询时动态合并数据。这种方式可以提高导入速度,但是会增加查询开销。虽然写入时处理简单高效,但是查询时需要在线聚合多版本。并且由于 Merge 算子的存在,谓词和索引无法下推,严重影响了查询性能。

4.4 建表语句及说明

#在电商订单分析场景中,经常按照日期对订单状态进行统计分析
create table if not exists orders (create_time date not null comment "create time of an order",order_id bigint not null comment "id of an order",order_state int comment "state of an order",total_price bigint comment "price of an order"
)
unique key(create_time, order_id)
distributed by hash(order_id) buckets 8
properties (
"replication_num" = "3"
); #既能够满足实时更新订单状态的需求,又能够在查询中进行快速过滤#将经常使用的过滤字段订单创建时间create_time、订单编号order_id 作为主键,其余列订单状态 order_state和订单总价total_price作为指标列

 建表说明:

  • 建表时必须使用distributed by hash子句指定分桶键,否则建表失败
  • 在建表语句中,排序键(该模型中的排序键也称作主键)必须定义在其他列之前,上述建表语句中排序键(主键)为 create_time, order_id
  • 主键必须满足唯一性约束
  • 查询时,排序键(主键)的过滤在多版本的聚合之前进行,而指标列的过滤在多版本的聚合之后。因此建表可以将频繁使用的过滤字段作为排序键,这样在对数据聚合之前,就可以先过滤一批数据,提升查询性能。

五、主键模型

5.1 概述

   建表时,支持定义主键和指标列,查询时返回主键相同的一组数据中的最新数据。主键模型和更新模型的区别在于:更新模型的实现方式是读时合并(merge on read),简称Mor Primary 模型实现方式是写时合并(merge on write),简称Mow。聚合模型和更新模型都不支持update功能,主键模型通过Delete+Insert 的策略,实现update功能。

 ps:(更新模型)Mor 表是指在导入数据时,不会对数据进行合并,而是在查询时动态合并数据。这种方式可以提高导入速度,但是会增加查询开销虽然写入时处理简单高效,但是查询时需要在线聚合多版本。并且由于 Merge 算子的存在,谓词和索引无法下推,严重影响了查询性能

    (主键模型)Mow表是指在导入数据时,会对数据进行合并,保证每个 key 值只有一条记录,即数据在导入阶段就将被覆盖和被更新的数据进行标记删除,同时将新的数据写入新的文件。在查询的时候, 所有被标记删除的数据都会在文件级别被过滤掉,读取出来的数据就都是最新的数据,消除掉了读时合并中的数据聚合过程。这种方式可以提高查询速度,但是会增加导入开销。相对于更新模型,主键模型在查询时不需要执行聚合操作,并且支持谓词和索引下推。

5.2 适用场景

主键模型适用于实时和频繁更新的场景,例如:

  • 实时对接事务型数据至 StarRocks:事务型数据库中,除了插入数据外,一般还会涉及较多更新和删除数据的操作
  • 支持部分列更新轻松实现多流 JOIN:主键模型的部分列更新功能就很好地满足这种需求,不同业务直接各自按需更新与业务相关的列即可,并且继续享受主键模型的实时同步增删改数据及高效的查询性能

5.3 更新原理

      主键模型采用了 Delete+Insert 的策略,保证同一个主键下仅存在一条记录,这样就完全避免了 Merge 操作。主键模型实现方式是写时合并(merge on write),即数据在导入阶段就将被覆盖和被更新的数据进行标记删除,同时将新的数据写入新的文件。在查询的时候, 所有被标记删除的数据都会在文件级别被过滤掉,读取出来的数据就都是最新的数据,消除掉了读时合并中的数据聚合过程。写时合并(merge on write)的实现方式如下:

  • StarRocks 收到对某记录的更新操作时,会通过主键索引找到该条记录的位置,并对其标记为删除(旧记录标记删除Delete),再插入一条新的记录。相当于把Update改写为 Delete+Insert。

  • StarRocks 收到对某记录的删除操作时,会通过主键索引找到该条记录的位置,对其标记为删除(旧记录标记删除)。

5.4 建表语句及说明

# 需要实时分析用户情况,将user_id 作为主键,其余为指标列。建表语句如下:
create table users (user_id bigint not null,name string not null,email string null,address string null,age tinyint null,sex tinyint null,last_active datetime,property0 tinyint not null,property1 tinyint not null,property2 tinyint not null,property3 tinyint not null
) primary key (user_id)
distributed by hash(user_id) buckets 4
properties ("replication_num" = "3","enable_persistent_index" = "true"
);#分区列和分桶列必须在主键中,该表中的分桶键(分桶列)是user_id,全表只有一个分区

 建表说明:

  • 建表时必须使用distributed by hash子句指定分桶键,否则建表失败
  • 在建表语句中,主键必须定义在其他列之前
  • 主键通过primary key定义,本示例中主键为user_id
  • 主键必须满足唯一性约束
  • 分区列和分桶列必须在主键中

参考文章:

数据模型 - Apache Doris

第2.2章:StarRocks表设计--数据模型_starrocks 自增主键-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/694202.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络入门基础

本专栏内容为:Linux学习专栏,分为系统和网络两部分。 通过本专栏的深入学习,你可以了解并掌握Linux。 💓博主csdn个人主页:小小unicorn ⏩专栏分类:网络 🚚代码仓库:小小unicorn的代…

[AIGC] JVM内存结构中的方法区主要存储哪些信息?

在JVM的内存结构中,方法区(Method Area)被视为JVM的永久代。它主要负责存储已经被虚拟机加载的类信息、常量、静态变量以及编译器编译后的代码等数据。具体可以分为以下几个部分: 类信息 这部分信息包括类数据(如类名…

32FLASH闪存

目录 一.FLASH简介 二.代码实现 (1)读写内部FLASH (2)读取芯片ID 一.FLASH简介 存储器地址要记得累 系统存储器是原厂写入的Bootloader程序(用于串口下载)&#xff0…

04.结构体和结构体数组

1.结构体 struct stu{int id;string name;float grade; };2.结构体数组的排序 sort算法如果是非自定义类型可以缺省,默认升序排序,但自定义类型必须自己重写比较规则,因为系统没法知道你怎么比较 sort(首元素地址,尾元素下一位…

Python 写网络监控

大家好!我是爱摸鱼的小鸿,关注我,收看每期的编程干货。 网络监控是保障网络可靠性的一项重要任务。通过实时监控网络性能,我们可以及时发现异常,迅速采取措施,保障网络畅通无阻。本文将以 Python为工具&…

Debug系列 GroupNorm和BatchNorm出现Nan或inf的情况

Debug系列 GroupNorm和BatchNorm出现Nan或inf的情况 前言这两个函数做了什么可能出现的问题解决方法train和evalbatchsize或channel设置过小可训练参数的问题数值溢出其它的方法 前言 在复现别人论文的实验结果时,按照README乖乖做完之后,却发现损失函数…

Windows / Linux dir 命令

Windows / Linux dir 命令 1. dir2. dir *.* > data.txt3. dir - list directory contentsReferences 1. dir 显示目录的文件和子目录的列表。 Microsoft Windows [版本 10.0.18363.900] (c) 2019 Microsoft Corporation。保留所有权利。C:\Users\cheng>dir驱动器 C 中…

线性代数:向量组的秩

目录 回顾“秩” 及 向量组线性表示 相关特性 向量组的秩 例1 例2 矩阵的“秩” 及 向量组线性表示 相关特性 向量组的秩 例1 例2

@Async引发的spring循环依赖的问题,

今天发现一个很有意思的问题,正常解决项目中产生的循环依赖,是找出今天添加的注入代码,然后一个个加lazy试过去,会涉及到类中新增的注入 但是今天修改了某个serviceimpl的方法,加入了Async方法后 就发生循环依赖了 ai…

【职场经验】关于自动化用例设计的思考

为什么要设计用例? 作为质量保证(QA)人员,设计测试用例的重要性不亚于开发人员编写技术实现方案。如果实现方案设计不周,编码阶段将可能遇到许多问题;同理,如果我们未能设计测试用例,产品质量就难以得到充…

如何实现一个K8S DevicePlugin?

什么是device plugin k8s允许限制容器对资源的使用,比如CPU和内存,并以此作为调度的依据。 当其他非官方支持的设备类型需要参与到k8s的工作流程中时,就需要实现一个device plugin。 Kubernetes提供了一个设备插件框架,你可以用…

机器视觉系统选型-为什么还要选用工业光源控制器

工业光源控制器最主要的用途是给光源供电,实现光源的正常工作。 1.开关电源启动时,电压是具有波浪的不稳定电压,其瞬间峰值电压超过了LED灯的耐压值,灯珠在多次高压冲击下严重降低了使用寿命; 2.使用专用的光源控制器&…

【算法学习】搜索算法之深度优先搜索

深度优先搜索 DFS 1.算法介绍 深度优先搜索(DFS)算法是一种用于遍历或搜索树或图的算法。它的基本思想是尽可能深地搜索图的分支,直到到达叶节点或无法再深入为止,然后回溯到前一个节点,继续探索其他分支。这种搜索策略可以确保图中的每个节点都被访问到,除非它是一个环。…

inBuilder低代码平台新特性推荐-第十六期

各位友友们,大家好~今天来给大家介绍一下inBuilder低代码平台社区版中的系列特性之一 —— 构件热加载! 01 概述 构件热加载指的是:构件代码修改后,无需重启应用,通过WebIDE的部署或发布工程后,即可正常调…

08-静态pod(了解即可,不重要)

我们都知道,pod是kubelet创建的,那么创建的流程是什么呐? 此时我们需要了解我们k8s中config.yaml配置文件了; 他的存放路径:【/var/lib/kubelet/config.yaml】 一、查看静态pod的路径 [rootk8s231 ~]# vim /var/lib…

代码的复用——Mixin使用例子

Mixin(混入)是一种在Sass和Vue.js等框架中常用的技术,用于分发和重用代码。以下是Sass和Vue.js中Mixin的使用举例。 在Sass中,Mixin允许你定义可以在整个样式表中重复使用的样式。以下是一个Sass中Mixin的使用例子: …

华为配置直连三层组网直接转发示例

华为配置直连三层组网直接转发示例 组网图形 图1 配置直连三层组网直接转发示例组网图 业务需求组网需求数据规划配置思路配置注意事项操作步骤配置文件扩展阅读 业务需求 企业用户接入WLAN网络,以满足移动办公的最基本需求。且在覆盖区域内移动发生漫游时&#xff…

标题:从预编译到链接:探索C/C++程序的翻译环境全貌

引言 在软件开发的世界里,我们通常会遇到两种不同的环境——翻译环境与运行环境。今天,我们将聚焦于前者,深入剖析C/C程序生命周期中至关重要的“翻译环境”,即从源代码到可执行文件这一过程中涉及的四个关键阶段:预编…

三七互娱,顺丰24春招内推

三七互娱,顺丰24春招内推 ①三七互娱 【介绍】知名上市游戏企业,24届本科及以上可投递,使用内推码,面试快人一步! 【岗位】美术设计类,运营类,游戏研发类,策划类,市场推广…

设备改造经历干扰处理

设备改造完了,终于松了口气。没过几天,客户打电话过来,刚松了的那口气立马又吊了起来。通过客户描述,感觉麻烦来了。 客户每台机器都用了4台伺服,国产某品牌的,之前就经常发生液压站压力变送器损坏、某个环节偶尔不工作等情况,通过增加滤波电路、分开走线等措施解决了。…