常规说明
数据库连接
CONN_MAX_AGE 定义数据库连接时限(ALL)
default:0 保存在每个请求结束时关闭数据库连接的历史行为。
None:保持长连接
Other:xx 单位秒
连接管理
Django连接发生在每次请求时,如果没有可用连接便主动建立连接,如果限制了连接时间的话。
警告
- 每个线程包含自己的数据库连接,数据库必须支持至少和工作线程一样多的同步连接;
- 有时出现大多数视图无法访问数据库,此时应当试图减少数据库保持连接时间,这样不会有意地维护连接,同时有助于减少数据库同步连接数;
- 开发服务器会为每个处理的连接创立新的线程,会使长连接失效;
- 当Django建立一个连接时会设置适当的参数(取决于被使用的后端),如果使能长连接,这些设置便不会在每个请求重复设置,但是如果你定义了比如连接隔离或时区,就应在每次连接断开后还原默认配置,强制写入适当的值或者禁用长连接。
编码
Django 默认假设所有数据库均采用UTF-8编码。
MySQL连接说明
版本说明
支持MySQL 5.5+,期望数据库支持UTF-8编码和事务和参照完整性。
数据库存储引擎
推荐引擎---InnoDB
MySQL数据库API驱动
MySQLdb 原生驱动已被开发支持超过10年(不支持Python3);
-
mysqlclient MySQLdb的衍生,支持Python3(Django MySQL推荐API);
mysqlclient 1.3.3+,推荐此API
-
MySQL Connector/Python 纯Python驱动(Oracle,支持Python3),无须MySQL客户端库和Python其他标准库;
MySQL connector/Python 1.1.X+
时区定义
使用Django 时区支持,mysql_tzinfo_to_sql加载时区表至MySQL数据库。
创建数据库(支持UTF-8)
SQL语句:
CREATE DATABASE <dbname> CHARACTER SET utf8;
排序规则
排序规则用于列序控制,可以设置数据库范围级别或单独表/单独列级别的排序规则,Django不提供模型设置排序,可手动修改数据库表进行修改。
默认utf-8数据库,MySQL采用utf8_general_ci排序规则(默认大小写不敏感,插入‘a’和‘A’会视为一样),如果想区分大小写,请采用utf8_bin排序规则。
utf8_general_ci 排序快有一些误差
utf8_unicode_ci 排序稍慢相对准确
连接数据库
连接设置采用优先顺序:
- OPTIONS选项
- NAME,USER,PASSWORD,HOST,PORT
- MySQL配置
# settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'OPTIONS': {
'read_default_file': '/path/to/my.cnf',
},
}
}
# my.cnf
[client]
database = NAME
user = USER
password = PASSWORD
default-character-set = utf8
设置sql_mode
STRICT_TRANS_TABLES/STRICT_ALL_TABLES
Django 强烈建议激活strict mode(此模式会将插入时的truncate警告升级为错误,以此来防止数据丢失)
隔离等级Isolation level
当运行并发负载时,数据库会处理不同的回话可能会相互影响。相互影响方式由每个回话的处理隔离等级决定。在数据库配置文件OPTIONS中设置isolation_level,有效的设置值如下:
- 'read uncommitted'
- 'read comitted'
- 'repeatable read'
- 'serializable'
- 'None'
Django 在'read committed'工作好于MySQL默认'repeatable read'。
创建表
提前设置好数据库存储引擎
表名
推荐使用小写
特殊区域注意事项
字符域
字符域默认为最大255字符,如果使用unique=True将会影响字符域。
TextField 限制
TextField不能标记为 unique=True
小数秒在Time和DataTime Field被支持
要求MySQL 5.6.4+
TIMESTAMP 列
如果数据库包含TIMESTAMP列,必须设置USE_TZ = False来避免冲突,如果你使能为True,则inspectdb会映射这些列到DateTimeField,MySQL和Django都将会尝试从UTC到local time转换这些值。
Row locking with QuerySet.select_for_update()
MySQL不支持NOWAIT和SKIP LOCKED,
故select_for_update() is used with nowait=True or skip_locked=True then a DatabaseError will be raised.