数据库设计规范

1、数据库设计规范(设计之初,须要DBA介入)mysql

规范前言:redis

1.保证数据库高可用:制定3重高可用(容灾)架构,主备架构、同城容灾、异地容灾(能够采用mha、pxc等高可用架构,注意数据可能丢失风险)sql

2.根据业务了解热点数据:制定相应热点数据是否须要redis等缓存,来减小直接对数据库访问的请求,以及根据不一样状况制定相应的redis与mysql的数据同步机制,若是选择redis,则可采用哨兵或cluster高可用架构数据库

3.根据业务了解数据分布及读写状况:制定是否须要分库分表及读写分离,以及此策略对应采用哪一种中间件缓存

4.根据业务了解数据分析对应数据需求:制定是否须要采用不影响生产库性能的同时,经过binlog进行实时同步数据来作数据分析服务器

5.根据业务对数据保留需求:制定相应的备份策略,并制定按期备份验证策略架构

6.根据业务了解活跃dml相关表:制定按期整理分析表策略并发

7.根据业务了解大表数据留存需求:制定历史数据的清理机制数据库设计

8.部署夜鹰:对数据库服务器进行合理监控,能够采用zabbix、pmm、openfalcon等监控工具函数

9.不在数据库作运算:cpu计算移至业务层

10.控制单表数据量:单表记录控制在1000w

11.控制列数量:字段数控制在20之内

12.平衡范式与反范式:为提升效率牺牲范式设计,冗余数据

13.拒绝3B:拒绝大sql,大事物,大批量




表设计规范:

1.库名、表名、字段名尽可能使用小写字母,"_"分割。

2.库名、表名、字段名尽可能不超过26个字符。

3.库名、表名、字段名见名知其意,建议使用名词而不是动词。

4.非惟一索引按照“idx_表简写_字段简写”命名。

5.惟一索引必须按照“uniq_表简写_字段简写”命名。

7.每张表及每一个字段必须有注释。

8.mysql建议使用innodb为默认存储引擎,建表采用默认存储引擎便可。

9.字符集建议默认采用utf8或utf8mb4(mysql5.7),表使用默认字符集便可。

10.innodb表必定要有主键,在不分库分表的状况下,不要使用有实际意义的字段作主键,且随机主键索引,插入致使大量的页面分割,建议使用自增id,尽可能不要使用联合主键,长主键索引使全部相应的二级索引变得更长、更慢(注意:主键创建聚簇索引、主键不该该被修改、字符串不该该作主键、若是不指定主键,innodb会使用惟一且非空值索引代替)。

固然,若是一个字段有助于在各个方面的数据分组或者这个字段被频繁的在查询中使用,能够做为主键。

11.建议不要采用外键,尽可能程序端实现其逻辑来保证约束。

12.存储精确数值必须使用decimal,禁止使用float和double。

13.建议使用unsigned存储非负数值。

14.整形定义中不添加长度,如int,而不是int(8)

15.varchar(n),n表示的是字符数而不是字节数,如varchar(100),能够最大存储100个汉字,须要根据实际须要的宽度来选择n。

16.存储日期建议使用date、DATETIME类型。

17.须要 join 的字段,数据类型两边保持绝对一致。 不一致会有隐式转换的风险。

18.尽可能的了解数据类型,会运算的能用int的不用string,即使如此,也要选择合适的int类型达到更快的查询或运算。

19.在设计时建议包含两个日期字段:created_time(建立日期),updated_time(修改日期)且非空。

20.尽量使用简单数据类型,不要使用如blob、clob、long等大字段类型。

21.不容许字段默认null,能够采用如0、一、""等


字段类型设计规范:

1.用好数值类型,最小化规则

tinyint(1Byte)、smallint(2Byte)、mediumint(3Byte)、int(4Byte)、bigint(8Byte)

不该该采用的用法:int(1)/int(11)

2.字符转化为数字

用int而不是char(15)存储ip

3.优先使用enum或set

如:`sex` enum (‘F’, ‘M’)

4.避免使用NULL字段

NULL字段很难查询优化、NULL字段的索引须要额外空间、NULL字段的复合索引无效

错误如:`name` char(32) default null

正确如:`age` int not null default 0

5.少用text/blob

varchar的性能会比text高不少,实在避免不了blob,请拆表

6.不在数据库里存图片,应使用专门的图片处理方式



索引设计规范:(索引是一把双刃剑,谨慎合理使用索引,索引改善查询、减慢更新,索引必定不是越多越好,能不加就不加,要加的必定得加,要衡量好索引带来的收益与损耗)

1.只使用普通索引或惟一索引,其余须要DBA参与衡量,如一些字符字段建前缀索引。

2.索引名称必须使用小写

3.非惟一索引按照“idx_表简写_字段简写”命名。

4.惟一索引必须按照“uniq_表简写_字段简写”命名。

5.索引中的字段数建议不要超过5个,索引是昂贵的,更新索引经常是数据库写操做的主要开销,为关键性能查询集创建索引,总体取审视,而不是一个个看,最好全部的查询条件和联表条件都使用索引(起码区分度最高的部分是)。

6.修改索引时,切记验证对性能的影响。

7.不要建立冗余或者无效的索引,如(a),(a,b)建立索引属于重复索引。

8.多数状况下,联合索引比添加一个新的索引要好,固然要衡量利弊,作出取舍,注意:创建联合索引要按能支持更多查询的顺序创建索引,把全部都是点查询的字段放到索引的首位,

9.在联合索引中,MySQL在遇到返回查询(<,>,BETWEEN)条件时,将中止停止剩余部分索引的使用;可是使用IN(…)的范围查询则能够继续往右使用索引。

10.尽可能使用索引进行排序,不使用索引将进行很是昂贵的filesort操做(external sort),经常使用联合索引进行高效排序(注意:不能对两个字段进行不一样顺序的排序,对非ORDER BY部分的字段只能使用点查询(=),IN()也不行)。

11.索引能够帮助优化 MIN()/MAX() 这类的统计函数,如:SELECT MAX(ID) FROM tab;使用key(a)

SELECT MAX(b) FROM tab GROUP BY a;使用KEY(a,b)

12.MySQL使用嵌套循环(Nested Loops)进行联表查询(小结果集驱动大的结果集),使每一个关联的表(关联字段)都使用上索引显得很是的重要,小表(驱动表)关联字段索引多是没必要要的,但大表(被驱动表)关联字段索引是必要的。

13.不要建立过多的索引,尽可能不要添加非性能关键查询的索引,太多的索引会使MYSQL慢下来,如一个表超过10个以上索引,可能会影响dml的性能(5%左右),一些状况会致使应用程序相应dml很是慢。

14.不在索引作列运算。

15.常见的不合适的索引:

a.过于理想,索引过宽,致使索引维护代价高,并发dml高了以后会出现性能抖动。

b.索引筛选性不强,走上索引也不够快,并发高了以后对db冲击很大。

c.并非全部索引都比全表扫描快,若是获取的数据超过30%,则不走索引,若是超过20%,则可能走全表更好。


sql开发规范:

1.在代码中不容许出现任何ddl语句,ddl统一由dba执行。

2.除非特殊状况,sql语句必定要加上where条件或limit。

3.不容许写select * from 这样的代码,必定要指定须要的字段,来减小无用数据的查询请求(消耗多余cpu,io,内存,带宽)。

4.慎用count(*),如大概查看表数据量,能够经过统计信息查看,如查具体,能够采用count(主键id)。

5.尽可能避免在where子句中对字段使用函数或表达式,且字段的值必定要与字段类型匹配,不然会致使索引失效。

6.有表链接时,设计的时候要尽可能使两个表的相应字段类型一致,若是不一致,则必须在一边加上类型转换函数(注意mysql的日期和字符是相同的,因此不须要另外的转换)。

7.全模糊查询没法使用索引,应尽可能避免,如%a%,可使用半模糊查询a%。

8.sql中直接使用表名,不使用schema做为前缀,应在链接时直接连到改schema或采用use。

9.sql语句尽量简单,不要使用复杂sql,复杂逻辑尽可能在代码中实现(一条sql只能在一个cpu运算,大语句拆小语句,减小锁时间,一条大sql能够堵死整个库)。

10.简单的事务,使事务时间尽量短,避免如上传图片等事务。

11.原则上通常禁止使用<>、!=和not in,而应该转换成相应的=和in查询条件,若有特殊须要没法完成相应的转换,必须征求dba。

12.原则上通常不容许使用exists和not exists查询,应转换为相应的等链接和外链接来查询,若有特殊须要没法完成相应的转换,必须征求dba。

13.不要有太多的join,核心操做表尽可能不要join,join控制在3个之内,让每一个查询sql尽可能简洁和高性能。

14.全部非外链接sql(inner join),把关联表统一写到from子句里面,关联条件和过滤条件统一写到where子句中。

15.出于代码可读性,全部的外链接sql语句,统一使用left join。

16.Query语句中的ORDER BY、GROUP BY的时候,尽量利用已有的索引来避免实际的排序计算,能够很大幅度的提高ORDER BY、GROUP BY操做的性能。

17.避免使用trig/func,由客户端程序取而代之。

18.OR改写为IN(),or的效率是n级别,in的效率是log(n)级别,in的个数建议控制在200之内。

如:select id from t where a=1 or a= 2;

=>select id from t where a in (1, 2);

19.OR改写为UNION,mysql的索引合并不太友好

如:select id from t where a = 1 or b = 'ds';key(a),key(b)

=>select id from t where a = 1

union all或union(看具体状况,union有去重开销)

select id from t where b= 'jonh'


20.使用load data导数据,load data比insert快约20倍,但要注意自增主键问题致使主从不一致与空洞问题;

21.应用程序端尽可能采用Prepared Statements(是一种运行在后台的SQL语句集合),在性能方面,当一个相同的查询被使用屡次的时候,会带来可观的性能优点



数据库权限分配规范


生产库:

DBA:有全部权限,超级管理员权限

应用程序:分配insert、delete、update、select、execute、events、jobs权限。

测试人员:无权限

开发人员:无权限

原则:全部对线上表的操做,除了应用程序以外,都必须经由DBA来决定是否执行、已经何时执行等。



测试库:

DBA:全部权限。

测试人员:有insert、delete、update、select、execute、jobs,ddl等权限。

数据分析人员:只有select查询权限

开发人员:有select权限。

原则:DBA有全部权限,并且严格控制表结构的变动,不容许除了qa以外的人对测试环境的库环境进行修改,以避免影响测试人员测试。全部对测试库的表结构进行的修改必须由测试人员和DBA一块儿审核事后才能操做。


开发库:

DBA:全部权限

测试人员:有库表结构以及数据的全部操做权限。

开发人员:有库表结构以及数据的全部操做权限。

数据分析人员:有库表结构以及数据的全部操做权限。

相关文章
相关标签/搜索