Skip to content

Latest commit

 

History

History
90 lines (56 loc) · 7.36 KB

数据库设计.md

File metadata and controls

90 lines (56 loc) · 7.36 KB

命名规则

  1. 【强制】表名、字段名必须使用小写字母或数字,禁止出现数字开头,禁止两个下划线中间只出现数字。数据库字段名的修改代价很大,所以字段名称需要慎重考虑。说明:MySQLWindows下不区分大小写,但在Linux下默认是区分大小写。因此,数据库名、表名、字段名,都不允许出现任何大写字母,避免节外生枝。正例:aliyun_adminrdc_configlevel3_name 反例:AliyunAdminrdcConfiglevel_3_name
  2. 【强制】表名字段名不使用英文与拼音的复合表达式,符合表达习惯。禁用保留字,如descdaterange、match、delayed等,请参考MySQL官方保留字。
  3. 【强制】主键索引名为pk_字段名;唯一索引名为uk_字段名;普通索引名则为idx_字段名。 说明:pk_primary keyuk_unique keyidx_index的简称。
表/字段规则
  1. 【强制】不得使用外键与级联,一切外键概念必须在应用层解决。 说明:以学生和成绩的关系为例,学生表中的student_id是主键,那么成绩表中的student_id则为外键。如果更新学生表中的student_id,同时触发成绩表中的student_id更新,即为级联更新。外键与级联更新适用于单机低并发,不适合分布式、高并发集群;级联更新是强阻塞,存在数据库更新风暴的风险;外键影响数据库的插入速度。

  2. 【强制】所有的字符存储与表示,均以utf-8编码,注意字符统计函数的区别。

  3. 【强制】如果存储的字符串长度几乎相等,使用char定长字符串类型。

  4. 【强制】varchar是可变长字符串,不预先分配存储空间,长度不要超过 2000,如果存储长度大于此值,定义字段类型为text,独立出来一张表,用主键来对应,避免影响其它字段索引效率。

  5. 【推荐】表必备三字段:id, createon, updateon。 说明:其中id必为主键,类型为bigint unsigned、单表时自增、步长为1。createon, updateon的类型均为datetime类型。

  6. 【推荐】所有字段都应该有默认值,不应该存在值为NULL的列,NULL值在统计中会造成很多麻烦。

  7. 【推荐】字段允许适当冗余,以提高查询性能,但必须考虑数据一致。冗余字段应遵循:

    1)不是频繁修改的字段。

    2)不是varchar超长字段,更不能是text字段。 正例:商品类目名称使用频率高,字段长度短,名称基本一成不变,可在相关联的表中冗余存储类目名称,避免关联查询。

  8. 【推荐】单表行数超过 500 万行或者单表容量超过 2GB,才推荐进行分库分表。 说明:如果预计三年后的数据量根本达不到这个级别,请不要在创建表时就分库分表。

索引规则
  1. 【强制】勿认为一个查询就需要建一个索引,也不要胡乱认为索引会消耗空间、严重拖慢更新和新增速度,而是应该业务需求考虑索引的必要程度。

  2. 【强制】对于有限的几个值的列不需要建索引。

  3. 【强制】经常出现在where条件和order by子句中的列一定要建立索引。

  4. 【强制】业务上具有唯一特性的字段,即使是多个字段的组合,也必须建成唯一索引。

    说明:不要以为唯一索引影响了insert速度,这个速度损耗可以忽略,但提高查找速度是明显的;另外,即使在应用层做了非常完善的校验控制,只要没有唯一索引,根据墨菲定律,必然有脏数据产生。

  5. 【强制】在varchar字段上建立索引时,必须指定索引长度,一般来说 8 位即可,没必要对全字段建立索引,根据实际文本区分度决定索引长度即可。

  6. 【推荐】

    SQL
    

    性能优化的目标:至少要达到

    range
    

    级别,要求是

    ref
    

    级别,如果可以是

    consts
    

    最好。

    说明:

    1)consts 单表中最多只有一个匹配行(主键或者唯一索引),在优化阶段即可读取到数据。

    2)ref 指的是使用普通的索引(normal index)。

    3)range 对索引进行范围检索。 反例:explain表的结果,type=index,索引物理文件全扫描,速度非常慢,这个index级别比较range还低,与全表扫描是小巫见大巫。

SQL语句
  1. 【强制】不要使用count(列名)count(常量)来替代count(*)count(*)SQL92定义的标准统计行数的语法,跟数据库无关,跟NULL和非NULL无关。 说明:count(*)会统计值为NULL的行,而count(列名)不会统计此列为NULL值的行。
  2. 【强制】order by排序的时候如果是根据创建时间来排序,不要使用createon列,直接用order by id 或者order by id desc。说明:通过主键来排序大幅提高性能。
  3. 【强制】 在代码中写分页查询逻辑时,若count为0应直接返回,避免执行后面的分页语句。
  4. 【强制】where条件中如果字段是字符类型,代码中的条件值必须加上引号,避免索引失效。
  5. 【强制】在表查询中,一律不要使用 作为查询的字段列表,需要哪些字段必须明确写明。 说明:1)增加查询分析器解析成本;2)无用字段增加网络消耗,尤其是text类型的字段。
  6. 【强制】禁止使用存储过程,存储过程难以调试和扩展,更没有移植性。
  7. 【强制】 除临时表外程序中禁止使用TRUNCATE TABLE 。说明:TRUNCATE TABLE 在功能上与不带 WHERE 子句的 DELETE 语句相同,极有可能造成事故。
  8. 【推荐】in操作能避免则避免,若实在避免不了,需要仔细评估in后边的集合元素数量,控制在1000个之内。
  9. 【推荐】不要写一个大而全的数据更新接口。不管是不是自己的目标更新字段,都进行update table set c1=value1,c2=value2,c3=value3; 这是不对的。执行SQL时,不要更新无改动的字段,一是易出错;二是效率低;三是增加binlog存储。
  10. 【推荐】利用延迟关联或者子查询优化超多分页场景。 说明:MySQL并不是跳过offset行,而是取offset+N行,然后返回放弃前offset行,返回N行,那当offset特别大的时候,效率就非常的低下,要么控制返回的总页数,要么对超过特定阈值的页数进行SQL改写。 正例:先快速定位需要获取的id段,然后再关联: SELECT a.* FROM 表1 a, (select id from 表1 where 条件 LIMIT 100000,20 ) b where a.id=b.id
  11. 【推荐】建组合索引的时候,区分度最高的在最左边。 正例:如果where a=? and b=? ,如果a列的几乎接近于唯一值,那么只需要单建idx_a索引即可。 说明:存在非等号和等号混合时,在建索引时,请把等号条件的列前置。如:where c>? and d=? 那么即使c的区分度更高,也必须把d放在索引的最前列,即索引idx_d_c
  12. 【推荐】超过三个表禁止join。需要join的字段,数据类型必须绝对一致;多表关联查询时,保证被关联的字段需要有索引。 说明:即使双表join也要注意表索引、SQL性能。