流行的 Golang MySQL driver。
DSN
DSN 即 Data Source Name,在一些地方也称 connection string。完整格式是:
[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...¶mN=valueN]
例子见 文档。
重要参数
DSN 中可以设置各种参数。有一些参数是比较重要的,列举在这里。
字符编码及 collation
Driver 默认指定了 utf8mb4_general_ci
为 collation。另外一个选择是 utf8mb4_unicode_ci
:
utf8mb4_unicode_ci
更准确,比如如果你要使用德文字典序,那么需要用它utf8mb4_general_ci
更快,但是在一些排序上稍微不准确
至于具体用哪个:
我认为直接用 unicode_ci 好一点。因此应添加:collation=utf8mb4_unicode_ci
。
Charset 不需要指定。
时区相关
parseTime
:表示是否把 MySQL 中的DATE
DATETIME
及TIMESTAMP
列转换成time.Time
(虽然文档没有提及TIMESTAMP
会被转换,但 事实上 它是会被转换的)。默认为 false,建议改为 trueloc
:当parseTime
为 true 时起作用;会设置转换出来的time.Time
变量的时区。默认是 UTC,建议设置成与 MySQL 的 time_zone 变量一样的时区。可选的值有:- "UTC"
- "Local"(表示你的 Go 程序运行的本机时区)
- 更具体的 "Asia/Shanghai"
time_zone
:是 MySQL 的 system variable;可以设置本次连接所使用的时区:- 影响范围:
- 时区敏感的数据的存储和展示。比如
NOW()
CURTIME()
返回值的展示;TIMESTAMP
列在存储时会按time_zone
的时区转换成 UTC 存储,在读取时再转换成time_zone
的时区 DATE
TIME
DATETIME
是时区无关的,它们的存储与展示不受time_zone
变量影响;但是当他们被转换为TIMESTAMP
值时,time_zone
会起作用
- 时区敏感的数据的存储和展示。比如
time_zone=%27Asia%2FShanghai%27
等同于在 MySQL 中执行SET time_zone='Asia/Shanghai'
- 但很多 MySQL 实例默认是没有加载时区信息的(可以看系统 schema
mysql.time_zone_name
中有无行),需要运维导入一次。因此你设置时区为Asia/Shanghai
时 MySQL 可能并不认识;可以将值设置成 offset,如'+8:00'
- 影响范围:
综上所述,建议的参数汇总如下:
parseTime=true&loc=Asia%2FShanghai&time_zone=%27%2B8%3A00%27
超时控制
Driver 默认不设超时时间(无限制)。相关参数:
timeout
:建立连接时的超时时间,建议 2~5sreadTimeout
:I/O 读超时时间。视应用程序读数据量大小,建议 2~20swriteTimeout
:I/O 写超时时间。视应用程序写数据量大小,建议 2~20s
综上所述,超时控制、建议的参数汇总如下:
timeout=2s&readTimeout=2s&writeTimeout=2s
此外,还有连接池相关的参数,比如 MaxOpenConns
、MaxIdleConns
等,这些通过 Golang 的 database/sql
包的接口、或者 GORM 的参数来设置。