14. 2.5 字段上添加函数使用规范 基本原则: 禁止在 WHERE 条件中出现的过滤字段上,使用任何函数进行类型或格式的转换;正确的做法是把传入比较的值转换为列类型所需要的。 错误的写法: SELECT username FROM gl_user WHERE DATE_FORMAT(gmt_create, '%Y%m%d%H%i%s')='20090501022300‘; 正确的写法: SELECT username FROM gl_user WHERE gmt_create=DATE_FORMAT('20090501022300', '%Y-%m-%d %H:%i:s');
15. 2.6 表连接规范 基本原则: 所有非外连接SQL(即INNER JOIN),请把关联表统一写到 FROM字句中,关联条件与过滤条件统一写到WHERE字句中. 出于代码的可读性原因,所有外连接SQL语句中,请一律使用LEFT JOIN,禁用RIGHT JOIN。 另外,请注意LEFT JOIN字句中,右边位置表的条件书写位置不同的影响: SELECT A.rolename,A.gmt_create,B.nickname FROM gl_role A LEFT JOIN gl_roledetail B ON A.ID=B.roleidAND B.roleID=2; +-------------+---------------------+----------+ | rolename | gmt_create | nickname | +-------------+---------------------+----------+ | 163.com | 0000-00-00 00:00:00 | test2 | | sina.com | 0000-00-00 00:00:00 | NULL | | hotmail.com | 0000-00-00 00:00:00 | NULL | | 126.com | 2009-08-20 18:20:18 | NULL | +-------------+---------------------+----------+ SELECT A.rolename,A.gmt_create,B.nickname FROM gl_role A LEFT JOIN gl_roledetail B ON A.ID=B.roleidWHERE B.roleID=2; +----------+---------------------+----------+ | rolename | gmt_create | nickname | +----------+---------------------+----------+ | 163.com | 0000-00-00 00:00:00 | test2 | +----------+---------------------+----------+
16. 2.7 分页查询规范 基本原则: 分页查询语句全部都需要带有排序条件,除非商业方明确要求不要使用任何排序来随机展示数据。详细说明: 1> 常规分页语句写法(start:起始记录数,page_offset:每页记录数): SELECT ID,username FROM gl_user WHERE username like '%@163.com' ORDER BY M.gmt_create LIMIT start, page_offset; 2> 多表 Join 的分页语句,如果过滤条件在单个表上,需要先分页,再 Join: 低性能写法: SELECT M.username,P.rolename FROM gl_user M INNER JOIN gl_role P ON M.ID=P.userid WHERE username like '%@163.com' ORDER BY M.gmt_create LIMIT start, page_offset; 高性能写法: SELECT M.username,P.rolename FROM (SELECT ID,username FROM gl_user WHERE username like '%@163.com' ORDER BY M.gmt_create LIMIT start, page_offset)M,gl_role P WHERE M.ID=P.userid; 这样写的前提是关联的表之间记录一一对应,否则可能会返回的记录数目少于或多于page_offset的值。
21. 7.MySQL使用建议 1>. 进行数据库结构设计的时候,考虑适当的冗余,尽量确保应用读写数据的SQL简洁. 2>. 所有字符集为utf8,校对规则为utf8_general_ci ,默认是不区分英文字母大小写,若有需求 区分大小写,请跟DBA特别声明,或者表定义语句指定 COLLATE ‘utf8_bin’. 3>.尽量不需要使用子查询,特别是IN的方式,可考虑转化为EXISTS. SELECT * FROM A WHRE A.ColName1 IN (SELECT DISTINCT ID FROM B WHERE ..); 建议改写为: SELECT * FROM A WHRE EXISTS (SELECT 1 FROM B WHERE B.ID= A.ColName1...); 4> 要返回MySQL自增序列的ID值,可以考虑使用函数LAST_INSERT_ID(),此函数只能返回同 一个SESSION最近一次对有AUTO_INCREMENT属性表INSERT的ID值. 5> 所有的时间字段值,请以MySQL数据库的时钟为准,除用户输入的时间值外. 6> 对于项目的数据量、PV等合理评估,我们DBATEAM相关人员,会给大家推荐合理成熟的数 据存取架构,增强系统的扩展性与用户体验,以及高可用性等.