文章目录

MySQL表名、字段、索引规范

表名规范

  • 表的命名最好是遵循“业务名称_表的作用”

  • 表名、字段名必须使用小写字母或数字,禁止出现数字开头,禁止两个下划线中间只出现数字。

MySQL 在 Windows 下不区分大小写,但在 Linux 下默认是区分大小写。因此,数据库名、表名、字段名,都不允许出现任何大写字母,避免节外生枝。

  • 表名不使用复数名词

字段规范

  • 如果修改字段含义或对字段表示的状态追加时,需要及时更新字段注释。
  • 表达是与否概念的字段,必须使用 is_xxx 的方式命名,数据类型是 unsigned tinyint (1 表示是,0 表示否)

说明:任何字段如果为非负数,必须是 unsigned
注意:POJO 类中的任何布尔类型的变量,都不要加 is 前缀,所以,需要在设置从 is_xxx 到Xxx 的映射关系。数据库表示是与否的值,使用 tinyint 类型,坚持 is_xxx 的命名方式是为了明确其取值含义与取值范围。

  • 小数类型为 decimal,禁止使用 float 和 double。(这个~~~)
  • 表必备三字段:id, create_time, update_time

其中 id 必为主键,类型为 bigint unsigned、单表时自增、步长为 1。

create_time, update_time的类型均为 datetime 类型,前者现在时表示主动式创建,后者过去分词表示被动式更新。

CREATE TABLE mytb (
  id bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id 主键',
  create_time timestamp NULL DEFAULT current_timestamp(),
  update_time timestamp NULL DEFAULT current_timestamp() ON UPDATE current_timestamp()
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
  • 字段允许适当冗余,以提高查询性能,但必须考虑数据一致。

冗余字段应遵循:
1) 不是频繁修改的字段。
2) 不是唯一索引的字段。
3) 不是 varchar 超长字段,更不能是 text 字段。

  • 合适的字符存储长度,不但节约数据库表空间、节约索引存储,更重要的是提升检索速度。
    无符号值可以避免误存负数,且扩大了表示范围。
对象 年龄区间 类型 字节 标识范围
150岁以内 tinyint unsigned 1 无符号值:0 到 255
数百岁 smallint unsigned 2 无符号值:0 到 65535
恐龙化石 数千万年 int unsigned 4 无符号值:0 到约 43 亿
太阳 约50亿年 bigint unsigned 8 无符号值:0 到约 10 的 19 次方

索引规范

  • 主键索引名为 pk_字段名;
  • 唯一索引名为 uk_字段名;
  • 普通索引名则为 idx_字段名;

  • 业务上具有唯一特性的字段,即使是组合字段,也必须建成唯一索引

不要以为唯一索引影响了 insert 速度,这个速度损耗可以忽略,但提高查找速度是明显的;另外,

即使在应用层做了非常完善的校验控制,只要没有唯一索引,根据墨菲定律,必然有脏数据产生。

  • 超过三个表禁止 join。需要 join 的字段,数据类型保持绝对一致;多表关联查询时,保证被关联的字段需要有索引。

  • 在 varchar 字段上建立索引时,必须指定索引长度,没必要对全字段建立索引,根据实际文本区分度决定索引长度。

索引的长度与区分度是一对矛盾体,一般对字符串类型数据,长度为 20 的索引,区分度会高达 90%以上,可以使用 count(distinct left(列名, 索引长度))/count(*)的区分度来确定。

  • 页面搜索严禁左模糊或者全模糊,如果需要请走搜索引擎来解决。

索引文件具有 B-Tree 的最左前缀匹配特性,如果左边的值未确定,那么无法使用此索引。

  • SQL 性能优化的目标:至少要达到 range 级别,要求是 ref 级别,如果可以是 consts最好。

说明:

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

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

3) range 对索引进行范围检索。

反例:

​ explain 表的结果,type=index,索引物理文件全扫描,速度非常慢,这个 index 级别比较 range还低,与全表扫描是小巫见大巫。

  • 建组合索引的时候,区分度最高的在最左边

正例:如果 where a=? and b=?,a 列的几乎接近于唯一值,那么只需要单建 idx_a 索引即可。

说明:存在非等号和等号混合判断条件时,在建索引时,请把等号条件的列前置。如:where c>? and d=?

那么即使 c 的区分度更高,也必须把 d 放在索引的最前列,即建立组合索引 idx_d_c。

外键和级联

  • 不得使用外键与级联,一切外键概念必须在应用层解决。

(概念解释)学生表中的 student_id 是主键,那么成绩表中的 student_id 则为外键。如果更新学

生表中的 student_id,同时触发成绩表中的 student_id 更新,即为级联更新。外键与级联更新适用于单机

低并发,不适合分布式、高并发集群;级联更新是强阻塞,存在数据库更新风暴的风险;外键影响数据库

的插入速度。

存储过程

  • 禁止使用存储过程,存储过程难以调试和扩展,更没有移植性