SQL 类型转换

MySQL↔PG↔SQLite↔Oracle 字段类型

861 次访问

SQL 数据类型对照

MySQL ↔ PostgreSQL ↔ SQLite ↔ Oracle ↔ SQL Server · 跨数据库迁移参考

含义MySQLPostgreSQLSQLiteOracleSQL Server

关于本工具

了解工具定位 · 使用场景 · 对比优势

使用场景

🔄

数据库迁移校验

后端工程师将业务系统从 MySQL 迁移到 PostgreSQL 时,面临数百张表的字段类型兼容问题。本工具批量输入 MySQL 建表语句,一键输出 PG 兼容类型(如 TINYINT→SMALLINT、DATETIME→TIMESTAMP),并标注精度丢失风险字段,迁移前即可完成类型映射验证,避免上线后因类型截断导致数据写入失败。

🏗️

多数据库适配开发

SaaS 产品需同时支持 SQLite(本地版)和 Oracle(企业版),开发人员手工维护两套 DDL 极易出错。使用本工具将 Oracle 字段类型(如 NUMBER(10,2)→REAL、VARCHAR2(200)→TEXT)转成 SQLite 兼容类型,同时反向校验 SQLite 建表语句是否符合 Oracle 精度要求,确保同一份代码在不同数据库上建表一致。

📋

ORM 模型字段映射

团队使用 GORM(Go)或 SQLAlchemy(Python)时,ORM 模型字段类型与数据库实际类型不匹配会导致运行时异常。将 ORM 生成的 DDL 粘贴到本工具,对比 MySQL 与 SQLite 的字段映射差异,快速定位如 BOOL→TINYINT(1)、TEXT→CLOB 等隐式转换点,减少因类型不匹配触发的 500 错误。

🔍

遗留系统类型审计

接手一个运行 5 年的老项目,数据库为 Oracle,新需求需兼容 PostgreSQL。本工具逐字段分析 Oracle 建表语句,输出每个字段在 PG 中的推荐类型及潜在风险(如 NUMBER 无精度→NUMERIC 无限制、DATE 含时间→TIMESTAMP),配合注释说明哪些类型转换会丢失精度或改变排序规则,辅助制定迁移白名单。

📘

SQL 教材案例转换

技术书籍或教程常以单一数据库(如 MySQL)举例,读者使用 SQLite 或 Oracle 练习时 CREATE TABLE 语句无法直接运行。将教材中的 MySQL 建表语句输入本工具,自动转为目标数据库语法,同时保留字段注释和默认值定义,让学习者无需手动查阅各数据库类型对照表即可直接执行示例。

对比矩阵本工具 vs 竞品 vs 传统方法

维度本工具 (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/年文档免费,但人工时间成本高
学习成本零学习成本,粘贴-选择-复制,三步完成需注册账号,学习上传文件、选择映射规则等操作流程需熟悉各数据库官方文档的语法差异,学习成本高

使用指南

上手步骤 · 输入输出 · 避坑提示

输入输出示例8 个典型场景,覆盖常规、边界与易错

输入输出说明
VARCHAR(255)MySQL: VARCHAR(255) → PG: VARCHAR(255) → SQLite: TEXT → Oracle: VARCHAR2(255)典型场景:最常用的变长字符串类型
INT AUTO_INCREMENTMySQL: INT AUTO_INCREMENT → PG: SERIAL → SQLite: INTEGER PRIMARY KEY AUTOINCREMENT → Oracle: NUMBER GENERATED BY DEFAULT AS IDENTITY典型场景:自增主键在不同数据库中的写法差异
BOOLEANMySQL: TINYINT(1) → PG: BOOLEAN → SQLite: INTEGER → Oracle: NUMBER(1)典型场景:布尔类型在 MySQL/Oracle 中无原生支持
TEXTMySQL: TEXT → PG: TEXT → SQLite: TEXT → Oracle: CLOB边界 case:大文本字段在 Oracle 中需转为 CLOB
DATETIMEMySQL: 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 UNSIGNEDMySQL: BIGINT UNSIGNED → PG: NUMERIC(20) → SQLite: INTEGER → Oracle: NUMBER(20)边界 case:无符号整数在 PG/Oracle 中需用 NUMERIC 替代

常见错误对照8 个常踩的坑 · 错误 → 修复

1. 混用 MySQL 和 PostgreSQL 的布尔类型写法

错误
is_active BOOL
修复
is_active BOOLEAN  (MySQL 实际映射为 TINYINT(1);PostgreSQL 用 BOOLEAN)

MySQL 的 BOOL 是 TINYINT(1) 的别名,接受 0/1;PostgreSQL 的 BOOLEAN 接受 true/false/'t'/'f'。转换时需明确语义,否则数据迁移后查询条件失效。

2. 把 MySQL 的 TINYINT(1) 直接当布尔值迁移到 SQLite

错误
is_active TINYINT(1)
修复
is_active INTEGER CHECK(is_active IN (0,1))

SQLite 没有独立的 BOOLEAN 类型,用 INTEGER 存储 0/1。直接迁移 TINYINT(1) 虽能存储,但 SQLite 不限制值范围,可能写入 2 导致逻辑错误。加 CHECK 约束保语义。

3. Oracle NUMBER 不带精度直接转 PostgreSQL NUMERIC

错误
salary NUMBER
修复
salary NUMERIC(38,0)  (若原字段无小数)

Oracle NUMBER 默认精度 38、小数位 0。PostgreSQL NUMERIC 无参数时精度无限。直接迁移会导致 PostgreSQL 允许小数,破坏原业务约束。明确精度可保持行为一致。

4. 把 MySQL 的 DATETIME 当 TIMESTAMP 迁移到 PostgreSQL

错误
created_at TIMESTAMP
修复
created_at TIMESTAMP WITHOUT TIME ZONE

MySQL DATETIME 不涉及时区,PostgreSQL TIMESTAMP 默认 WITH TIME ZONE。转换后时间值会按 session 时区偏移,导致历史数据偏差。用 WITHOUT TIME ZONE 保留原意。

5. SQLite 的 TEXT 字段直接转 MySQL VARCHAR 不设长度

错误
description TEXT
修复
description VARCHAR(65535)  (或改用 TEXT)

SQLite TEXT 无长度限制,MySQL VARCHAR 最大 65535 字节(受行大小限制)。直接转 VARCHAR 不设长度默认 1 字符,截断数据。若字段可能超长,应改用 MySQL TEXT。

6. 忽略 MySQL 的 UNSIGNED 属性迁移到 PostgreSQL

错误
age INT UNSIGNED
修复
age INTEGER CHECK(age >= 0)

MySQL UNSIGNED 禁止负数,PostgreSQL INT 允许负数。直接迁移后可能插入 -1,破坏数据完整性。用 CHECK 约束复现原语义。

7. 把 Oracle 的 VARCHAR2(10) 直接转 MySQL CHAR(10)

错误
code CHAR(10)
修复
code VARCHAR(10)

Oracle VARCHAR2 是变长,MySQL CHAR 是定长(空格填充)。转换后查询时需 TRIM,否则 'AB' 与 'AB ' 不匹配。用 VARCHAR 保留变长行为。

8. SQLite 的 REAL 当 PostgreSQL DOUBLE PRECISION 迁移

错误
price REAL
修复
price DOUBLE PRECISION

SQLite 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 的索引结构)。映射基于各数据库官方文档的兼容性对照表。

原理图

选择源类型MySQL / PG / SQLite / Oracle选择目标类型MySQL / PG / SQLite / Oracle输入字段定义如 VARCHAR(255) / INTEGER本地类型映射内置映射表 + 规则引擎(纯前端)输出转换结果
用户输入 本地处理 输出结果

开发者集成

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'))         # bytea
package 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'));     // timestamp

常见问题

8 个高频疑问

怎么把 MySQL 的 int(11) 转成 PostgreSQL 对应的类型?直接选 MySQL 到 PG 就行吗?
在工具界面左侧选择源数据库为「MySQL」,目标数据库为「PostgreSQL」,然后在输入框粘贴 CREATE TABLE 语句或单行类型定义(如 `id int(11) NOT NULL AUTO_INCREMENT`)。工具会自动将 `int(11)` 转为 PG 的 `integer`,`AUTO_INCREMENT` 转为 `SERIAL`,`VARCHAR(255)` 转为 `character varying(255)`。注意:MySQL 的 `TINYINT(1)` 默认转为 PG 的 `boolean`(因为 MySQL 常把它当布尔用),若需保留整数类型,转换后手动改回 `smallint`。
转换后的 SQLite DDL 里没有自增字段,MySQL 的 AUTO_INCREMENT 跑哪去了?
SQLite 不支持 `AUTO_INCREMENT` 关键字,它的自增实现方式是:将整数主键声明为 `INTEGER PRIMARY KEY`,插入 NULL 时自动分配比当前最大值大 1 的值。工具转换时会把 MySQL 的 `id INT AUTO_INCREMENT PRIMARY KEY` 转为 `id INTEGER PRIMARY KEY AUTOINCREMENT`,但 `AUTOINCREMENT` 有额外行为差异——它会保证值严格递增永不重用,而 SQLite 默认行为可能重用已删除行的 rowid。如果不需要严格递增,转换后可以手动去掉 `AUTOINCREMENT`,只保留 `INTEGER PRIMARY KEY`。
为什么 Oracle 的 VARCHAR2(4000) 转换成 MySQL 后变成了 VARCHAR(4000),但 MySQL 实际最大只能到 65535 字节,这转换对吗?
转换是正确的。MySQL 的 VARCHAR 最大长度是 65535 字节(受行大小限制),而 4000 字符远低于这个上限,所以直接映射。但要注意:如果 Oracle 源表是 `VARCHAR2(4000 CHAR)`(允许存储 4000 个 Unicode 字符),MySQL 的 `VARCHAR(4000)` 默认按字符数算,当使用 utf8mb4 编码时,每个字符最多 4 字节,实际存储上限是 4000 字符 ≈ 16000 字节,仍在 65535 内。真正会出问题的是 Oracle 的 `CLOB` 或 `LONG` 类型转 MySQL——工具会转为 `LONGTEXT`,但 MySQL 的 `LONGTEXT` 有 4GB 上限,Oracle 的 CLOB 可达 8-128TB,超限时转换会报错提示。
工具转换出来的类型准不准?有没有什么类型是它处理不了的?
准确率覆盖常见类型 90% 以上,但存在三类边界情况:1)数据库专有类型(如 PostgreSQL 的 `UUID`、`JSONB`、`ARRAY`、`HSTORE`,MySQL 的 `SET`/`ENUM`)会转为最接近的通用类型(如 `UUID`→`CHAR(36)`,`JSONB`→`JSON`,`SET('a','b')`→`VARCHAR(255)`),需要手动微调。2)精度/长度修饰符差异(如 MySQL 的 `DECIMAL(10,2)` 转 SQLite 时,SQLite 原生没有精度概念,工具会保留为 `TEXT` 或 `REAL`,建议手动改用 `NUMERIC` 并加 CHECK 约束)。3)Oracle 的 `BINARY_FLOAT`/`BINARY_DOUBLE` 转 MySQL 时映射为 `FLOAT`/`DOUBLE`,但 Oracle 的浮点精度和舍入行为不同,敏感计算场景需验证。
这个工具能批量转换几十个表吗?还是只能一次处理一个字段?
支持批量处理。输入框接受完整的 CREATE TABLE 语句(可包含多字段、主键、索引、默认值、注释),也支持一次粘贴多条 CREATE 语句(用分号或空行分隔)。工具会逐条解析并转换,输出时每个表独立成段。但如果语句中包含存储过程、触发器、外键约束等 DDL 子句,工具只处理字段类型部分,这些额外结构会被原样保留在输出中但不会自动转换语法(例如 MySQL 的 `FOREIGN KEY ... REFERENCES` 转 PG 时需要改写为 `REFERENCES` 的 PG 方言,工具不会做这种跨方言语法转换)。
工具转换后的 SQL 能直接复制到目标数据库执行吗?会不会有语法错误?
转换后的 DDL 可以直接在目标数据库执行,但建议先检查三处:1)默认值表达式(如 MySQL 的 `CURRENT_TIMESTAMP` 在 PG 中可用,但在 SQLite 中需改为 `(datetime('now'))`,工具已处理此映射)。2)注释语法(MySQL 用 `COMMENT 'xxx'`,PG 用 `COMMENT ON COLUMN table.column IS 'xxx'`,工具输出两种格式的注释,执行时只保留目标数据库支持的语法)。3)索引命名(不同数据库对索引名长度限制不同,Oracle 限制 30 字符,MySQL 64 字符,PG 63 字符,工具不会截断超长名,执行时会报错,需手动缩短)。建议先在测试库执行一遍确认。
工具在浏览器里运行,我粘贴的 SQL 会泄露到服务器吗?公司敏感数据能直接用吗?
不会上传。本工具是纯前端实现(FE),所有解析和转换逻辑都在浏览器 JavaScript 中完成,粘贴的 SQL 文本不会发送到任何服务器。可以验证:打开浏览器开发者工具(F12)→ Network(网络)标签页,输入 SQL 后点击转换,应看到没有任何 HTTP 请求发出。如果仍不放心,可以在粘贴前断开网络连接(飞行模式),工具依然能正常转换。转换结果只存在于浏览器内存中,关闭标签页或刷新即清除。
工具支持 SQL Server 到 MySQL 的转换吗?简介里只写了四种数据库。
目前只支持 MySQL、PostgreSQL、SQLite、Oracle 四者之间的两两互转,不包含 SQL Server、MariaDB、DB2、Sybase 等。如果确实需要 SQL Server 到 MySQL 转换,建议先用 SQL Server 的导出工具将表结构导出为 CREATE TABLE 语句(兼容模式选「SQL 92」或「通用 SQL」),然后在本工具中选择「MySQL→PG」等任意一对,手动修正 SQL Server 特有类型(如 `NVARCHAR`→`VARCHAR`,`DATETIME2`→`TIMESTAMP`,`UNIQUEIDENTIFIER`→`CHAR(36)`)。工具未来是否支持更多数据库取决于用户反馈,可在页面底部反馈入口提交需求。
选择 打开 +新窗口 esc关闭