【主键模型】主键长度问题

SR 版本 2.5.3 46bf084

官方文档 逐渐模型种描述:* 如果开启持久化索引,主键模型大大降低了主键索引对内存的占用。因为导入时少部分主键索引存在内存中,大部分主键索引存在磁盘中。 单条主键编码后的最大长度为 128 字节

主键编码指的是什么?
目前发现的问题,主键表用三个varchar 字段作为主键,插入 length 为126的字符后出现主键超长

  1. 建表语句
    CREATE TABLE dwd_pom_mapping_back (

CODE varchar(765) NOT NULL COMMENT “”,

SOURCE_SYSTEM varchar(765) NOT NULL COMMENT “”,

FACTORY_CODE varchar(765) NOT NULL COMMENT “”,

ID decimal128(20, 0) NULL COMMENT “”,

VALID int(11) NULL COMMENT “”,

FACTORY_ID decimal128(20, 0) NULL COMMENT “”,

WM_EXTRA_UPDATE_TIME datetime NULL COMMENT “”

) ENGINE=OLAP

PRIMARY KEY(CODE, SOURCE_SYSTEM, FACTORY_CODE)

COMMENT “OLAP”

DISTRIBUTED BY HASH(CODE, SOURCE_SYSTEM, FACTORY_CODE) BUCKETS 10

PROPERTIES (

“replication_num” = “1”,

“in_memory” = “false”,

“storage_format” = “DEFAULT”,

“enable_persistent_index” = “true”

);

  1. 插入语句
    INSERT INTO dwd_pom_mapping_back (CODE,SOURCE_SYSTEM,FACTORY_CODE) VALUES (‘111111111111111111111111111111111111111111’, ‘111111111111111111111111111111111111111111’, ‘111111111111111111111111111111111111111111’);

执行后报错

长度查询

  1. 插入语句2
    INSERT INTO dwd_pom_mapping_back (CODE,SOURCE_SYSTEM,FACTORY_CODE) VALUES (‘烟台区域_环保科技污水处理装置_9724 东区电池回收废水预处理单元’,‘POMAPI_SYSTEM_TYPE/HSE’,‘WH_YT_HBKJ_NLHS_DQ’);

执行报错

长度查询

对文档中的描述 单条主键编码后的最大长度为 128 字节有点疑惑,有没有大佬可以讲一下这块的细节。

Strarocks社区群9

CREATE TABLE `dwd_pom_mapping_back` (
  `CODE` varchar(765) NOT NULL COMMENT "",
  `SOURCE_SYSTEM` varchar(765) NOT NULL COMMENT "",
  `FACTORY_CODE` varchar(765) NOT NULL COMMENT "",
  `ID` decimal128(20, 0) NULL COMMENT "",
  `VALID` int(11) NULL COMMENT "",
  `FACTORY_ID` decimal128(20, 0) NULL COMMENT "",
  `WM_EXTRA_UPDATE_TIME` datetime NULL COMMENT ""
) ENGINE=OLAP
PRIMARY KEY(`CODE`, `SOURCE_SYSTEM`, `FACTORY_CODE`)
COMMENT "OLAP"
DISTRIBUTED BY HASH(`CODE`, `SOURCE_SYSTEM`, `FACTORY_CODE`) BUCKETS 10
PROPERTIES (
"replication_num" = "1",
"in_memory" = "false",
"storage_format" = "DEFAULT",
"enable_persistent_index" = "true"
);

INSERT INTO dwd_pom_mapping_back (CODE,SOURCE_SYSTEM,FACTORY_CODE) VALUES ('烟台区域_环保科技污水处理装置_9724 东区电池回收废水预处理单元','POMAPI_SYSTEM_TYPE/HSE','WH_YT_HBKJ_NLHS_DQ');
	
INSERT INTO dwd_pom_mapping_back (CODE,SOURCE_SYSTEM,FACTORY_CODE) VALUES ('111111111111111111111111111111111111111111', '111111111111111111111111111111111111111111', '111111111111111111111111111111111111111111');

select LENGTH (CONCAT('111111111111111111111111111111111111111111',
	'111111111111111111111111111111111111111111', 
	'111111111111111111111111111111111111111111'));

select CONCAT('111111111111111111111111111111111111111111',
	'111111111111111111111111111111111111111111', 
	'111111111111111111111111111111111111111111');
	
select LENGTH (CONCAT('烟台区域_环保科技污水处理装置_9724 东区电池回收废水预处理单元','POMAPI_SYSTEM_TYPE/HSE','WH_YT_HBKJ_NLHS_DQ'));
select current_version();


CREATE TABLE `dwd_pom_mapping_back` (
  `CODE` varchar(765) NOT NULL COMMENT "",
  `SOURCE_SYSTEM` varchar(765) NOT NULL COMMENT "",
  `FACTORY_CODE` varchar(765) NOT NULL COMMENT "",
  `ID` decimal128(20, 0) NULL COMMENT "",
  `VALID` int(11) NULL COMMENT "",
  `FACTORY_ID` decimal128(20, 0) NULL COMMENT "",
  `WM_EXTRA_UPDATE_TIME` datetime NULL COMMENT ""
) ENGINE=OLAP
PRIMARY KEY(sha(md5(CONCAT(`CODE`, `SOURCE_SYSTEM`, `FACTORY_CODE`))))
COMMENT "OLAP"
DISTRIBUTED BY HASH(sha(md5(CONCAT(`CODE`, `SOURCE_SYSTEM`, `FACTORY_CODE`)))) BUCKETS 10
PROPERTIES (
"replication_num" = "1",
"in_memory" = "false",
"storage_format" = "DEFAULT",
"enable_persistent_index" = "true"
);

这样试试,不知道能不能成…

PRIMARY KEY(md5sum(`CODE`, `SOURCE_SYSTEM`, `FACTORY_CODE`))

还可以这样,就是不知道是否唯一

这种方案不太能接受,不能保证百分百唯一

计算方法是主键列实际值的byte不能超过127,一个汉字是3个byte,和length 计算方法不一样

可以细看一下,我是纯数字,127个数字字符

实际测试下来,127 个字节也无法插入

String str2 = "烟台区域_环保科技污水处理装置_974 东区电池回收废水预处理单元POMAPI_SYSTEM_TYPE/HSEWH_YT_HBKJ_NLHS_DQ";
        System.out.println(str2.getBytes(StandardCharsets.UTF_8).length); // 127

中间有一些编码开销,多列的时候会略小于128bytes,可以升级2.5版本最新版本,be primary_key_limit_size这个配置可以调大,但是注意调大后主键索引内存的使用

primary_key_limit_size 这个配置在文档中没找到,可以贴一下地址嘛。另外,这个多列的编码开销指的是什么,方便讲一下嘛?我现在内部做了一次主键长度校验,符合的才会发送到 sr中

@dongquan 大佬,这个额外的编码开销指的是什么。primary_key_limit_size 文档地址可以发下不

primary_key_limit_size 这个参数还没加到官网中,单位是字节。“编码开销”这个具体逻辑我需要确认下,简单理解为总长127字节,主键字段越多这个总长限制越少。

hi, @dongquan

“编码开销”这个具体逻辑我需要确认下,简单理解为总长127字节,主键字段越多这个总长限制越少。

请问这个编码开销确定了嘛,额外开销是怎么计算的?

我看的是3.1的代码,大概是这个逻辑:
列类型分两种:定长:long,int 这种可以从类型推断出最大长度的;变长:varchar不确定数据长度
校验规则:
1、如果varchar在最后一列,则 pk_size = pk1(int).size+pk2(long).size+pk3(varchar).size
2、如果varchar不是最后一列,中间会有2字节的占位;size = pk1(int).size + [pk2(varchar).size + 2] + pk3(long).size

第一种情况,pk3 最大可以支持到128-4-8 = 116
第二种情况,pk2 最大可以支持到128-4-8-2 = 114