SQLite与MySQL的语法差异有哪些?常用SQL语句对比总结

来源:HTML教程作者:沙月恵奈‌头衔:网络博主
导读:本期聚焦于沙月恵奈‌创作的《SQLite与MySQL的语法差异有哪些?常用SQL语句对比总结》,敬请观看详情。SQLite和MySQL是使用最广泛的两款关系型数据库,很多SQL语句在两者中写法并不一样。本文从数据类型、建表语句、自增主键、分页查询、日期函数、字符串拼接、 Upsert写法等实际场景出发,系统梳理两款数据库的语法差异,并给出可直接运行的对比示例,帮助你避免在项目迁移或切换数据库时踩坑,快速掌握两者在SQL层面的核心区别与各自的写法习惯。

SQLite和MySQL都是市面上使用极其广泛的关系型数据库,前者轻量、零配置、单文件存储,常用于移动端、嵌入式和小型工具;后者是成熟的服务型数据库,广泛部署在Web后端。虽然两者都支持标准SQL,但在实际写SQL的过程中,你会发现不少语句在一个数据库能跑,换到另一个就报错。这些差异主要集中在数据类型、自增主键、Upsert、日期处理、字符串拼接和分页等地方。本文把这些常见差异逐一整理出来,方便你在数据库迁移或双端兼容开发时快速查阅。

SQLite与MySQL的语法差异有哪些?常用SQL语句对比总结

数据类型与建表语句的差异

MySQL是强类型数据库,建表时必须明确指定每个字段的类型和长度,比如VARCHAR(255)、INT、DECIMAL(10,2)等,写错了直接报错。而SQLite采用的是动态类型系统,字段类型只有五大存储类别:NULL、INTEGER、REAL、TEXT和BLOB,你甚至可以写一个MySQL里的类型名,SQLite也只会按亲和性去映射,不会报错。

一个很典型的区别是布尔值。MySQL有TINYINT(1)表示布尔,SQLite则直接接受BOOLEAN关键字,但底层存储仍是INTEGER,true存为1,false存为0。另外MySQL里常用的ENUM枚举类型、UNSIGNED无符号修饰符,在SQLite里都不存在,需要用TEXT加CHECK约束来模拟。

-- MySQL 建表
CREATE TABLE users (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    status ENUM('active', 'disabled') DEFAULT 'active',
    balance DECIMAL(10,2) DEFAULT 0.00
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- SQLite 建表
CREATE TABLE users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    status TEXT DEFAULT 'active' CHECK (status IN ('active', 'disabled')),
    balance REAL DEFAULT 0.0
);

自增主键的写法完全不同

自增主键是两者差异最大的地方之一。MySQL使用AUTO_INCREMENT关键字,且该字段必须是主键或唯一索引,插入时可以显式传NULL让数据库自动分配。SQLite则用AUTOINCREMENT关键字,但有个前提:字段类型必须写成INTEGER PRIMARY KEY,而且INTEGER这个拼写不能换成INT,否则AUTOINCREMENT不生效。

更细的区别在于行为语义。MySQL的自增计数在数据库重启后可能被重置为最大值加一,而SQLite的AUTOINCREMENT会通过内部表sqlite_sequence记录历史最大值,保证主键严格递增、不复用已删除的最大ID。如果只是INTEGER PRIMARY KEY而不加AUTOINCREMENT,SQLite在删除最大ID后可能会复用该值,这点在设计有外键关联的表时要格外注意。

另外获取刚插入的自增ID的方式也不同:MySQL用LAST_INSERT_ID()函数,SQLite用last_insert_rowid(),两者的会话隔离行为类似,都只返回当前连接最后一次插入的行ID。

分页、Upsert与插入语法的区别

分页查询方面两者基本一致,都用LIMIT加OFFSET,MySQL还支持简写形式LIMIT 20, 10,表示跳过20条取10条,SQLite同样支持这种逗号写法,这是少数高度兼容的地方。

真正容易踩坑的是Upsert(存在则更新,不存在则插入)。MySQL使用ON DUPLICATE KEY UPDATE语法,依赖主键或唯一索引冲突;SQLite则使用ON CONFLICT子句,写法借鉴了PostgreSQL,需要在子句里明确指定冲突的字段。两者的插入忽略写法也不同,MySQL用INSERT IGNORE,SQLite用INSERT OR IGNORE。

-- MySQL 的 Upsert
INSERT INTO stock (sku, qty) VALUES ('A100', 5)
ON DUPLICATE KEY UPDATE qty = qty + 5;

-- SQLite 的 Upsert(3.24.0 以上版本)
INSERT INTO stock (sku, qty) VALUES ('A100', 5)
ON CONFLICT(sku) DO UPDATE SET qty = qty + 5;

-- SQLite 的插入忽略
INSERT OR IGNORE INTO stock (sku, qty) VALUES ('A100', 5);

还有一个细节:MySQL支持INSERT INTO t SET col1=1, col2=2这种SET风格的插入写法,SQLite不支持,只接受标准的VALUES形式或多行批量插入。

函数与日常查询的差异

字符串拼接是最常见的差异点。MySQL默认使用CONCAT函数,比如CONCAT(a, '-', b);SQLite没有CONCAT,只能用双竖线运算符,写成a || '-' || b。如果SQL里大量用了CONCAT,迁移到SQLite时必须全部改写,或者自己注册自定义函数。

日期时间函数的差异更大。MySQL有NOW()、CURDATE()、DATE_FORMAT()、DATEDIFF()等一整套函数;SQLite则只有少数几个核心函数:date()、time()、datetime()、strftime()和julianday()。格式化日期时MySQL用DATE_FORMAT(created_at, '%Y-%m-%d'),SQLite要用strftime('%Y-%m-%d', created_at),虽然格式符看起来像,但函数名完全不同。计算时间差时,MySQL用DATEDIFF返回天数,SQLite要用julianday做减法再处理。

-- 当前时间
SELECT NOW();                          -- MySQL
SELECT datetime('now', 'localtime');   -- SQLite

-- 格式化日期
SELECT DATE_FORMAT(created_at, '%Y-%m-%d') FROM orders;       -- MySQL
SELECT strftime('%Y-%m-%d', created_at) FROM orders;          -- SQLite

-- 两个日期相差天数
SELECT DATEDIFF('2024-06-01', '2024-05-01');                            -- MySQL
SELECT CAST(julianday('2024-06-01') - julianday('2024-05-01') AS INT);  -- SQLite

其他函数差异还包括:字符串截取MySQL用SUBSTRING或SUBSTR,SQLite只有SUBSTR;判断空值两者都有IFNULL,但MySQL的IF()函数在SQLite里要用CASE WHEN替代;类型转换MySQL用CAST也支持隐式转换较多,SQLite主要靠CAST且行为更严格。另外SQLite默认不区分大小写的比较只对ASCII字母有效,中文场景下的模糊查询行为也需要额外验证。

迁移与兼容性建议

如果你在做一个需要同时支持两种数据库的项目,建议尽量写标准SQL,避开各家方言:分页统一用LIMIT和OFFSET,条件判断统一用CASE WHEN,字符串拼接可以考虑在应用层完成而不依赖数据库函数。自增主键的建表语句可以放在各自的迁移脚本里分开维护。

需要特别提醒的是SQL注释里的风险点:MySQL支持#开头的单行注释,SQLite不支持,会把#当成语法错误。导出MySQL的SQL脚本导入SQLite前,除了改写ENGINE、CHARSET等子句,还要记得处理注释格式和反引号包裹的标识符,SQLite虽然能兼容大部分反引号写法,但建议统一改成双引号或直接去掉,兼容性更稳妥。掌握这些差异点后,在两款数据库之间切换或迁移就会顺畅很多。

SQLiteMySQLSQL语法差异修改时间:2026-09-12 16:22:36

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260912/55417.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。