|
| 1 | +## Mysql设计规范 |
| 2 | + |
| 3 | +[原文](https://mp.weixin.qq.com/s?__biz=MjM5ODYxMDA5OQ==&mid=2651961030&idx=1&sn=73a04dabca409c1557e752382d777181&chksm=bd2d031a8a5a8a0c6f7b58b79ae8933dfefbd840dfb5d34a5c708ab63e6decbbc1b13533ebc8&scene=21#wechat_redirect) |
| 4 | + |
| 5 | +1. 基础规范 |
| 6 | + - 表存储引擎必须使用InnoDB |
| 7 | + - 表字符集默认使用utf8,必要时候使用utf8mb4 *(1)通用,无乱码风险,汉字3字节,英文1字节,(2)utf8mb4是utf8的超集,有存储4字节例如表情符号时,使用它* |
| 8 | + - 禁止使用存储过程,视图,触发器,Event *1)对数据库性能影响较大,互联网业务,能让站点层和服务层干的事情,不要交到数据库层,2)调试,排错,迁移都比较困难,扩展性较差* |
| 9 | + - 禁止在数据库中存储大文件,例如照片,可以将大文件存储在对象存储系统,数据库中存储路径 |
| 10 | + - 禁止在线上环境做数据库压力测试 |
| 11 | + - 测试,开发,线上数据库环境必须隔离 |
| 12 | +2. 命名规范 |
| 13 | + - 库名,表名,列名必须用小写,采用下划线分隔 |
| 14 | + - 库名,表名,列名必须见名知义,长度不要超过32字符 |
| 15 | + - 库备份必须以bak为前缀,以日期为后缀 |
| 16 | + - 从库必须以-s为后缀 |
| 17 | + - 备库必须以-ss为后缀 |
| 18 | +3. 表设计规范 |
| 19 | + - 单实例表个数必须控制在2000个以内 |
| 20 | + - 单表分表个数必须控制在1024个以内 |
| 21 | + - 表必须有主键,推荐使用UNSIGNED整数为主键 *1)删除无主键的表,如果是row模式的主从架构,从库会挂住,2)B+聚簇索引* |
| 22 | + - 禁止使用外键,如果要保证完整性,应由应用程式实现 *外键使得表之间相互耦合,影响update/delete等SQL性能,有可能造成死锁,高并发情况下容易成为数据库瓶颈* |
| 23 | + - 建议将大字段,访问频度低的字段拆分到单独的表中存储,分离冷热数据 |
| 24 | +4. 列设计规范 |
| 25 | + - 根据业务区分使用tinyint/int/bigint,分别会占用1/4/8字节 |
| 26 | + - 根据业务区分使用char/varchar *1)字段长度固定,或者长度近似的业务场景,适合使用char,能够减少碎片,查询性能高,2)字段长度相差较大,或者更新较少的业务场景,适合使用varchar,能够减少空间* |
| 27 | + - 根据业务区分使用datetime/timestamp *前者占用5个字节,后者占用4个字节,存储年使用YEAR,存储日期使用DATE,存储时间使用datetime* |
| 28 | + - 必须把字段定义为NOT NULL并设默认值 *NULL的列使用索引,索引统计,值都更加复杂,MySQL更难优化,2)NULL需要更多的存储空间,3)NULL只能采用IS NULL或者IS NOT NULL,而在=/!=/in/not in时有大坑* |
| 29 | + - 使用INT UNSIGNED存储IPv4,不要用char(15) |
| 30 | + - 使用varchar(20)存储手机号,不要使用整数 *1)牵扯到国家代号,可能出现+/-/()等字符,例如+86,2)手机号不会用来做数学运算,3)varchar可以模糊查询,例如like ‘138%’* |
| 31 | + - 使用TINYINT来代替ENUM *ENUM增加新值要进行DDL操作* |
| 32 | +5. 索引规范 |
| 33 | + - 唯一索引使用uniq_[字段名]来命名 |
| 34 | + - 非唯一索引使用idx_[字段名]来命名 |
| 35 | + - 单张表索引数量建议控制在5个以内 *太多索引会影响写性能,异常复杂的查询需求,可以选择ES* |
| 36 | + - 组合索引字段数不建议超过5个 |
| 37 | + - 不建议在频繁更新的字段上建立索引 |
| 38 | + - 非必要不要进行JOIN查询,如果要进行JOIN查询,被JOIN的字段必须类型相同,并建立索引 |
| 39 | + - 理解组合索引最左前缀原则,避免重复建设索引,如果建立了(a,b,c),相当于建立了(a), (a,b), (a,b,c) |
| 40 | +6. SQL规范 |
| 41 | + - 禁止使用select *,只获取必要字段 *1)select *会增加cpu/io/内存/带宽的消耗,3)指定字段查询,在表结构变更时,能保证对应用程序无影响* |
| 42 | + - insert必须指定字段,禁止使用insert into T values() |
| 43 | + - 隐式类型转换会使索引失效,导致全表扫描 |
| 44 | + - 禁止在where条件列使用函数或者表达式 *导致不能命中索引,全表扫描* |
| 45 | + - 禁止负向查询以及%开头的模糊查询 *致不能命中索引,全表扫描* |
| 46 | + - 禁止大表JOIN和子查询 |
| 47 | + - 同一个字段上的OR必须改写问IN,IN的值必须少于50个 |
| 48 | + - 应用程序必须捕获SQL异常 *方便定位线上问题* |
| 49 | + |
0 commit comments