暂无图片
暂无图片
8
暂无图片
暂无图片
暂无图片

数据库设计(MySQL)避坑指南

原创 aisql 2024-03-13
1689

1、主键设计的坑

a、MySQL是索引组织表,所以一定要显示指定主键

没有显示指定主键,MySQL部份功能会受限,比如组复制
没有显示主键,当表要做关联查询时会比较难受
没有显示主键,如果也没有指定唯一键,那么可能会造成删除异常,修改异常

b、不要使用业务字段当主键

如果使用业务字段当主键,当业务发现变化了,原有的主键字段不符合了,需要增加或减少字段对于已上线的系统来说都是毁灭性的,特别是当时间长这个表变成大表后,后面要变更主键可能必须停业务才能操作

c、不要使用组合主键

不建议使用组合主键,每个主键都是二级索引的叶子,如果使用组合主键,极大增加了存储需求

d、不用UUID

理由和C一样

f、自增ID

当有主从表(父子表)时,从表关联主表依赖主表自增产生的ID,那就必须在主表插入后还要查询一次。使业务开发更复杂

建议

使用业务生成雪花ID做为主键,或数据库单独拿一个表来生成自增ID

2、函数设计的坑

开发函数时记得带上DETERMINISTIC 关键字 声明为确定性函数
如果声明为非确定函数会严重影响查询的性能 参见我的文档 确定性函数

3、字段设计的坑

a、时间类型声明为datetime 而非TIMESTAMP 类型

2038不远了,不要再埋坑,而且从5.6版本后MySQL优化了datetime占用的存储空间
详见我的文档 MySQL数据类型存储空间占用–日期型

b、varchar类型声明 注意长度

当修改字符宽度有两个情况不能online ddl
1、减少宽度
2、跨越255这个坎
看下面列子

drop table stt; create table stt ( id int not null, str1 char(10) not null, str2 varchar(60) not null, str3 varchar(70) not null, primary key(id) ) engine = InnoDB default charset = utf8mb4 ROW_FORMAT=COMPACT ;

image.png
将str2列由60减少到50 是不能online ddl的 减少宽度不能INPLACE

image.png
将 str2列由60增加到64也是不能online ddl的 跨越255这个坎不能INPLACE

image.png
而将 str3列由80增加到84是能online ddl的

所以我们在声明varchar的时候 如果发现靠近255的时候 不妨加大一点点,为了以后在线变更能更快速。
怎么算空间占用,详细见我的文档 MySQL数据类型存储空间占用–字符串

4、字符集的声明

创建表的时候,尽量指定字符集并指定排序规则,列上也同理
这里看一个官方例子

CREATE TABLE t1 ( c1 CHAR(10) CHARACTER SET latin1 ) DEFAULT CHARACTER SET latin1 COLLATE latin1_danish_ci; show create table t1;

image.png
可以看到c1列的排序规则是latin1_swedish_ci 而不是创建表指定的 latin1_danish_ci
官方原文档在此

5、关联表、主从表(父子表)

这种关系紧密的表的设计在常用查询字段一定要加上冗余,以减少关联

6、读写分离应用需注意的点

目前几乎所有架构都会应用到读写分离技术,写操作在主库上,报表等查询在从库上,减少主库负担,从而提升TPS.
但应用中有些对数据效验的查询,比如订单是否支付成功的效验。这种关键的效验一定要确认走主库查询,如果这种效验走从库查询来效验,一旦遇到主从延迟,会造成你的数据混乱,而且极其难排查问题原因。

欢迎大家关注我的微信公众号,分享MySQL相关知识
扫码_搜索联合传播样式白色版.png

最后修改时间:2025-01-16 19:31:38
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论

目录
  • 1、主键设计的坑
    • a、MySQL是索引组织表,所以一定要显示指定主键
    • b、不要使用业务字段当主键
    • c、不要使用组合主键
    • d、不用UUID
    • f、自增ID
    • 建议
  • 2、函数设计的坑
  • 3、字段设计的坑
    • a、时间类型声明为datetime 而非TIMESTAMP 类型
    • b、varchar类型声明 注意长度
  • 4、字符集的声明
  • 5、关联表、主从表(父子表)
  • 6、读写分离应用需注意的点