背景:读《阿里巴巴Java开发手册》前言,有提到mysql的表结构和索引设计,对这块不了解,谷歌搜索了些中文和英文文章,记录一下要点。

参考链接一

  • 允许保存表情的表,存储格式设计为utf8mb4,避免使用utf8。
  • 选择合适的数据类型。
  • 主外键字段类型一定要一致,否则会造成隐式转化,不走索引,造成生产事故!
  • 表以及字段上添加合理的注释。
  • 数据库表设计时,一定要在外键字段以及合适的字段上加索引。

参考链接二

如何建索引:

  • 区分度

计算公式:select count(distinct(name))/count(*) from t_base_user;

单列索引:通过区分度确定在该字段上新建索引是否有效,区分度越大建立索引越有效。

多列索引(联合索引):区分度较高的放在前面,这样联合索引才更有效。

例如:有一个表test的字段name若比status区分度高,两者建立联合索引时name应放在status前,如:alter table

test add index idx_name_status(name,status);

  • 最左前缀匹配原则

MySQL会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如select * from t_base_user where

type="10" and created_at<"2017-11-03" and status=1, (该语句仅作为演示),在上述语句中,status就不会走索引,因为遇到

<时,MySQL已经停止匹配,此时走的索引为:(type,created_at),其先后顺序是可以调整的,而走不到status索引,此时需要修改

语句为:select * from t_base_user where type=10 and status=1 and created_at<"2017-11-03",即可走status索引。

  •  函数运算

不要在索引列上,进行函数运算,否则索引会失效。因为b+树中存的都是数据表中的字段值,但进行检索时,需要把所有元

素都应用函数才能比较,显然成本太大。

  • 扩展优先

扩展优先,不要新建索引,尽量在已有索引中修改。如:select * from t_base_user where name="andyqian"

and email="andytohome",在表t_base_user表中已经存在idx_name索引,如果需要加入idx_name_email的索引,应该是修

改idx_name索引,而不是新建一个索引。(查了下,索引名称也是可以修改的)

参考链接三

  • 选择合适的存储引擎,应根据业务场景选择,OLTP(在线事务处理)用InnoDB,仅用作存储,允许数据不一致,数据仓库等场景时,可用MyISAM
  • 选择合适的字符集,见上面参考链接一部分的第一条。
  • 主/外键类型,主键的设计是非常重要的,在主键的选择上,应满足唯一性(必要条件)、非空性、有序性、可读性、可扩展性。有序性可以提高查询效率,存储的顺序也是有序的,对分库分表也有好处。该参考文章的作者建议用8字节无符号的bigint(20)作为主键类型。

       注意点:主外键的数据类型一定要一致,每个表中的主键命名保持一致。

       原文作者提到varchar类型会对性能有影响,比如用UUID作主键,数据量大时性能不好。varchar也不是有序的,可读性也不 

       好。

       PS:主键适用于主从架构,对于多主,主键的生成可能会有重复,因此一些大厂有自己的ID生成中间件。

  • 外键约束,外键约束用来保证数据完整性的,但不建议在数据库表中加外键约束,因为会影响性能,例如:每一次修改数据时,都要在另外的一张表中执行查询。原文作者建议:在应用层,也就是代码层面,来维持外键关系。
  • 选择合适的类型,尽量选择小、简单的类型,保持可读性,尽量避免Null。小的数据类型服务端处理效率、传输等都会快些。常见的数据类型设计:

       状态类型用tinyint,例如性别等。

       时间日期用datetime,timestamp,其中datetime可读性高些。

       尽量不要使用text和blob,特别是blob

  • 设计逻辑删除,在数据重要性较高的场景下可以考虑使用,原因是可恢复,物理删除一旦删除,即不可恢复。
  • 创建时间&修改时间,主要是用作业务上的字段,每个表中都应该有,在查询,以及问题查找定位时有诸多好处。

       created_time datetime not null default now();

       updated_time datetime not null default now() comment '';

  • 添加合适的索引
  • 添加注释

 参考链接四

该文对数据库表设计应遵守的三范式介绍地十分清楚。      

 

参考链接一:

https://mp.weixin.qq.com/s?__biz=MzI2NDU3OTg5Nw==&mid=2247483799&idx=1&sn=4d1f45ab7d5bc9655a8fef2601171e52&chksm=eaab3fc1dddcb6d794dde2ee8e71a56a9b71fdc207efc033c56d1b53c7dc05b096e7cbc3482b&scene=21#wechat_redirect

参考链接二:

https://mp.weixin.qq.com/s?__biz=MzI2NDU3OTg5Nw==&mid=2247483736&idx=1&sn=e3fa0bf61b77c9ca12ee1d295c51313a&chksm=eaab3f0edddcb618d38fabaccfd6a7cd18df0f2d77dfeeaa1403bae02c7eb588e29607149dcc&scene=21#wechat_redirect

参考链接三:

https://zhuanlan.zhihu.com/p/32382274