SQL 数据类型对照
MySQL ↔ PostgreSQL ↔ SQLite ↔ Oracle ↔ SQL Server · 跨数据库迁移参考
| 含义 | MySQL | PostgreSQL | SQLite | Oracle | SQL Server |
|---|
MySQL↔PG↔SQLite↔Oracle 字段类型
MySQL ↔ PostgreSQL ↔ SQLite ↔ Oracle ↔ SQL Server · 跨数据库迁移参考
| 含义 | MySQL | PostgreSQL | SQLite | Oracle | SQL Server |
|---|
了解工具定位 · 使用场景 · 对比优势
后端工程师将业务系统从 MySQL 迁移到 PostgreSQL 时,面临数百张表的字段类型兼容问题。本工具批量输入 MySQL 建表语句,一键输出 PG 兼容类型(如 TINYINT→SMALLINT、DATETIME→TIMESTAMP),并标注精度丢失风险字段,迁移前即可完成类型映射验证,避免上线后因类型截断导致数据写入失败。
SaaS 产品需同时支持 SQLite(本地版)和 Oracle(企业版),开发人员手工维护两套 DDL 极易出错。使用本工具将 Oracle 字段类型(如 NUMBER(10,2)→REAL、VARCHAR2(200)→TEXT)转成 SQLite 兼容类型,同时反向校验 SQLite 建表语句是否符合 Oracle 精度要求,确保同一份代码在不同数据库上建表一致。
团队使用 GORM(Go)或 SQLAlchemy(Python)时,ORM 模型字段类型与数据库实际类型不匹配会导致运行时异常。将 ORM 生成的 DDL 粘贴到本工具,对比 MySQL 与 SQLite 的字段映射差异,快速定位如 BOOL→TINYINT(1)、TEXT→CLOB 等隐式转换点,减少因类型不匹配触发的 500 错误。
接手一个运行 5 年的老项目,数据库为 Oracle,新需求需兼容 PostgreSQL。本工具逐字段分析 Oracle 建表语句,输出每个字段在 PG 中的推荐类型及潜在风险(如 NUMBER 无精度→NUMERIC 无限制、DATE 含时间→TIMESTAMP),配合注释说明哪些类型转换会丢失精度或改变排序规则,辅助制定迁移白名单。
技术书籍或教程常以单一数据库(如 MySQL)举例,读者使用 SQLite 或 Oracle 练习时 CREATE TABLE 语句无法直接运行。将教材中的 MySQL 建表语句输入本工具,自动转为目标数据库语法,同时保留字段注释和默认值定义,让学习者无需手动查阅各数据库类型对照表即可直接执行示例。
| 维度 | 本工具 (sql-type.tl654.com) | 竞品 A (dbconvert.com) | 传统方法 (手动查表) |
|---|---|---|---|
| 数据隐私 | 纯浏览器端处理,SQL 语句和类型数据不上传任何服务器 | 需上传 SQL 文件或数据库连接信息到云端服务器处理 | 数据完全本地,但依赖人工查阅文档,存在截图/复制粘贴泄露风险 |
| 处理速度 | 输入后 1 秒内返回转换结果 | 上传文件后需排队处理,通常 5-30 秒 | 查阅文档、手动映射,单条类型需 1-5 分钟,整表需数小时 |
| 离线可用 | 完全离线,无需网络,断网环境可用 | 必须联网,依赖云端 API | 完全离线,依赖纸质或本地文档 |
| 支持的数据库 | MySQL、PostgreSQL、SQLite、Oracle 四种互转 | 支持 10+ 种数据库,但免费版仅限 MySQL 到 PostgreSQL | 需分别查找两两数据库的官方文档进行比对 |
| 批量处理能力 | 支持一次性粘贴整个 CREATE TABLE 语句,批量转换所有字段 | 支持上传 .sql 文件批量转换 | 只能逐字段手动对照文档,无法批量 |
| 收费模式 | 完全免费,无隐藏付费功能 | 免费版有转换行数限制(如 100 行),完整版 $99/年 | 文档免费,但人工时间成本高 |
| 学习成本 | 零学习成本,粘贴-选择-复制,三步完成 | 需注册账号,学习上传文件、选择映射规则等操作流程 | 需熟悉各数据库官方文档的语法差异,学习成本高 |
上手步骤 · 输入输出 · 避坑提示
| 输入 | 输出 | 说明 |
|---|---|---|
| VARCHAR(255) | MySQL: VARCHAR(255) → PG: VARCHAR(255) → SQLite: TEXT → Oracle: VARCHAR2(255) | 典型场景:最常用的变长字符串类型 |
| INT AUTO_INCREMENT | MySQL: INT AUTO_INCREMENT → PG: SERIAL → SQLite: INTEGER PRIMARY KEY AUTOINCREMENT → Oracle: NUMBER GENERATED BY DEFAULT AS IDENTITY | 典型场景:自增主键在不同数据库中的写法差异 |
| BOOLEAN | MySQL: TINYINT(1) → PG: BOOLEAN → SQLite: INTEGER → Oracle: NUMBER(1) | 典型场景:布尔类型在 MySQL/Oracle 中无原生支持 |
| TEXT | MySQL: TEXT → PG: TEXT → SQLite: TEXT → Oracle: CLOB | 边界 case:大文本字段在 Oracle 中需转为 CLOB |
| DATETIME | MySQL: DATETIME → PG: TIMESTAMP WITHOUT TIME ZONE → SQLite: TEXT → Oracle: DATE | 边界 case:日期时间类型在 SQLite 中存为文本 |
| DECIMAL(10,2) | MySQL: DECIMAL(10,2) → PG: NUMERIC(10,2) → SQLite: REAL → Oracle: NUMBER(10,2) | 易错 case:SQLite 无精确 DECIMAL,转为浮点可能精度丢失 |
| ENUM('small','medium','large') | MySQL: ENUM('small','medium','large') → PG: VARCHAR(6) CHECK (value IN ('small','medium','large')) → SQLite: TEXT CHECK (value IN ('small','medium','large')) → Oracle: VARCHAR2(6) CHECK (value IN ('small','medium','large')) | 易错 case:ENUM 在非 MySQL 中需用 CHECK 约束模拟 |
| BIGINT UNSIGNED | MySQL: BIGINT UNSIGNED → PG: NUMERIC(20) → SQLite: INTEGER → Oracle: NUMBER(20) | 边界 case:无符号整数在 PG/Oracle 中需用 NUMERIC 替代 |
is_active BOOLis_active BOOLEAN (MySQL 实际映射为 TINYINT(1);PostgreSQL 用 BOOLEAN)MySQL 的 BOOL 是 TINYINT(1) 的别名,接受 0/1;PostgreSQL 的 BOOLEAN 接受 true/false/'t'/'f'。转换时需明确语义,否则数据迁移后查询条件失效。
is_active TINYINT(1)is_active INTEGER CHECK(is_active IN (0,1))SQLite 没有独立的 BOOLEAN 类型,用 INTEGER 存储 0/1。直接迁移 TINYINT(1) 虽能存储,但 SQLite 不限制值范围,可能写入 2 导致逻辑错误。加 CHECK 约束保语义。
salary NUMBERsalary NUMERIC(38,0) (若原字段无小数)Oracle NUMBER 默认精度 38、小数位 0。PostgreSQL NUMERIC 无参数时精度无限。直接迁移会导致 PostgreSQL 允许小数,破坏原业务约束。明确精度可保持行为一致。
created_at TIMESTAMPcreated_at TIMESTAMP WITHOUT TIME ZONEMySQL DATETIME 不涉及时区,PostgreSQL TIMESTAMP 默认 WITH TIME ZONE。转换后时间值会按 session 时区偏移,导致历史数据偏差。用 WITHOUT TIME ZONE 保留原意。
description TEXTdescription VARCHAR(65535) (或改用 TEXT)SQLite TEXT 无长度限制,MySQL VARCHAR 最大 65535 字节(受行大小限制)。直接转 VARCHAR 不设长度默认 1 字符,截断数据。若字段可能超长,应改用 MySQL TEXT。
age INT UNSIGNEDage INTEGER CHECK(age >= 0)MySQL UNSIGNED 禁止负数,PostgreSQL INT 允许负数。直接迁移后可能插入 -1,破坏数据完整性。用 CHECK 约束复现原语义。
code CHAR(10)code VARCHAR(10)Oracle VARCHAR2 是变长,MySQL CHAR 是定长(空格填充)。转换后查询时需 TRIM,否则 'AB' 与 'AB ' 不匹配。用 VARCHAR 保留变长行为。
price REALprice DOUBLE PRECISIONSQLite REAL 是 8 字节 IEEE 浮点,PostgreSQL REAL 是 4 字节。直接迁移会丢失精度,大数值或高精度场景出错。用 DOUBLE PRECISION(8 字节)匹配。
公式推导 · 流程图解 · 依据出处
type_map = {MySQL: {TINYINT: PG:SMALLINT, SQLite:INTEGER, Oracle:NUMBER(3)}, ...}
type_map — 数据库类型到目标类型的映射字典MySQL:TINYINT — MySQL 的 TINYINT 类型PG:SMALLINT — PostgreSQL 的 SMALLINT 类型SQLite:INTEGER — SQLite 的 INTEGER 类型Oracle:NUMBER(3) — Oracle 的 NUMBER(3) 类型将 MySQL 的 VARCHAR(255) 转换为 PostgreSQL:查询映射表得到 VARCHAR(255) → TEXT。若转换为 SQLite:VARCHAR(255) → TEXT。若转换为 Oracle:VARCHAR(255) → VARCHAR2(255)。转换过程不改变数据,仅改变类型声明语法。
适用于 MySQL 5.7+/8.0、PostgreSQL 9.6+、SQLite 3.x、Oracle 12c+ 的常见字段类型。不适用于自定义类型、枚举类型、空间数据类型(如 GEOMETRY)、JSON 子类型(如 JSONB 的索引结构)。映射基于各数据库官方文档的兼容性对照表。
3 种主流语言 · 复制即用
import re
# MySQL → PostgreSQL 类型映射表
MYSQL_TO_PG = {
'int': 'integer',
'tinyint': 'smallint',
'bigint': 'bigint',
'varchar': 'text',
'text': 'text',
'datetime': 'timestamp',
'float': 'real',
'double': 'double precision',
'blob': 'bytea',
}
def convert_type(mysql_type: str) -> str:
"""将 MySQL 字段类型转为 PostgreSQL 等效类型"""
base = re.sub(r'\(.*\)', '', mysql_type).strip().lower()
return MYSQL_TO_PG.get(base, 'text') # 默认 fallback 为 text
# 示例
print(convert_type('VARCHAR(255)')) # text
print(convert_type('BIGINT')) # bigint
print(convert_type('DATETIME')) # timestamp
print(convert_type('BLOB')) # byteapackage main
import (
"fmt"
"strings"
)
var mysqlToPG = map[string]string{
"int": "integer",
"tinyint": "smallint",
"bigint": "bigint",
"varchar": "text",
"text": "text",
"datetime": "timestamp",
"float": "real",
"double": "double precision",
"blob": "bytea",
}
func convertType(mysqlType string) string {
// 去除括号及内容,转小写
idx := strings.Index(mysqlType, "(")
if idx != -1 {
mysqlType = mysqlType[:idx]
}
base := strings.ToLower(strings.TrimSpace(mysqlType))
if pg, ok := mysqlToPG[base]; ok {
return pg
}
return "text" // fallback
}
func main() {
fmt.Println(convertType("VARCHAR(255)")) // text
fmt.Println(convertType("BIGINT")) // bigint
fmt.Println(convertType("DATETIME")) // timestamp
}const mysqlToPG = {
int: 'integer',
tinyint: 'smallint',
bigint: 'bigint',
varchar: 'text',
text: 'text',
datetime: 'timestamp',
float: 'real',
double: 'double precision',
blob: 'bytea',
};
function convertType(mysqlType) {
// 提取类型基名(去掉括号及内容)
const base = mysqlType.replace(/\(.*\)/, '').trim().toLowerCase();
return mysqlToPG[base] || 'text';
}
// 示例
console.log(convertType('VARCHAR(255)')); // text
console.log(convertType('BIGINT')); // bigint
console.log(convertType('DATETIME')); // timestamp8 个高频疑问
「时间 / 数字开发」下的其他工具