一、数据库命令规范所有数据库对象名称必须使用小写字母,并用下划线分隔需要用单引号括起来)数据库对象的名字应该可以看出来按名称,最后一个不应超过32个字符。临时数据库表必须以tmp_为前缀,date为后缀,备份表必须以bak_为前缀所有存储相同数据的列名和列类型必须一致(一般为关联列,如果查询时关联列类型不一致,数据类型会自动隐式转换,会导致列上的索引无效,导致查询效率降低)二、数据库基本设计规范1、所有表必须使用Innodb存储引擎。如果没有特殊要求(即Innodb不能满足的功能,如:列存储,存储空间数据等),所有表必须使用Innodb存储引擎(mysql5.5之前默认使用Myisam,而Innodb5.6后默认使用)Innodb支持事务,支持行级锁,恢复更好,高并发下性能更好2.数据库和表统一使用字符集UTF8兼容性更好,统一字符集可以避免乱码字符集转换引起的字符。不同的字符集在比较前需要进行转换,会导致索引失效。3.所有的表和字段都需要注释。使用注释子句添加表和列。备注:从一开始就维护数据字典4.尽量控制单表数据的大小。建议数据量控制在500万以内。500万不是MySQL数据库的极限。如果太大,会导致表结构修改、备份和恢复。对于大问题,可以采用历史数据归档(应用于日志数据)、分库分表(应用于业务数据)等手段来控制数据量。5.谨慎使用MySQL分区表。分区表在物理上代表了多个文件,逻辑上表现为一个精心选择分区键的表,跨分区查询效率可能较低。建议使用物理分区来管理大数据。6、尽量做到冷热数据分离,减少表的宽度。MySQL限制每个表的最大值。存储4096列,每行数据大小不能超过65535字节,减少磁盘IO,保证热数据的内存缓存命中率(表越宽,表加载到内存缓冲池时占用的内存越大,也会消耗更多的IO)更有效的利用缓存,避免读取无用的冷数据,将经常一起使用的列放在一张表中(避免更多的关联操作)7.禁止在表中创建保留字段命名字段的名称和定义很难看。保留字段无法确定存储的数据类型,因此无法选择合适的类型。保留字段类型的修改会影响表锁定8、禁止在数据库中存储图片、文件等大型二进制数据。通常文件很大,会造成短时间内数据量的急剧增加。数据库在读取数据库时,通常会进行大量的随机IO操作。当非常大时,IO操作比较耗时,一般存放在文件服务器上。数据库只存储文件地址信息。9、禁止在线进行数据库压力测试。1、优先选择满足存储需要的最小数据类型。列的字段越大,索引需要的空间就越大,因此一个页中可以存储的索引节点数也越来越少,遍历时需要的IO次数越多,索引的性能越差。方法1)将字符串转为数字类型存储,如:将IP地址转为整型数据mysql提供了两种处理ip地址的方法:inet_aton将ip转为无符号整数(4-8位)inet_ntoa将整型ip转为address在插入数据之前,先使用inet_aton将ip地址转换为整数,这样可以节省空间。显示数据时,使用inet_ntoa将整型ip地址转换成地址显示。2)对于非负数的数据(比如自增ID,整型IP),应该优先使用无符号整数进行存储,因为:无符号比有符号可以增加一倍的存储空间SIGNEDINT-2147483648~2147483647UNSIGNEDINT0~4294967295VARCHAR(N)表示字符数,而不是字节数。使用UTF8存储255个汉字Varchar(255)=765字节。过长会消耗更多的内存2.避免使用TEXT和BLOB数据类型。最常见的TEXT类型可以存储64k的数据。建议将BLOB或TEXT列分隔到单独的扩展表中。mysql内存临时表不支持TEXT、BLOB等大数据类型,如果查询中包含此类数据,则不能使用临时内存表进行排序等操作,必须使用临时磁盘表进行操作。而且对于这种数据,Mysql仍然需要进行二次查询,这会让SQL的性能很差,但是不代表一定不能使用这种数据类型。如果一定要用,建议把BLOB或TEXT列单独放到一个单独的扩展表中。查询时不要用select*,只需要取出必要的列即可。当您不需要TEXT列中的数据时,不要查询该列。TEXT或BLOB类型只能使用前缀索引,因为MySQL对索引字段的长度有限制,所以TEXT类型只能使用前缀索引,TEXT列不能有默认值。3.避免使用ENUM类型修改ENUM值。您需要使用ALTER语句。ENUM类型的ORDERBY操作效率低下,需要额外操作。禁止使用该值作为ENUM的枚举值。4.尽可能将所有列定义为NOTNULL原因:索引NULL列需要额外的空间来保存,所以占用空间较多;NULL值在比较计算时要特殊处理5.使用TIMESTAMP(4字节)或DATETIME类型(8字节)存储时间TIMESTAMP存储的时间范围为1970-01-0100:00:01~2038-01-19-03:14:07。TIMESTAMP占用4个字节,与INT相同,但比INT更具可读性。如果超出了TIMESTAMP的取值范围,则以DATETIME类型存储。人们经常使用字符串来存储日期类型的数据(错误做法):缺点一:不能使用日期函数进行计算比较缺点二:使用字符串存储日期比较占空间6.与金融相关的金额类数据必须使用小数类型非精度浮点数:float,双精度浮点数:decimalDecimal类型是精确浮点数,计算时不会丢失精度。占用空间由定义的宽度决定,每4个字节可存放9位数字,小数点占用1个字节。可用于存储大于bigint的整数数据。四、索引设计规范1、限制每张表的索引数量。建议单表使用的索引不要超过5个。越多越好!索引可以提高效率,也可以降低效率。索引可以提高查询效率,但也会降低插入和更新的效率,在某些情况下甚至会降低查询效率。因为mysql优化器在选择如何优化查询时,会根据统一的信息对各个可用的索引进行评估,生成最佳的执行计划。如果有多个索引可以同时用于查询,会增加mysql优化器生成执行计划的时间,也会降低查询性能。2、禁止为表中的每一列创建单独的索引。在5.6版本之前,一条SQL只能在一张表中使用一个索引。5.6以后,虽然有合并索引的优化方法,但是离使用联合索引的查询方法好还差得很远3.Innodb的每张表都必须有一个主键。Innodb是一个索引组织表:数据存储的逻辑顺序和索引的顺序是一样的。每个表可以有多个索引,但表只能有一个存储顺序。Innodb根据主键索引的顺序组织表。不要使用频繁更新的列作为主键,多列主键不适用(相当于联合索引)。不要使用UUID、MD5、HASH、string列作为主键(不能保证数据的顺序增长)。主键推荐使用自增ID值。5、常用索引列建议SELECT、UPDATE、DELETE语句的WHERE子句中出现的列包括ORDERBY、GROUPBY、DISTINCT中的字段,不要为匹配的列创建索引1和2中的字段。通常1和2中的字段最好建立联合索引。多表join的关联列6.如何选择索引列的顺序建立索引的目的是:希望用索引来查找数据,减少随机IO,增加查询性能,索引可以过滤读出的数据越少,从磁盘读入的数据就越少。最高区分度放在联合索引的最左边(区分度=列中不同值的个数/列中的总行数);尽量把字段长度小的列放在联合索引的最左边(因为字段长度越小,一页可以存储的数据量越大,IO性能越好);最常用的列放在联合索引的左侧(这样可以建立更少的索引)。7.避免创建冗余索引和重复索引,因为这会增加查询优化器生成执行计划的时间。重复索引示例:primarykey(id),index(id),uniqueindex(id)冗余索引示例:index(a,b,c),index(a,b),index(a)八、优先覆盖对于频繁的查询,索引优先使用覆盖索引。覆盖索引:是覆盖所有查询字段(where、select、orderyby、groupby中包含的字段)的索引。索引覆盖索引的好处:避免对Innodb索引表进行二次查询。Innodb是按照聚簇索引的顺序存储的。对于Innodb来说,二级索引存储的是叶子节点中行的主键信息。如果使用二级索引查询数据,找到对应的键值后,必须通过主键进行二级查询才能获得。我们真正需要的数据。在覆盖索引中,所有的数据都可以在二级索引的key值中获取,避免了主键的二次查询,减少IO操作,提高查询效率。可以把随机IO变成顺序IO来加快查询效率。由于覆盖索引是按照键值顺序存储的,对于IO密集型范围搜索,数据IO要比从磁盘随机读取每一行要少得多。因此,使用覆盖索引也可以在访问时将磁盘的随机读IO转化为索引查找的顺序IO。九、索引SET规范应尽量避免使用外键约束。不建议使用外键约束(foreignkey),但必须在表间关联键上建立索引;外键可以用来保证数据的引用完整性,但是建议在业务端实现;外键会影响父子表的写操作,降低性能。十。数据库SQL开发规范1、推荐使用预编译语句进行数据库操作。预编译语句可以重用这些计划,减少SQL编译所需的时间,也可以解决动态SQL带来的SQL注入问题。只传递参数,比传递SQL语句更高效同一条语句可以解析一次,多次使用,提高处理效率。2.避免数据类型的隐式转换。隐式转换会导致索引失效。如:selectname,phonefromcustomerwhereid='111';3、充分利用表已有的索引,避免使用双%号查询条件。比如像'%123%',(如果没有前导%,只有尾随%,可以使用该列上的索引)一条SQL只能使用复合索引中的一列进行范围查询,如:有一个,b列和c列的联合索引,如果查询条件中有a列的范围查询,则不会使用b列和c列的索引。在定义联合索引时,如果a列需要使用范围搜索,则需要将a列放在联合索引的右侧。使用leftjoinornotexists来优化notin操作,因为notin通常也使用索引失效。4、设计数据库时,要考虑未来的扩展。5、程序连接不同的数据库,使用不同的账号。基础系统跨库查询,为数据库迁移和分库分表留有空间,减少业务耦合,避免权限过大。6.禁止使用SELECT*必须使用SELECT
