暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL到KaiwuDB数据类型映射全解析:避坑指南

原创 想你依然心痛 2026-08-17
128

Table of Contents


每日一句正能量

理解不是妥协,而是打开格局的钥匙。
看清事物因果与逻辑。钥匙打开了门,让你看清全貌,但进不进去、如何行动,主动权依然在你。

一、前言:数据类型是迁移的基石

前面四篇文章,我分享了MySQL迁移KaiwuDB的整体流程、KDTS图形化工具、DataX脚本化迁移、CSV离线兜底方案。有读者反馈:“迁移过程中最头疼的不是工具使用,而是数据类型不匹配导致的各种报错。”

确实,数据类型映射是数据库迁移中最基础也最容易出问题的环节。MySQL和KaiwuDB虽然都兼容SQL标准,但在具体实现上存在差异。一个小小的类型不匹配,可能导致数据截断、精度丢失,甚至迁移失败。

本文就把MySQL到KaiwuDB的数据类型映射完整梳理一遍,包括类型差异对比、常见陷阱、解决方案,以及我踩过的坑。


二、数据类型对比总览

2.1 整数类型

MySQL类型 KaiwuDB类型 存储范围 注意事项
TINYINT INT2 -128 ~ 127 直接映射
TINYINT UNSIGNED INT2 0 ~ 255 直接映射
SMALLINT INT2 -32768 ~ 32767 直接映射
SMALLINT UNSIGNED INT4 0 ~ 65535 需放大到INT4
MEDIUMINT INT4 -8388608 ~ 8388607 直接映射
MEDIUMINT UNSIGNED INT4 0 ~ 16777215 需放大到INT4
INT INT4 -2147483648 ~ 2147483647 直接映射
INT UNSIGNED INT8 0 ~ 4294967295 需放大到INT8
BIGINT INT8 -9223372036854775808 ~ 9223372036854775807 直接映射
BIGINT UNSIGNED NUMERIC(20) 0 ~ 18446744073709551615 必须映射为NUMERIC(20)

踩坑点1:BIGINT UNSIGNED映射错误

-- MySQL CREATE TABLE test ( id BIGINT UNSIGNED PRIMARY KEY ); -- 错误:直接映射为INT8 CREATE TABLE test ( id INT8 PRIMARY KEY -- 错误!会溢出 ); -- 正确:映射为NUMERIC(20) CREATE TABLE test ( id NUMERIC(20) PRIMARY KEY );

原因:KaiwuDB的INT8最大值为9223372036854775807,而MySQL的BIGINT UNSIGNED最大值为18446744073709551615,直接映射会导致溢出。

2.2 浮点类型

MySQL类型 KaiwuDB类型 精度 注意事项
FLOAT FLOAT4 单精度 直接映射
DOUBLE FLOAT8 双精度 直接映射
DECIMAL(M,D) DECIMAL(M,D) 定点数 直接映射
NUMERIC(M,D) NUMERIC(M,D) 定点数 直接映射

踩坑点2:DECIMAL精度丢失

-- MySQL CREATE TABLE test ( amount DECIMAL(18,2) ); -- KaiwuDB(正确) CREATE TABLE test ( amount DECIMAL(18,2) ); -- 错误:改为FLOAT8 CREATE TABLE test ( amount FLOAT8 -- 错误!会丢失精度 );

原因:FLOAT8是浮点数,无法精确表示小数,会导致金额计算错误。DECIMAL是定点数,可以精确表示小数。

2.3 字符串类型

MySQL类型 KaiwuDB类型 最大长度 注意事项
CHAR(N) CHAR(N) N字符 直接映射
VARCHAR(N) VARCHAR(N) N字符 直接映射
TINYTEXT TEXT 255字节 直接映射
TEXT TEXT 65535字节 直接映射
MEDIUMTEXT TEXT 16777215字节 直接映射
LONGTEXT TEXT 无限制 直接映射
BINARY(N) BYTES N字节 直接映射
VARBINARY(N) VARBYTES N字节 直接映射
TINYBLOB BYTES 255字节 直接映射
BLOB BYTES 65535字节 直接映射
MEDIUMBLOB BYTES 16777215字节 直接映射
LONGBLOB BYTES 无限制 直接映射

踩坑点3:TEXT字段长度超限

-- MySQL CREATE TABLE test ( content LONGTEXT ); -- KaiwuDB(正确) CREATE TABLE test ( content TEXT -- TEXT在KaiwuDB中无长度限制 );

注意:KaiwuDB的TEXT类型没有长度限制,可以直接映射MySQL的LONGTEXT。

2.4 日期时间类型

MySQL类型 KaiwuDB类型 精度 注意事项
DATE DATE 日期 直接映射
TIME TIME 时间 直接映射
DATETIME TIMESTAMP 日期时间 注意时区
TIMESTAMP TIMESTAMPTZ 日期时间+时区 直接映射
YEAR INT2 年份 映射为INT2

踩坑点4:DATETIME时区问题

-- MySQL CREATE TABLE test ( created_at DATETIME ); -- KaiwuDB(正确) CREATE TABLE test ( created_at TIMESTAMP -- 注意:KaiwuDB的TIMESTAMP会自动处理时区 ); -- 如果需要保留原始时区信息 CREATE TABLE test ( created_at TIMESTAMPTZ -- 带时区的TIMESTAMP );

原因:MySQL的DATETIME不存储时区信息,而KaiwuDB的TIMESTAMP会转换为UTC存储。如果业务需要保留原始时区,应使用TIMESTAMPTZ。

2.5 JSON类型

MySQL类型 KaiwuDB类型 说明 注意事项
JSON JSON JSON数据 直接映射

踩坑点5:JSON字段长度超限

-- MySQL CREATE TABLE test ( ext JSON ); -- KaiwuDB(正确) CREATE TABLE test ( ext JSON ); -- 如果JSON数据过大 CREATE TABLE test ( ext TEXT -- 映射为TEXT,避免长度限制 );

原因:KaiwuDB的JSON类型有默认长度限制,如果JSON数据过大,可以映射为TEXT类型。

2.6 枚举和集合类型

MySQL类型 KaiwuDB类型 说明 注意事项
ENUM VARCHAR + CHECK 枚举值 需要手动创建CHECK约束
SET ARRAY或JSON 集合值 需要转换

踩坑点6:ENUM类型映射

-- MySQL CREATE TABLE test ( status ENUM('active', 'inactive', 'deleted') ); -- KaiwuDB(正确) CREATE TABLE test ( status VARCHAR(20) CHECK (status IN ('active', 'inactive', 'deleted')) );

原因:KaiwuDB不支持ENUM类型,需要使用VARCHAR + CHECK约束实现。


三、特殊类型处理

3.1 自增主键

MySQL KaiwuDB 说明
AUTO_INCREMENT 不支持 需要应用层生成或使用序列

解决方案

-- MySQL CREATE TABLE orders ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, order_no VARCHAR(64) ); -- KaiwuDB(使用序列) CREATE SEQUENCE orders_id_seq START 1 INCREMENT 1; CREATE TABLE orders ( id NUMERIC(20) DEFAULT nextval('orders_id_seq') PRIMARY KEY, order_no VARCHAR(64) ); -- 或者应用层生成ID CREATE TABLE orders ( id NUMERIC(20) PRIMARY KEY, order_no VARCHAR(64) );

3.2 位类型

MySQL KaiwuDB 说明
BIT(N) INT2/INT4/INT8 根据位数选择

解决方案

-- MySQL CREATE TABLE test ( flags BIT(8) ); -- KaiwuDB CREATE TABLE test ( flags INT2 -- 8位用INT2 );

3.3 空间类型

MySQL KaiwuDB 说明
GEOMETRY 不支持 需要转换
POINT 不支持 需要转换
LINESTRING 不支持 需要转换
POLYGON 不支持 需要转换

解决方案

-- MySQL CREATE TABLE test ( location POINT ); -- KaiwuDB(使用JSON存储) CREATE TABLE test ( location JSON -- 存储为{"x": 123.45, "y": 67.89} ); -- 或者使用两个字段 CREATE TABLE test ( location_x FLOAT8, location_y FLOAT8 );

四、类型映射工具

4.1 手动映射

根据上面的对照表,手动编写CREATE TABLE语句。

4.2 自动映射(KDTS)

KDTS会自动识别MySQL的类型并映射到KaiwuDB,但需要人工确认。

4.3 脚本自动映射

#!/usr/bin/env python3 # mysql_to_kaiwudb_types.py mysql_to_kaiwudb = { 'TINYINT': 'INT2', 'SMALLINT': 'INT2', 'MEDIUMINT': 'INT4', 'INT': 'INT4', 'BIGINT': 'INT8', 'FLOAT': 'FLOAT4', 'DOUBLE': 'FLOAT8', 'DECIMAL': 'DECIMAL', 'NUMERIC': 'NUMERIC', 'CHAR': 'CHAR', 'VARCHAR': 'VARCHAR', 'TEXT': 'TEXT', 'BLOB': 'BYTES', 'DATE': 'DATE', 'TIME': 'TIME', 'DATETIME': 'TIMESTAMP', 'TIMESTAMP': 'TIMESTAMPTZ', 'JSON': 'JSON', 'ENUM': 'VARCHAR', 'SET': 'ARRAY', 'BIT': 'INT2', } def map_type(mysql_type, unsigned=False): """映射MySQL类型到KaiwuDB类型""" base_type = mysql_type.upper().split('(')[0] if base_type == 'BIGINT' and unsigned: return 'NUMERIC(20)' if base_type == 'INT' and unsigned: return 'INT8' return mysql_to_kaiwudb.get(base_type, 'TEXT') # 测试 print(map_type('BIGINT', unsigned=True)) # NUMERIC(20) print(map_type('INT', unsigned=True)) # INT8 print(map_type('VARCHAR(64)')) # VARCHAR print(map_type('DECIMAL(18,2)')) # DECIMAL

五、常见问题排查

5.1 数据截断

问题:导入时数据被截断

ERROR: value too long for type character varying(64)

解决方案

-- 检查源数据最大长度 SELECT MAX(LENGTH(order_no)) FROM orders; -- 调整目标字段长度 ALTER TABLE orders ALTER COLUMN order_no TYPE VARCHAR(128);

5.2 精度丢失

问题:金额计算出现精度丢失

-- 错误:使用FLOAT8 SELECT SUM(amount) FROM orders; -- 结果:123456789.01000001 -- 正确:使用DECIMAL SELECT SUM(amount) FROM orders; -- 结果:123456789.01

解决方案:金额字段必须使用DECIMAL类型。

5.3 时区问题

问题:时间显示不一致

-- MySQL SELECT created_at FROM orders; -- 结果:2023-01-01 10:00:00 -- KaiwuDB SELECT created_at FROM orders; -- 结果:2023-01-01 02:00:00+00

解决方案

-- 设置时区 SET TIME ZONE 'Asia/Shanghai'; -- 或者使用TIMESTAMPTZ ALTER TABLE orders ALTER COLUMN created_at TYPE TIMESTAMPTZ;

六、最佳实践

6.1 迁移前检查

-- 检查MySQL表结构 SHOW CREATE TABLE orders; -- 检查字段类型和长度 SELECT column_name, data_type, character_maximum_length, numeric_precision, numeric_scale FROM information_schema.columns WHERE table_name = 'orders'; -- 检查数据范围 SELECT MIN(id) as min_id, MAX(id) as max_id, MAX(LENGTH(order_no)) as max_order_no_length FROM orders;

6.2 迁移后验证

-- 检查KaiwuDB表结构 SHOW CREATE TABLE orders; -- 检查数据类型 SELECT column_name, data_type, character_maximum_length FROM information_schema.columns WHERE table_name = 'orders'; -- 抽样验证 SELECT * FROM orders WHERE id = 10086;

6.3 类型映射检查清单

  • 整数类型:检查UNSIGNED,BIGINT UNSIGNED映射为NUMERIC(20)
  • 浮点类型:金额字段使用DECIMAL,避免使用FLOAT/DOUBLE
  • 字符串类型:检查长度,VARCHAR(N)直接映射
  • 日期时间:检查时区,DATETIME映射为TIMESTAMP
  • JSON类型:检查长度,过大时映射为TEXT
  • 枚举类型:使用VARCHAR + CHECK约束
  • 自增主键:使用序列或应用层生成

七、总结

数据类型映射是数据库迁移的基础,也是最容易出问题的环节。通过本文的介绍,你应该能够:

  1. 理解类型差异:MySQL和KaiwuDB的类型对应关系
  2. 避免常见陷阱:BIGINT UNSIGNED、DECIMAL精度、时区等
  3. 使用映射工具:手动映射、KDTS自动映射、脚本映射
  4. 验证迁移结果:检查表结构、抽样验证、性能测试

关键要点

  • BIGINT UNSIGNED必须映射为NUMERIC(20)
  • 金额字段必须使用DECIMAL,避免使用FLOAT/DOUBLE
  • DATETIME注意时区问题,使用TIMESTAMPTZ保留时区
  • JSON字段过长时映射为TEXT
  • ENUM类型使用VARCHAR + CHECK约束

如果你正在考虑数据库国产化迁移,建议先做好类型映射的规划,避免迁移过程中出现数据问题。


欢迎 👍点赞✍评论⭐收藏,欢迎指正

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论