1.引子
对于后端开发工程师来讲,数据库设计,优化是一项必备的技能,瞧瞧咱们是否是常常在项目中吐槽其余小伙伴编写的sql语句,既如此,千万不要让其余小伙伴有机会吐槽回来。甚至咱们应该作到在编写sql语句的时候,脑海中已经浮现了该sql语句的执行轨迹,这样一来,相信咱们写出的sql语句质量会很是高。mysql
由于工做上的须要,抽空整理了一版数据库设计开发参考规范,我把它叫作必知必会之数据库规约,并分享给你,指望给你带来一些收获!sql
我将内容分为:数据库
-
建表规范后端
-
sql规范bash
-
索引规范网络
2.建表规范
2.1.范式化
#1.关系数据库表设计基础理论:第一范式、第二范式、第三范式 ##1.1.第一范式 强调列的原子性,字段不可再分割 ##1.2.第二范式 强调行的惟一性,不可存在相同的行(表中必须有主键字段) ##1.3.第三范式 强调主外键关联,消除冗余性(须要注意,在互联网项目中,通常不创建主外键约束,在代码层面实现业务关联) 所以今天咱们有时候在强调反范式化设计,就是针对的第三范式
2.2.存储引擎
#1.mysql数据库,存储引擎建议选择InnoDB ##缘由: InnoDB存储引擎支持事务、支持行级锁(并发性能更好)、支持Crash safe能力(redo log能力)
3.3.数据类型
#1.选择合适的数据类型 ##1.1.整数 TinyInt,SmallInt,MediumInt,Int,BigInt 使用的存储8,16,24,32,64位存储空间。使用Unsigned表示不容许负数,可使正数的上线提升一倍 ##1.2.实数 Float,Double , 支持近似的浮点运算 Decimal,用于存储精确的小数(一般用于货币存储) ##1.3.字符串 VarChar,存储变长的字符串。须要1或2个额外的字节记录字符串的长度 Char,定长,适合存储固定长度的字符串,如MD5值。 Blob,Text 为了存储很大的数据而设计的。分别采用二进制和字符的方式 ##1.4.时间 DateTime,保存大范围的值,占8个字节,存储范围(1001-9999)。 TimeStamp,推荐,与UNIX时间戳相同,占4个字节,存储范围(1970-2038)
如何选择?并发
-
尽可能使用对应的数据类型。好比不要用字符串类型保存时间oracle
-
选择更小的数据类型。能用TinyInt,就不用Int框架
-
标识列(identifier column),建议使用整型,不推荐字符串类型,占用更多空间,并且计算速度比整型慢 数据库设计
2.4.字符集
#1.统一字符集(客户端、服务端),建议使用utf-8字符集,mysql数据库须要注意真正的utf-8字符集应该选择:utf8mb4
2.5.命名
#1.见名知意,禁止拼音英文混用 #2.约定库名、表名、字段名小写、下划线风格,不超过32个字符 #3.禁止使用保留字
2.6.注释
#1.表、字段必须添加必要的注释(千万不要偷懒)
2.7.默认值
#1.字段定义为 NOT NULL 且需提供默认值 ##缘由: NULL的列使索引/索引统计/值比较都更加复杂,数据库自身更难优化 NULL这种类型Msql内部须要进行特殊处理,增长数据库处理记录的复杂性;同等条件下,表中有较多空字段的时候,数据库的处理性能会下降不少 NULL值须要更多的存储空,不管是表仍是索引中每行中的NULL的列都须要额外的空间来标识
2.8.手写schema
#1.禁止经过工具,或者orm框架生产schema。所有ddl sql必须手工提供
3.sql规范
3.1.select *
#1.大原则:客户端须要什么,就返回什么 #2.读取不须要的列,会增长cpu、Io、网络开销 #3.select * 不能有效利用覆盖索引
3.2.where条件
#1.禁止where条件属性上,执行隐式转换,隐式转换会让索引失效 好比select id, name,phone from table where phone=18688438888 (phone是字符串类型) #2.禁止where条件属性上,使用函数或者表达式,where条件属性上使用函数,会让索引失效,同理表达式让索引失效 好比select id,name,age where age+1 = 10
3.3.外键关联
#1.禁止使用外键、级联。一切外键概念必需要应用层解决 ##缘由: 外键与级联更新适用于单机低并发,不适合分布式、高并发集群 外键影响数据库的插入速度 级联更新是强阻塞,存在数据库更新风暴的风险
3.4.or链接条件
#1.尽可能避免在where子句中,经过or链接条件 ##缘由: or 链接条件可能会使索引失效 经过union all 替换 or链接条件
3.5.模糊查询
#1.主流关系数据库oracle、mysql支持前缀索引 #2.模糊查询应用场景,like子句中要放在后面 好比:select id,name from table where name like '小明%'
3.6.表关联
#1.表关联数量,尽可能不要超过5个表,连表越多,编译的时间和开销也就越大 #2.把链接表拆开成较小的几个执行,可读性更高 #3.表之间的关联,让小表成为驱动表 #4.多个表关联时,每一列上必须明确来源表 好比:select A.id,B.name from A,B WHERE A.id=B.id
3.7.限制结果集
#1.若是明确查询结果最多只有1条记录,请使用好limit=1 或者rownum<=1
4.索引规范
4.1.索引原理
#1.索引的原理:空间换时间 ##优点: 减小查询扫描的数据量 避免排序和零时表 将随机IO变为顺序IO ##代价: 须要更多的存储空间 影响更新维护效率(增删改)
4.2.索引选择
#1.B-tree索引 实践中使用更多的索引类型 支持精确查找、范围查找、前缀查找、支持排序 #2.hash索引 查询效率更高,但只支持精确查找 不支持范围、前缀查找,不支持排序
4.3.索引实践
#1.索引字段区分度要高(索引字段值不能有太多重复数据) ##1.1.好比:select id,name,age from user where sex=1 ##1.2.解释: 性别只有男,女,每次过滤掉的数据不多,不宜使用索引 经验上,能过滤80%数据时就可使用索引。对于订单状态,若是状态值不多,不宜使用索引,若是状态值不少,可以过滤大量数据,则应该创建索引 #2.用好复合索引 ##2.1.复合索引,指多个字段联合起来建立索引,好比字段A、字段B,联合建立索引(A,B) ##2.2.利用复合索引,能够有效减小索引数量,索引(A,B),至关于创建了索引(A),与索引(A,B) #3.删除冗余重复的索引,缘由参考索引的代价