4. 命名规范
SQL 语句中,
? 保留字使用全大写
? 字符串使用单引号(')
-- 正确
SELECT id, title FROM xiaoqu WHERE id = 1
SELECT id, title FROM xiaoqu WHERE areacode = '000100010001'
-- 错误
select ID, title from XiaoQu where id = 1
SELECT id, title FROM xiaoqu WHERE areacode = "000100010001"
5. 表的设计
MySQL 存储引擎使用 InnoDB
不用纠结,没有特殊原因的情况下,作为 OLTP 的 MySQL 使用 InnoDB 引擎。
字符集使用 UTF-8
Charset 为 utf8;Collation 为 utf8_general_ci。
正确使用时间类型
MySQL 应当正确设置 time_zone。
? 精确到秒的时间采用 TIMESTAMP
? 精确到日期使用 DATE
? 一般不使用 DATETIME 类型
? 不允许使用字符串类型存储时间
6. 表的设计
字段定义为 NOT NULL
真的需要 NULL 值吗?如果不确定,就将字段设置为 NOT NULL。
字段设置 DEFAULT 值
设置为 NOT NULL 的字段,需要设置一个缺省值。
不使用浮点类型(FLOAT、DOUBLE)
没有充分的理由,不要使用浮点数。
例如金额可以用分为单位,然后采用 INT。如果依然要以元为单位,可以采用
DECIMAL。
8. 表的设计
当要查询某段的 IP 时,请参考以下示例:
SELECT user_id FROM user_ip
WHERE ip > INET_ATON('192.168.0.0') AND ip < INET_ATON('192.168.255.255')
当程序使用自带的函数进行 IP 地址的字符串形式与数字形式之间的转换时,需要
注意数字的存储类型至少应为 32 位的无符号整型(如 uint32_t),并注意字节顺。
12. SQL 语句
-- 禁止
SELECT id FROM property WHERE CHAR_LENGTH(title) > 20
-- 假设字段 property.status 的类型为 TINYINT
-- 禁止
SELECT id FROM property WHERE status = '1'
-- 改为
SELECT id FROM property WHERE status = 1
13. SQL 语句
禁止隐式类型转换
不仅在查询条件中禁止隐示类型转换,INSERT,UPDATE 也不允许隐式类型转换。
-- 假设字段 property.status 的类型为 TINYINT
-- 禁止
INSERT INTO property (..., status) VALUES (..., '1')
UPDATE property SET status = '1' WHERE id = '43'
-- 改为
INSERT INTO property (..., status) VALUES (..., 1)
UPDATE property SET status = 1 WHERE id = 43
14. SQL 语句
禁止使用 % 前导查询
尽量不使用 LIKE 查询,不得不用的情况下也禁止使用 % 前导查询。
-- 禁止
SELECT id FROM property WHERE title LIKE '%最%‘
不使用联表查询
OLTP 不使用 JOIN 联合查询。
不使用子查询
没有特别好的理由,OLTP 不允许使用子查询。
16. SQL 语句
LIMIT m, n,其中 m 应当小于 500
使用 SELECT ... LIMIT offset, row_count 或者 SELECT ... LIMIT row_count OFFSET offset
时,当 offset 小于 500 时,允许使用。
-- 允许
SELECT ... FROM property WHERE broker_id=? ORDER BY update_time LIMIT 40, 20
-- 不允许
SELECT ... FROM property WHERE areacode=? ORDER BY update_time LIMIT 4000, 20
17. SQL 语句
能够不使用 offset 的情况应当避免,如下面的例子(其中 id 是主键),
-- 建议
SELECT ... FROM property WHERE broker_id=? AND id>? ORDER BY id LIMIT 20
-- 避免
SELECT ... FROM property WHERE broker_id=? ORDER BY id LIMIT 40, 20
18. SQL 语句
避免使用 COUNT() 函数
能不使用就不使用,尽量用其他方法来解决。
例如判断经纪人是否有房源,可以不使用 COUNT() 函数,
-- 正确
SELECT 1 FROM propertys WHERE broker_id=? LIMIT 1
-- 错误
SELECT COUNT(*) FROM propertys WHERE broker_id=?
19. SQL 语句
一次 COUNT() 可能扫描的行数应当确保小于 500 行
COUNT() 函数需要扫描所有的结果集之后才能得出结果。而结果集的大小需要业
务知识来判断(EXPLAIN 方法只能来来检验某一个条件下的当前情况)。因此需
要使用 COUNT() 查询的代码应当经过审阅。
-- 允许。审阅。经纪人的房源数不允许超过 200 套
SELECT COUNT(*) FROM property WHERE broker_id=?
-- 不允许。一个区域板块下的房源数量不定,可能非常多
SELECT COUNT(*) FROM property WHERE areacode=?
其他聚合函数,例如 SUM()、AVG()、MAX() 等,同样适用。