Django 对 Sqlite、Mysql、Postgresql 三种数据库支持小结

三种数据库各有优劣,需要根据自己的情况来选择。比如 Sqlite 不支持并发,那显然不能用来作为大型网站的数据库,而 Mysql 在 Django 3.1 版本之前并不支持 JSONField,如果 JSONField 必须要用到那肯定也是不能选的,而 Postgresql 特性齐全,但是往往用的人比较少,难以获得足够的资料。

因此,在这里记录一下各个数据库的注意事项,方便以后的选择。等等!官方不还支持 Oracle 数据库吗,怎么没说?这数据库我真没用过,而且可见的将来都用不到,目前就不管了。

Sqlite

Sqlite 无法并发写入,但是能并发读取,因此适合用作读多写(并发写入)少的场景,更常见的用处是用作开发用的测试数据库。当然有时候无法完全模拟生产环境,还是会换到其他数据库的。主要有以下特点:

  1. 数据库字串的匹配不区分大小写,像 filter(name__contains="aa") 这样的子句会匹配到 "Aabb"。
  2. 含有 ASCII 码以外字符的字符串匹配一定区分大小写,即使你传入了不区分大小写参数。
  3. Sqlite 内部没有小数类型,因此小数的舍入会有问题。
  4. 不支持 SELECT ... FOR UPDATE 语法
  5. 使用原始查询时不支持参数以字典形式传入并用 '%(name)s' 格式化,必须传入以列表形式传入。
  6. 使用 QuerySet 迭代查询结果并修改时,会进入薛定谔的数据库状态,Sqlite 无法保证会发生什么,可能成功也可能失败,取决于数据库版本、运行时的状态等,无法预期确定的结果。
  7. 支持 JSONField,但 Python 自带的 Sqlite 库需要启用 JSON1 扩展。

Mysql

对于 Mysql 有个同源的发行版 MariaDB,目前 Django 支持 MariaDB 仅支持 10.2 及以上版本。并非是因为之前版本有什么兼容性问题,主要是由于上游对于 10.2 之前版本的安全更新支持到期了,所以 Django 也就放弃支持了,需要的话酌情使用。而 Mysql 的话支持 5.6 及以上版本,5.7 和 5.6 的新版本可以开启严格模式,有更好的事务隔离性。

Mysql 旧版本一直是使用 MyISAM 储存引擎,它的缺点应该广为人知了,不支持事务和也不执行外键约束。而使用 InnoDB 就没有这两个问题了,但是需要注意 InnoDB 的自动增量计数器在 MySQL 重启时会丢失,直到 Mysql 8.0 才修复。Django 生成数据库架构的时候没有设置储存引擎,如果数据库默认配置不正确,需要手动设置为 InnoDB。此外,开启时区后,Django 会在数据库中创建一个 mysql_tzinfo_to_sql 表。

Mysql 还有要特别注意的是创建数据库时要使用 utf-8 字符集,同时字符序默认为 utf8_general_ci,比 utf8_unicode_ci 更快,但准确率略低(如德语字典顺序不对),并且数据库不区分大小写。另外,当在某些条件下执行某些 SQL 语句时,可能会导致表名的大小写被改变,建议使用全小写的表名以避免发生问题。其他的主要特点有:

  1. Django 推荐使用比 Mysql 默认更高的隔离级别,否则 get_or_create() 可能会引发一个 IntegrityError
  2. Django 生成数据库架构的时候没有设置储存引擎,如果数据库默认配置不正确,需要手动设置为 InnoDB。
  3. MyISAM 储存引擎不支持保存点。
  4. 如果 varchar 字段使用了 unique=Truemax_length 可能被限制在 255 个字符
  5. 只能对 BLOB 或 TEXT 列的前 N 个字符进行索引,并且 TextField 没有定义的长度,所以不能用 unique=True。
  6. 5.6.4 后支持小数秒,但是必须在列定义中包含(例如 DATETIME(6))。
  7. inspectdb 导出模型包含 TIMESTAMP 列的旧数据库时,必须设置 USE_TZ = False
  8. SELECT ... FOR UPDATE 的某些选项不支持,同时 select_for_update() 过滤时必须选择有唯一约束或索引的列,否则这个操作会独占整个表的写入锁。
  9. 对字符串字段进行证书查询时,Django 会把数字转为字符串,否则有奇怪的结果。

Postgresql

Django 支持 Postgresql 9.5 及以上版本,同时 Django 对 Postgresql 的支持几乎是最好的,这很大程度上由于 Postgresql 的先进性和规范性,结果就是你在 Django 上使用 Postgresql 时几乎不会遇到什么离奇的问题,官方文档中几乎没有什么关于 Postgresql 需要特别注意的事项。

而且 Postgresql 的 jsonbpostgis等各种独有索引和数据类型支持绝对的功能强大。除了对 Postgresql 不熟,中文资料较少外,没什么劣势,有条件必然是选择 Postgresql。

总结

看情况,保证自己能解决遇到的问题,爱用什么用什么,当然对于个人使用 Django 必然首推 Postgresql。

posted @ 2021-01-23 13:54  Veoco  阅读(539)  评论(0编辑  收藏  举报