MySQL数据库设计规范

规范一:库名、表名、字段名必须使用小写,并采用下划线分割。

1、MYSQL配置参数lower_case_table_names,不可动态更改,LINUX系统默认为0,即库表名以实际情况存储,大小写敏感。如果是 1,以小写存储,大小写不敏感。如果是 2,以实际情况存储,但以小写比较。

2、如果大小写混合使用,可能存在 abc、ABC、Abc 等多个表共存,容易导致混乱。

3、字段名显示区分大小写,但实际使用不区分,即不可以建立两个名字一样但大小写不一样的字段。

 

规范二,库名、表名、字段名禁止超过20 个字符。

库名、表名、字段名字符数存在上限,为了统一规范、易于辨识以及减少传输量,禁止超过20 个字符。

 

规范三,原则上业务范畴内的表统一使用 innodb 存储引擎;如需要使用其他存储引擎,需说明原因,并征得 DBA 同意。

innodb 支持事务、行级锁,有更好的数据恢复能力、更好的并发性能,同时对多核、大内存、SSD等硬件支持更好,支持数据热备份等。因此 innodb 比 myisam 有明显优势。

innodb 有非常多的状态数据可收集,而对于 myisam,能收集到的数据非常有限,不利于做监控和容量规划。

 

规范四,禁止使用分区表。

分区表对分区键有严格要求,分区表在表变大后,执行DDL、SHARDING、单表恢复等都变困难。因此禁止使用分区表,并建议业务端手动SHARDING。

 

规范五,减少或避免使用临时表。

 

规范六,为了切换后可以正常工作,无论主备,相同的表需要使用相同的引擎。

相同的表在主备架构下,可以使用不同的引擎来获得更好的性能,但是给管理带来复杂性,也给业务带来隐患。

 

规范七,每一个表都需要设置主键。

表没有主键,innodb 会默认设置隐藏的主键列,没有主键的表在定位数据行的时候非常困难,也会降低基于行复制的效率。

 

规范八,将大字段、访问频率低的字段拆分到单独的表中存储,分离冷热数据。

利于有效利用缓存,防止读入无用的冷数据,较少磁盘IO,同时保证热数据常驻内存提高缓存命中率。

 

规范九,表不要求一定满足第三范式,根据实际情况可适当添加冗余字段。

我们的原则是一个 SQL 最好操作一个表,最多不能超过 2 个表的关联。如果实现一个常用的功能需要一个关联多个表的查询,则需要重新考虑设计。

由程序保证冗余数据的维护。

 

规范十,对于字典类型的表,因数据量少,修改少,影响面大,应依赖数据库约束来确保数据质量。对于日志或流水型表,为了提升效率,可以适当放宽限制。

 

规范十一,对于字段设计:越简单越好,越小越好。

使用最合适的数据类型,能用数字类型就不要用 varchar 类型;能用 date/datetime 就不要用 varchar 类型;避免使用 char 类型;不使用浮点数,可以通过乘以一个系数来转换成整数数据。

在大部分情况下,数据类型比 varchar 类型更省空间,计算性能更高。

 char 类型占用固定空间,在很多时候会造成空间浪费。

 

规范十二,尽量避免text/lob 类型。

text 和 lob在行内只存储指针,实际数据是在行外单独存储的。使用这些数据类型,查询时需要更多的IO。

如果 SQL 引用了text/lob 字段,排序等操作需要用到隐式临时表时,只能用到 disk 临时表,不能用 in-memory 临时表。对性能影响巨大。

如果(也许)需要用 text/lob 类型,建议把这些字段和其他字段分离,放在单独的表中。

 

规范十三,字段长度定义遵循最小化原则,够用就行,不能贪图方便定义很大的长度。

过大的长度容错性高,容易出现低质量的数据。

定义大长度会消耗更多的空间(需要用额外的字节存储长度)

在很多时候,mysql 会以列的长度定义来分配使用内存,过大的字段长度定义会消耗更多的内存。甚至还有可能原来可以在内存执行的排序变为磁盘排序。

规范十四,字段实际值遵循最小化原则,在满足业务需求的前提下,选择最合适的数据类型,写入最少的数据。

ID一般无具体意义,优先使用数字来用于ID字段,杜绝滥用长字符串ID。

对于状态之类的字段,用 0/1 之类的数字代替 valid/invalid 等。

规范十五,对于字符类型,字段长度定义的是字符个数,而不是字节个数,所占空间与字符集相关。对于 int 类型,占用空间是固定的,指定长度只是指定了显示长度。

varchar(25000)不一定能存  25000 个字符,如果都是汉字,且是UTF-8,只能存储 65532/3 字符。

int(1)和 int(11)占用空间是一样的。1 和 11 只代表显示长度,与实际数据存储无关。

 

规范十六,区分使用 datetime 和 timestamp。存储年使用 YEAR 类型。存储日期使用 DATE 类型。存储时间(精确到秒)建议使用 timestamp 类型。

 

规范十七,一个表的字段个数控制在 30 个字段以内;如果字段超过30 个,可考虑按冷热程度分表。

 

规范十八,严格禁止单条记录超过 8 K。

目前DB 的一个 page 大小都设置为 16 K,当一条记录超过 page 的一半时,记录中 blob 或 varchar 类型的字段会在行外存储。存取时会有额外 IO 消耗。插入会锁住整个聚簇索引,直到插入完成才释放。

 

规范十九,建议每一个重要的业务表都加上 create_time 和modify_time 两个字段,数据类型为datetime或int;后续的所有更新都必须更新 modify_time 字段。

增加字段会带来额外的资源消耗,但考虑到它可能带来的好处,还是值得添加的。

 

规范二十,对于可能出现的 where条件中的字段,尽量设置为非空(notnull)。

B*Tree 索引不能索引空值(null),字段值为空,在部分查询不能有效使用索引。

 

规范二十一,字段字符集与表保持一致,不单独设置字符集。

 

规范二十二,相同含义的字段在不同表中应使用相同的名称,数据类型及长度必须保持一致。

 

规范二十三,innodb 表每一个表都要设置主键,主键越短越好,最好是 auto_increment 类型;如果不能使用自增,则应考虑构造使用单向递增主键;禁止使用随机类型值用于主键。

使用innodb,每一个表都必须有主键。如果没有指定主键,mysql 会选择一个非空的唯一键作为主键。如果都没有,mysql 会自动分配 6-bytes长度的全局的 rowid 隐藏列作为主键。所有 innodb 无主键表共享这一序列,并发性能较差,因此建议所有 innodb 表,指定主键。

所有的辅助索引都包含主键字段,因此,如果主键过大的话,会影响所有的索引大小。

递增型主键可以让索引更紧凑、空间利用率更充分、数据插入更高效。随机数据会让空间大量浪费,且会导致索引分裂加剧,离散IO增多,极大影响DML性能。

 

规范二十四,主键最好由一个字段构成,最多不要超过2个,禁止超过2个字段的组合主键。如果业务要求,则可创建一个自增字段作为主键,再添加一个唯一索引。

多列主键会导致其他索引体积膨胀,占用更多的空间,并降低性能。

如果查询都是基于主键字段,且只有 1个及以下辅助索引,则限制可放宽。

 

规范二十五,如果一个业务上存在多个(组)唯一键,以查询最常用的唯一键作为主键。

 

规范二十六,索引会降低 DML 的性能,不是越多越好,只创建需要的索引,避免冗余索引。

    创建索引需考虑返回数据量、对 DML 的影响,以及受其影响的查询 SQL的执行频率。

 

规范二十七,选择作为主键的列必须在插入后不再修改或者极少修改,否则需要考虑使用自增列作为主键。

 

规范二十八,创建组合索引/主键时,常用的字段放在前面;选择性高的字段放在前面。

两者冲突时,以常用为更优先考虑。

规范二十九,创建组合索引时,如果 where 条件中过滤性不强,且需要排序分页操作,建议把排序字段也加到组合索引中,放在组合索引的最后列。

 

规范三十,对较长的字符数据类型的字段建索引,优先考虑前缀索引。

 

规范三十一,低选择性的列不加索引,列外情况:对于状态数据分布非常倾斜的,且查询条件中没有其他更合适索引的字段。

 

规范三十二,禁止冗余索引

 

规范三十三,在建表时,应充分考虑需要加什么索引,尽量避免上线后条件索引。

 

规范三十四,如果数据有时效性,则建议按时间分表或者分区。

 

规范三十五,杜绝按天分表。

 

规范三十六,如果所有数据热度相同,则建议根据 hash 或者其他手段分表。

 

规范三十七,杜绝只按月份,不考虑年份方式分表。

 

规范三十八,如果多个独立业务需要共用一台 DB,不同业务的表必须放在不同的 database(schema)里。

 

规范三十九,对于分库分表,每一个表的索引结构及名称都必须一致。

 

规范四十,原则上禁止使用存储过程、触发器

精彩推荐:

1.  MySQL不停地自动重启怎么办

2.  升级python,就是这么简单

3.  MySQL里trx_mysql_thread_id为0 的事务导致大量锁等待超时该咋整

4.  mysql8.0新增用户及加密规则修改的那些事

5.  Postgresql部署及简单操作

6.  比hive快10倍的大数据查询利器-- presto

7.  国产数据库部署初体验

8.   监控利器出鞘:Prometheus+Grafana监控MySQL、Redis数据库

9.   PostgreSQL主从复制--物理复制

10. PostgreSQL主从复制--逻辑复制

11.  MySQL从库生成大量小的relay log案例模拟

12.  MySQL传统点位复制在线转为GTID模式复制

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值