clickhouse数据库表和doris数据库表迁移starrocks数据库时建表注意事项总结

发布于:2025-07-08 ⋅ 阅读:(16) ⋅ 点赞:(0)


零、前言

这可能是个技术选型的问题,前期各自为营,所以整个企业内部,数据库类型五花八门,相互之间数据也很难对齐引用。随着业务等等大势所趋,需要整合全公司资源,因此由来了这个数据资源迁移。针对迁移过程中的建表方面,作一总结,以备后续问题原因排查和进一步整改,让过程有迹可循。

一、clickhouse数据库表在starrocks数据库建表时问题总结

1.1 数据类型类问题:

  1. 字符类型varchar需要指定位数,默认位数为1,会导致 导入数据为空;
  2. 其它的类型映射遇到的映射关系,遇到的类型处理映射关系整理如下,其中key为clickhouse中的数据类型,value为对应的starrocks数据库类型:

{
‘Date’: ‘DATE’,
‘Nullable(Date)’: ‘DATE NULL’,
‘DateTime’: ‘DATETIME’,
‘Nullable(DateTime)’: ‘DATETIME NULL’,
‘Float64’: ‘FLOAT’,
‘Float32’: ‘FLOAT’,
‘Nullable(Float32)’: ‘FLOAT NULL’,
‘Nullable(Float64)’: ‘FLOAT NULL’,
‘Int32’: ‘INT’, ‘UInt32’: ‘INT’,
‘UInt16’: ‘INT’,
‘Int64’: ‘INT’,
‘Nullable(Int32)’: ‘INT NULL’,
‘Nullable(Int8)’: ‘INT NULL’,
‘Nullable(UInt32)’: ‘INT NULL’,
‘Nullable(Int64)’: ‘INT NULL’,
‘String’: ‘varchar(65535)’,
‘Nullable(String)’: ‘varchar(65535) NULL’
}

1.2 数据导出阶段:

  1. 默认通过【select * from table_name limit num offset offnum 】的形式进行大文件分拆,不指定排序会导致数据导出重复。这应该是大部分数据库的通病,需要注意先对数据按指定字段排序,再移动分块,就可以避免,当然就需要对该表多少有一些熟悉度,诸如主键等进行了解;
  2. clickhouse数据库通过【clickhouse-client】导出parquet文件,对于 日期时间类型 ,不明确通过 cast(字段名称 as datetime) 进行设定,会将日期时间转换为时间戳;

二、doris 数据库表在starrocks数据库建表时问题总结

doris数据库表DDL在starrocks中存在最主要的问题就是 properties属性 修改适配,字段类型目前所用类型全部可以在starrocks数据库中适配使用,所以无需更改。问题总结集中在properties方面。

2.1 properties不支持的属性(直接删除):

	"is_being_synced" = "false",
	"disable_auto_compaction" = "false",
	"enable_single_replica_compaction" = "false"
	"light_schema_change" = "true" 
	"dynamic_partition.create_history_partition" = "false",
	"dynamic_partition.storage_medium" = "HDD",
	"dynamic_partition.storage_policy" = "",
	"dynamic_partition.hot_partition_num" = "0",
	"dynamic_partition.reserved_history_periods" = "NULL",
	"enable_mow_light_delete" = "false"
	"light_schema_change" = "true"

2.2 properties需修改属性

	"replication_allocation" = "tag.location.default: 3"     				改为 "replication_num" = "3",
	"dynamic_partition.replication_allocation" = "tag.location.default: 3"  改为 "dynamic_partition.replication_num" = "3" 
	"dynamic_partition.history_partition_num" = "1200" starrocks数据库默认动态分区上限500,目前直接删除该属性

2.3 properties:doris建表语句分区明细,starrocks数据不需要明确设定,会自动更新

	a.PARTITION BY RANGE(`xxx`) 之后的明细分区,全部删除,不需指定,但括号需要保留。如:PARTITION BY RANGE(`xxx`)()
	b."dynamic_partition.start" = "-2147483648"  删除,不需指定

2.4 分桶设置问题

	DISTRIBUTED BY HASH(`vin`) BUCKETS AUTO ,starrocks不支持auto属性,直接设定具体数字,eg:10

2.5 索引设置问题

	索引类型:INDEX idx_vin (vin) USING INVERTED COMMENT '',starrocks不支持 INVERTED ,将索引类型修改为: USING BITMAP 即可。

2.6 python程序针对上述问题解决程序

# 删除分区明细
# 匹配分区定义部分,从(PARTITION开始到三个连续的右括号结束
# re.IGNORECASE:使正则表达式匹配时忽略大小写。 
# re.DOTALL:使 . 匹配任意字符,包括换行符。
pattern = r"\(PARTITION.*\){3}"
# step_one_sql = re.sub(pattern, "", sql, flags=re.IGNORECASE | re.DOTALL) # 这个会将分区明细全部剔除,且没有保留RANGE之后的明细需要的括号
step_one_sql = re.sub(pattern, "()", sql, flags=re.IGNORECASE | re.DOTALL) # 对上述sql的修正

# 正则表达式匹配并替换 BUCKETS AUTO 为 BUCKETS 10
step_one_sql = re.sub(r" BUCKETS AUTO", r" BUCKETS 10", step_one_sql) 

# 正则表达式匹配索引类型:并替换 
step_one_sql = re.sub(r" USING INVERTED ", r" USING BITMAP ", step_one_sql) 

# 正则表达式匹配 PROPERTIES 部分
pattern = r"(PROPERTIES\s*\([\s\S]*?\);)"
match = re.search(pattern, step_one_sql)    
if match:
	# 提取 PROPERTIES 部分
	properties_content = match.group(1)

	# 删除不支持的属性
	properties_content = re.sub(r'"is_being_synced"\s*=\s*"\w+"\s*,?', '', properties_content)
	properties_content = re.sub(r'"disable_auto_compaction"\s*=\s*"\w+"\s*,?', '', properties_content)
	properties_content = re.sub(r'"enable_single_replica_compaction"\s*=\s*"\w+"\s*,?', '', properties_content)
	properties_content = re.sub(r'"light_schema_change"\s*=\s*"\w+"\s*,?', '', properties_content)
	properties_content = re.sub(r'"dynamic_partition\.create_history_partition"\s*=\s*"\w+"\s*,?', '', properties_content)
	properties_content = re.sub(r'"dynamic_partition\.storage_medium"\s*=\s*"\w+"\s*,?', '', properties_content)
	properties_content = re.sub(r'"dynamic_partition\.storage_policy"\s*=\s*""\s*,?', '', properties_content)
	properties_content = re.sub(r'"dynamic_partition\.hot_partition_num"\s*=\s*"\w+"\s*,?', '', properties_content)
	properties_content = re.sub(r'"dynamic_partition\.reserved_history_periods"\s*=\s*"\w+"\s*,?', '', properties_content)
	properties_content = re.sub(r'"dynamic_partition\.start"\s*=\s*"[\w\d-]*"\s*,?', '', properties_content)
	properties_content = re.sub(r'"dynamic_partition\.history_partition_num"\s*=\s*"[\w\d-]*"\s*,?', '', properties_content)
	properties_content = re.sub(r'"enable_mow_light_delete"\s*=\s*"\w+"\s*,?', '', properties_content)
	

	# 修改属性
	properties_content = re.sub(
		r'"replication_allocation"\s*=\s*"tag\.location\.default:\s*\d+"',
		'"replication_num" = "3"',
		properties_content
	)
	# properties_content = re.sub(
	#     r'"light_schema_change"\s*=\s*"\w+"',
	#     '"enable_light_schema_change" = "true"',
	#     properties_content
	# )
	properties_content = re.sub(
		r'"dynamic_partition.replication_allocation"\s*=\s*"tag\.location\.default:\s*\d+"',
		'"dynamic_partition.replication_num" = "3"',
		properties_content
	)
	# properties_content = re.sub(
	#     r'"dynamic_partition.history_partition_num" = "-1"',
	#     '"dynamic_partition.history_partition_num" = "30"',
	#     properties_content
	# )

	# 清理多余的逗号和空白行
	properties_content = re.sub(r",\s*,", ",", properties_content)  # 清理多余的逗号
	properties_content = re.sub(r"\n\s*\n", "\n", properties_content)  # 清理空白行


	"""最后一个属性后 会有逗号,进行替换"""
	# 正则表达式:匹配 PROPERTIES 块中的最后一个逗号
	pattern = r'(?s)(PROPERTIES\s*\(.*?)(,\s*\);)'  # (?s) 表示单行模式,匹配换行符
	# 使用 re.sub 进行替换
	def remove_last_comma(match):
		# 如果匹配到逗号,则删除
		return match.group(1) + match.group(2).replace(',', '')
	
	properties_content = re.sub(pattern, remove_last_comma, properties_content)
	
	# 更新回 SQL 语句
	updated_sql = step_one_sql.replace(match.group(1), properties_content)

三、小结

初步测试上述问题解决方案运行可行,后续遇到新问题再进行补充更新。现有的豆包之类的工具,着实提高了问题解决的效率,从而让我们有了更多的思考时间。拥抱新工具,喜迎新未来。


网站公告

今日签到

点亮在社区的每一天
去签到