很多草根站长建站时都有过这样的纠结:数据库到底选 MySQL 还是 SQLite?网上教程默认让你装 MySQL,可个人博客这种低流量小站,动辄占用一两百 MB 内存的 MySQL 似乎又有点大材小用;而 SQLite 轻量是轻量,又怕它撑不住访问、功能不够用。这篇文章不吹不黑,从部署维护、性能、并发、备份迁移几个维度把两种数据库摆在一起对比,再给出不同场景下的选型建议,最后附上 SQLite 迁移到 MySQL 的实战步骤,帮你一次想明白。
两种数据库的本质区别
先搞清楚底层逻辑。MySQL 是典型的客户端-服务端架构:一个独立运行的数据库服务进程,监听端口(默认 3306),应用通过网络连接它读写数据。SQLite 则完全不同,它是个嵌入式数据库,没有独立的服务进程,数据库就是一个普通文件(比如 site.db),应用直接读写这个文件。这个本质差异决定了后面所有的优缺点。
正因为 MySQL 是独立服务,它可以同时接受多个应用的连接、支持细粒度的权限管理、支持网络远程访问,也正因为如此,它需要常驻内存、需要配置账号、需要监控进程是否存活。SQLite 则是"文件即数据库",零配置、零守护进程,应用进程退出它就不占用任何资源。
SQLite 的优势与局限
SQLite 的优势非常明显:第一,零配置零维护,不需要安装服务、不需要设置密码、不需要调参数,数据库文件拷走就是备份;第二,资源占用几乎可以忽略,不占端口不占常驻内存,非常适合 512MB 甚至 256MB 内存的低配云服务器;第三,单文件特性让备份和迁移极其简单,直接把 .db 文件复制一份就完成了备份;第四,读性能相当优秀,纯读场景下 SQLite 往往比 MySQL 还快,因为它省掉了网络通信和进程间开销。
但 SQLite 的局限也很清楚:第一,写并发能力弱,同一时刻只允许一个进程写数据库,多个进程同时写入会报 database is locked 错误,高并发写入场景直接出局;第二,不适合多应用共享,文件锁机制决定了它不适合被多个不同的服务同时访问;第三,远程访问麻烦,数据库是本地文件,跨服务器访问需要先把文件同步过去;第四,部分高级功能缺失,比如没有完善的用户权限体系,某些复杂的 ALTER TABLE 操作支持有限。
MySQL 的优势与局限
MySQL 的优势在于它是"正规军":第一,成熟的并发模型,基于连接和锁机制,支持高并发读写,扛得住几十上百的并发访问;第二,完善的权限体系,可以给不同应用分配不同账号和库表权限,安全性好;第三,生态极其庞大,主从复制、读写分离、全文索引、各种备份工具(mysqldump、Xtrabackup)都是现成的;第四,网上资料最多,遇到问题随便一搜就有答案,这对个人站长来说是很实在的优势。
MySQL 的局限在于"重":安装部署比 SQLite 复杂,需要初始化数据目录、创建账号、配置字符集;常驻内存,即便空闲状态也要占用 100MB 以上的内存,低配服务器上还得专门调优;备份恢复相对繁琐,逻辑备份用 mysqldump,物理备份要考虑数据目录一致性,新手容易在恢复环节翻车。
什么场景该选 SQLite
如果你是个人博客、访问量每天几百到几千,评论和文章读多写少,SQLite 完全够用,而且会让你省心很多。Typecho 官方就支持 SQLite 存储,WordPress 也有 SQLite 集成方案。具体来说,以下几类站点优先考虑 SQLite:日访问量低于一万的博客和内容站;没有高并发写入需求的工具站、导航站;跑在 512MB 以下低配服务器上的站点;对数据迁移灵活性要求高的场景,比如静态站生成器的本地数据层。
我自己测试过,一个日 PV 两三千的 Typecho 博客跑在 SQLite 上,页面响应速度和 MySQL 版本没有任何可感知的差异,而服务器内存占用却省下了将近 150MB,后台响应也更跟手。对个人站来说,这 150MB 内存可能就是能否再跑一个服务的分水岭。
什么场景该选 MySQL
反过来,以下几类情况老老实实用 MySQL:网站要接入电商、论坛、社区这类读写频繁、并发要求高的系统;同一个数据库要同时服务多个应用或子站;有明确的权限隔离需求,要给不同程序开不同账号;网站已经上了 CDN 或反代,流量可能快速增长,需要预留并发余量;未来大概率要做数据统计分析、需要复杂查询和索引优化。另外,如果你用的是宝塔面板这类集成环境,MySQL 是一键装的,安装成本被大幅摊薄,选 MySQL 的顾虑又少了一层。
从 SQLite 迁移到 MySQL 的实战步骤
万一你当初选了 SQLite,后来站点长大需要迁移到 MySQL,流程也不复杂,用现成工具就行。以 Typecho 为例:先在后台用插件把数据导出为 SQL 文件,或者直接用命令行工具转换。通用的转换思路是,先用 sqlite3 把表结构和数据导出:
sqlite3 site.db .dump > site.sql导出的 SQL 文件里有些 SQLite 特有的语法(比如 AUTOINCREMENT、双引号字符串字面量),直接喂给 MySQL 会报错。稳妥的做法是用现成的转换工具,比如 Python 的 sqlite3-to-mysql 脚本,它会自动处理类型映射和语法差异。转换完成后,在 MySQL 里建好同名数据库和账号,导入:
mysql -u 用户名 -p 数据库名 < site_converted.sql然后修改站点配置文件的数据库连接信息,重启 PHP-FPM,再逐页检查评论、分类、标签是否正常。注意迁移后要在 MySQL 端重建索引和自增主键,SQLite 的 rowid 体系与 MySQL 的 AUTO_INCREMENT 不是一一对应的,漏了这一步可能出现新数据 ID 冲突。
个人站长的选型建议
综合来看,给个人站长的建议可以浓缩成一句话:纯内容站、低配服务器、读多写少,选 SQLite;要跑论坛商城、要接多应用、流量看涨,选 MySQL。如果实在拿不准,还有一个折中方案:先用 SQLite 把站点跑起来,架构上留好数据库抽象层,将来流量上去了再迁移 MySQL,SQLite 到 MySQL 是单向平滑的,成本完全可控。数据库选型从来不是越强越好,而是越合适越好,把资源花在内容和运维上,比纠结数据库本身更值得。
常见问题
问:SQLite 的 database is locked 错误怎么解决?答:这通常发生在多个进程同时写库时。检查是否有多个 PHP-FPM 进程或定时任务在同时写同一个库;把 busy_timeout 调大一点可以缓解,但从根本上要避免并发写。
问:SQLite 数据库文件会无限变大吗?答:不会,但删除数据后文件大小不会自动收缩,需要执行 VACUUM 命令回收空间,建议配合定时任务每月跑一次。
问:SQLite 支持事务吗?答:支持,而且 SQLite 的事务机制很成熟,单库写操作具备原子性、一致性、隔离性、持久性保障,日常小站场景完全够用。
问:迁移到 MySQL 后网站变慢了是怎么回事?答:大概率是没建索引。SQLite 里某些隐式索引在迁移过程中丢失,对照原表结构在 MySQL 里重新创建索引,特别是主键、外键和常用查询字段。
总结
SQLite 和 MySQL 不是谁替代谁的关系,而是各有所长的两条路线。选型的核心依据是网站的访问模式、服务器配置和未来预期:低配小站用 SQLite 把资源省下来,成长中的站点用 MySQL 把余量留出来。无论选哪个,记得做好备份——数据库文件再小,也是你辛苦写下的内容,丢不起。希望这篇文章能帮你在数据库选型上少走弯路。