第2.5章:StarRocks表设计--数据类型

本文详细介绍了StarRocks中的数据类型,包括数值类型(如严格整型、近似数值和高精度定点数)、日期和时间类型、字符串类型以及特殊类型HLL和BITMAP。强调了正确选择数据类型对于查询效率的重要性,特别是如何利用非空约束和数字类型提升性能。HLL和BITMAP类型在聚合计数中发挥作用,提供了示例创建包含这些类型的表。

定义恰当数据字段类型对StarRocks查询的优化是非常重要的,从查询效率的角度考虑,我们可以遵循两条原则:

  • 如果数据没有Null,可以指定Not Null属性;
  • 尽量使用数字列代替字符串列。

StarRocks支持多种类型,大致可以分为:数值、时间、字符以和其他类型。

1数值类型

1.1严格数值整型

类型

大小

范围(区间)

TINYINT

1 Byte

[-128 , 127]

SMALLINT

2 Bytes

[-32768 , 32767]

NT

4 Bytes

[-2147483648 , 2147483647]

BIGINT

8 Bytes

[-9223372036854775808 , 9223372036854775807]

LARGEINT

16 Bytes

[-2^127 + 1 , 2^127 – 1]

BOOLEAN

1 Byte

0或1(0代表False,1代表True)

1.2近似数值类型

类型

大小

范围(区间)

FLOAT

4 Bytes

[-3.402 823 466 E+38,-1.175 494 351 E-38],0,[1.175 494 351 E-38,3.402 823 466 351 E+38]

DOUBLE


 

8 Bytes[-1.797 693 134 862 315 7 E+308,-2.225 073 858 507 201 4 E-308],0,[2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308]

1.3高精度定点数

类型

大小

范围

说明

Decimal V2

8 Bytes

DECIMAL(M[,D])

M范围是[1,27],D的范围[1, 9],M需大于等于D的取值。默认的D取值为0

Fast Decimal

16 Bytes

M的范围是[1,38], D的范围[1, M]。默认的D取值为0。

注意:自StarRocks 1.18版本已默认为Fast Decimal。

2日期和时间类型

StarRocks的时间类型只有两个:DATA和DATATIME,这两个类型都不会保存时区信息。

类型

大小

取值范围

默认形式

DATE

4 Bytes

['0000-01-01', '9999-12-31']

YYYY-MM-DD

DATETIME

8 Bytes

['0000-01-01 00:00:00', '9999-12-31 23:59:59']

YYYY-MM-DD HH:MM:SS

3字符串类型

StarRocks的字符串类型目前有三种:

类型

范围

用途

CHAR

CHAR(M),M为[1, 255]

定长字符串

VARCHAR

VARCHAR(M),M为[1, 65533]

变长字符串

STRING

目前等价与VARCHAR(65533)

变长字符串

说明:

1)Varchar中,由于前两个字节用于表示长度,因此比65535少两字节;

2)上表中M的值为字节数(不同于MySQL的字符数),所以在做MySQL的数据迁移时,StarRocks中M的值可以是MySQL的三到四倍;

3)当前不支持不限长的文本存储;

4)2.1版本开始,varchar()的上限增大为1MB,即取值为1-1048576字节。

4其他类型

4.1 HLL(HyperLogLog)

HLL是基于HyperLogLog算法的工程实现,用于保存HyperLogLog计算过程的中间结果。hll(length),长度length范围1~16385。用户不需要指定长度和默认值、长度根据数据的聚合程度系统内控制,并且HLL列只能通过配套的hll_union_agg、hll_cardinality、hll_hash进行查询或使用。

使用示例:

create table table09(

id int,

dt date,

uv hll hll_union

)

distributed by hash(id) buckets 32;

4.2 BITMAP

BITMAP与HLL类似只能作为聚合表的value类型使用,常见用来加速count distinct的去重计数使用。

使用示例:

CREATE TABLE table10 (

  `page_id` INT NOT NULL COMMENT '页面id',

  `visit_date` datetime NOT NULL COMMENT '访问时间',

  `visit_users` BITMAP BITMAP_UNION NOT NULL COMMENT '访问用户id'

) ENGINE=OLAP

AGGREGATE KEY(`page_id`, `visit_date`)

DISTRIBUTED BY HASH(`page_id`) BUCKETS 10

PROPERTIES (

  "replication_num" = "1"

);

<think>我们正在处理一个StarRocks写入报错:The row is out of partition ranges. Please add a new partition. 错误信息表明我们尝试插入的数据行(Row)的分区值(这里是2025-07-01)不在当前已有的分区范围内。 因此,我们需要为这个分区值(2025-07-01)创建一个新的分区。 处理步骤: 1. 确定表的分区方式:通常为范围分区(Range Partition),可能按日期分区(比如按月、按天等)。 2. 查看当前表的分区结构,确认是否包含2025-07-01所在的分区。 3. 如果没有,则需要添加一个新的分区,使其包含2025-07-01这个日期(或这个日期所在的区间)。 示例解决方案: 假设表结构如下(我们需要知道实际的分区列和分区方式): CREATE TABLE example_table ( id VARCHAR(255), dt DATE, ...其他列... ) ENGINE=OLAP PARTITION BY RANGE(dt) ( PARTITION p202501 VALUES [('2025-01-01'), ('2025-02-01')), PARTITION p202502 VALUES [('2025-02-01'), ('2025-03-01')), ... ); 报错中插入的行的日期是2025-07-01,而当前表的分区只定义到2025年6月(假设),那么我们需要添加2025年7月的分区。 添加分区的SQL语句示例: ALTER TABLE example_table ADD PARTITION p202507 VALUES [('2025-07-01'), ('2025-08-01')); 注意:分区范围是左闭右开区间 [start, end) 但是,如果分区是按月自动创建的,我们可以考虑使用动态分区特性(Dynamic Partition)来避免未来再次出现此问题。 动态分区配置: ALTER TABLE example_table SET ("dynamic_partition.enable" = "true"); ALTER TABLE example_table SET ("dynamic_partition.time_unit" = "MONTH"); ALTER TABLE example_table SET ("dynamic_partition.start" = "-3"); // 保留最近3个月的分区 ALTER TABLE example_table SET ("dynamic_partition.end" = "3"); // 提前创建未来3个月的分区 这样,StarRocks会自动创建未来3个月的分区,避免插入未来数据时报错。 然而,在修复当前问题之前,我们需要手动添加缺失的分区(2025-07-01所在的分区)。 具体步骤: 1. 连接到StarRocks数据库。 2. 执行添加分区的SQL(注意替换表名和分区范围): ALTER TABLE your_table_name ADD PARTITION partition_name VALUES [("start_date"), ("end_date")); 3. 确认分区添加成功:SHOW PARTITIONS FROM your_table_name; 如果不知道表的分区键和分区方式,可以通过以下命令查看表结构: SHOW CREATE TABLE your_table_name; 注意:报错中的Row数据示例中,第二个字段是2025-07-01(日期类型),所以分区键应该是这个日期字段。 如果分区是按天分区,那么我们需要添加的分区范围是['2025-07-01', '2025-07-02'),即只包含这一天的数据。 例如: ALTER TABLE your_table_name ADD PARTITION p20250701 VALUES [('2025-07-01'), ('2025-07-02')); 但是,如果分区是按月,则如上述示例添加整个月的分区。 重要:根据实际表的分区策略添加分区。 另外,如果数据量较大,且需要频繁添加分区,建议启用动态分区功能。 如果问题紧急,可以先手动添加分区,然后重新执行写入操作。 示例代码(假设表名为`your_table`,分区键为`dt`,按月分区): -- 添加2025年7月的分区 ALTER TABLE your_table ADD PARTITION p202507 VALUES [('2025-07-01'), ('2025-08-01')); 然后重新执行写入操作。 如果不知道如何确定分区范围,可以查看已有分区的定义: SHOW PARTITIONS FROM your_table; 观察已有分区的范围,然后按照同样的规则添加新分区。 注意:分区名称(如p202507)不能与现有分区重复。 如果错误中涉及多个分区值(即多个日期),则需要为每个缺失的分区都执行添加操作。 预防措施: - 启用动态分区(如果适用) - 定期检查分区情况,提前添加分区(特别是当已知未来数据会提前产生时) - 在写入前检查数据的分区值是否在已有分区范围内 如果表的分区方式不是按时间,而是其他范围,同样需要根据分区列的值确定分区范围,然后添加分区。 由于错误信息中明确指出了分区值(2025-07-01)和行数据,所以这里我们主要关注时间分区。 最后,重新执行写入操作。 如果问题仍然存在,请检查是否还有其他分区键导致的问题(例如复合分区)?但错误信息通常只报告第一个不满足的分区键。 因此,按照上述步骤处理即可。 下面给出一个完整的处理流程示例: 1. 查询表结构,确认分区方式: SHOW CREATE TABLE your_table; 2. 根据表结构,确定缺失的分区范围(2025-07-01)应该属于哪个分区。 3. 添加分区(假设按月分区): ALTER TABLE your_table ADD PARTITION p202507 VALUES [('2025-07-01'), ('2025-08-01')); 4. 确认分区添加成功: SHOW PARTITIONS FROM your_table; 5. 重新执行写入操作。 如果表的分区方式是按天,则添加: ALTER TABLE your_table ADD PARTITION p20250701 VALUES [('2025-07-01'), ('2025-07-02')); 注意:分区范围是左闭右开,所以2025-07-01的数据会落入该分区,而2025-07-02的数据则不会。 如果数据中还有2025-07-02的数据,那么我们需要为2025-07-02也添加分区,或者一次性添加多天的分区(如果分区是按天划分,则每天一个分区,或者按范围)。 如果分区是按天,并且需要添加多天,可以逐个添加,或者使用批量添加(StarRocks支持一次添加多个分区): ALTER TABLE your_table ADD PARTITION p20250701 VALUES [('2025-07-01'), ('2025-07-02')), ADD PARTITION p20250702 VALUES [('2025-07-02'), ('2025-07-03')), ...; 但是,如果数据日期跨度较大,手动添加麻烦,建议启用动态分区。 动态分区配置方法(假设按天分区): ALTER TABLE your_table SET ( "dynamic_partition.enable" = "true", "dynamic_partition.time_unit" = "DAY", "dynamic_partition.start" = "-30", // 保留过去30天 "dynamic_partition.end" = "3", // 提前创建未来3天 "dynamic_partition.prefix" = "p", // 分区名前缀 "dynamic_partition.buckets" = "10" // 每个分区的分桶数(根据数据量调整) ); 注意:动态分区只对时间分区有效,且分区列必须是DATE或DATETIME类型。 配置后,StarRocks会自动创建和删除分区(根据保留策略)。 如果表已经配置了动态分区,但是未来分区的创建还没有覆盖到2025-07-01,可能是因为动态分区的`end`设置不够大,可以调整`end`的值。 例如,将`end`调整为10,表示提前创建未来10天的分区。 总结:核心是添加缺失的分区,然后配置动态分区以避免未来再次出现。</think>### StarRocks "The row is out of partition ranges" 错误解决方案 #### 错误原因分析: 这个错误表示您尝试插入的数据行包含的分区键值(2025-07-01)超出了表当前定义的分区范围。StarRocks 的分区机制要求数据必须落在已定义的分区范围内,否则会拒绝写入。 #### 完整解决方案: ```sql -- 1. 查看表的分区定义 SHOW PARTITIONS FROM your_table_name; -- 2. 添加缺失的分区 (示例) ALTER TABLE your_table_name ADD PARTITION p202507 VALUES [("2025-07-01"), ("2025-08-01")); -- 3. 确认分区创建成功 SHOW PARTITIONS FROM your_table_name; -- 4. 重新执行写入操作 INSERT INTO your_table_name VALUES (...); ``` #### 关键操作说明: 1. **确定分区类型**: ```sql -- 查看表结构 SHOW CREATE TABLE your_table_name; ``` - 确认分区键字段(通常是日期字段) - 确认分区类型:Range分区 或 List分区 2. **添加单个分区**: ```sql -- 添加特定月份分区 ALTER TABLE your_table_name ADD PARTITION p202507 VALUES [('2025-07-01'), ('2025-08-01')); ``` 3. **批量添加未来分区**: ```sql -- 一次性添加多个月份分区 ALTER TABLE your_table_name ADD PARTITION p202507 VALUES [('2025-07-01'), ('2025-08-01')), ADD PARTITION p202508 VALUES [('2025-08-01'), ('2025-09-01')), ADD PARTITION p202509 VALUES [('2025-09-01'), ('2025-10-01')); ``` 4. **配置自动分区**(推荐长期方案): ```sql -- 启用动态分区 ALTER TABLE your_table_name SET ( "dynamic_partition.enable" = "true", "dynamic_partition.time_unit" = "MONTH", "dynamic_partition.start" = "-3", -- 保留最近3个月 "dynamic_partition.end" = "12", -- 提前创建未来12个月 "dynamic_partition.prefix" = "p", -- 分区名前缀 "dynamic_partition.buckets" = "8" -- 每个分区分桶数 ); ``` #### 预防措施: 1. **写入前检查分区**: ```python # Python 写入前检查分区是否存在 from starrocks.dbapi import connect conn = connect(host='your_host', port=9030, user='user', password='pass') cursor = conn.cursor() # 检查分区是否存在 cursor.execute(f"SHOW PARTITIONS FROM your_table WHERE PartitionName = 'p{partition_suffix}'") if not cursor.fetchall(): # 自动创建分区 cursor.execute(f"ALTER TABLE your_table ADD PARTITION p{partition_suffix} ...") ``` 2. **监控分区状态**: ```sql -- 创建定期检查任务 CREATE ROUTINE LOAD partition_monitor ON your_table PROPERTIES ( "desired_concurrent_number"="1", "max_error_number"="1000" ) FROM KAFKA (...) WHERE create_time >= NOW() + INTERVAL 1 MONTH; ``` 3. **分区维护脚本**: ```bash #!/bin/bash # 自动创建未来3个月分区 for i in {0..2}; do month=$(date -d "+${i} month" +%Y%m) starrocks-client -e "ALTER TABLE your_table ADD PARTITION p${month} ..." done ``` #### 分区策略优化建议: | 策略类型 | 适用场景 | 配置示例 | |---------|---------|---------| | **按月分区** | 时间序列数据 | `PARTITION BY RANGE(dt) (START ("2023-01-01") END ("2025-12-01"))` | | **按值分区** | 离散值数据 | `PARTITION BY LIST(city) (PARTITION p1 VALUES IN ("SH","BJ"))` | | **混合分区** | 大型数据集 | `PARTITION BY RANGE(dt) SUBPARTITION BY LIST(city)` |
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值