MySQL最佳实践
一、MySQL建表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | CREATE TABLE `t_xxxxx` ( `Fid` bigint (255) NOT NULL AUTO_INCREMENT COMMENT '编号' , `Fbuss_id` varchar (100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '业务主键' , `Fstatus` tinyint(4) DEFAULT '0' COMMENT '状态 //1、基于阶段定义 错位定义 10,20,30,如果后续新增11,12节点容易修改 2、状态机根据业务条件扭转,防止并发 `Ferror_code` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT ' 错误码 ', `Ferror_msg` varchar(5000) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT ' 错误信息 ',<br>`Fdetail` text COMMENT ' 明细 ', // 基于领域驱动的值对象设计,内部可定义子流程状态,已执行的子节点禁止重复执行,失败的节点从当前开始重复执行<br>`Fstart_time` datetime COMMENT ' 任务开始时间 ',<br>`Fend_time` datetime COMMENT ' 任务结束时间 ',<br>`Fretry_times` int COMMENt ' 任务最大重试次数 ', //当子任务执行成功后,修改重试次数为0,便于后续子流程的重试次数从0开始 `Fcreator` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, `Fcreate_time` datetime DEFAULT CURRENT_TIMESTAMP, `Flast_operation_user` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, `Fmodify_time` datetime DEFAULT CURRENT_TIMESTAMP, `Fversion` int(11) DEFAULT NULL COMMENT ' 数据版本号', PRIMARY KEY (`Fid`), UNIQUE KEY `idx_bussiness_id` (`Fbussiness_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE =utf8mb4_general_ci; |
1、业务主键 Fbuss_id:并发情况避免重复插入
2、版本号 Fversion: 并发情况基于乐观锁CAS,避免ABA重复更新问题
3、业务错误码 Ferror_code: 预留基于状态机中途特殊异常问题
4、分阶段状态 Fstatus: 流程特别长,记载每个阶段状态,可无限扩展
5、记载最后修改操作 Fmodify_time和Flast_operation_user
CREATE TABLE `t_xxxxx_log` (
1 2 3 4 5 6 7 8 9 10 11 12 13 | <em id= "__mceDel" >`Fid` bigint (255) NOT NULL AUTO_INCREMENT COMMENT '编号' , `Fxxx_id` bitint(255) NOT NULL COMMENT '业务外键' , `Fstatus` tinyint(4) DEFAULT '0' COMMENT '状态 //1、基于阶段定义 错位定义 10,20,30,如果后续新增11,12节点容易修改 2、状态机根据业务条件扭转,防止并发 `Frequest_msg` text COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT ' 请求报文 ', `Fresponse_msg` text COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT ' 响应报文 ',<br> `Fcreator` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, `Fcreate_time` datetime DEFAULT CURRENT_TIMESTAMP, `Flast_operation_user` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, `Fmodify_time` datetime DEFAULT CURRENT_TIMESTAMP, `Fversion` int(11) DEFAULT NULL COMMENT ' 数据版本号', PRIMARY KEY (`Fid`), UNIQUE KEY `idx_bussiness_id` (`Fbussiness_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE =utf8mb4_general_ci;</em> |
日志记载规范
1、主表任何状态变更,均记载日志
2、每次修改主表状态,均修改主表Fmodify_time
3、日志记载before和after信息,记载状态流变更
二、MySQL规范
1、show table status 'xxx表'
查看avg_row_length是否超过100字节,即为宽表
查看Date_free字段,如果字段>0,代表有磁盘碎片
2、单表记录<5kw条, 单行少于8k 8*1024
日新增<1w 单库单表
1w<日新增<10w db.t_table_yyyy 300*12=3600
10w<日新增<100w db.t_table_yyyymm 3000*12=36000
日新增>100w db.t_table_yyyymmdd
日新增记录数在1000W笔以上,且分布在不同的实例上 db_yyyymm_xx.t_table_dd_y
日新增记录数在1000W笔以上 db_yyyymm.t_table_dd_x
百库10表,总记录数在亿级别 db_xx.t_table_y
3、表规范 t_xxxx, 字段规范 F_xxxx
主键规范 pk_
唯一索引规范 uk_
其他索引 idx_
所有表字段加上Fcreate_time 和Fmodify_time字段
Fmodify_time datetime DEFAULT CURRENT_TIMESTAMP
4、金额字段 bigint
5、单表字段个数<100
6、避免text类型,如果需要放入另外张表
7、状态字段使用 unsigned tinyint
8、int类型主键使用 UNSIGNED
9、禁止字段defualt null, 字符串 DEFAULT ''
10、扩展字段 json类型
三、 MySQL防重幂等实践
1、 插入防重:通过获取流水号服务,获取流水号,流水号生成算法 雪花片算法
2、更新ABA问题
页面打开:保留V1版本号
更新事前检测:再次获取实体版本号Vn, 如果Vn=V1继续,否则刷新页面数据有变更
更新事中:update …. Set Fversion=Fversion+1 Where Fbuss_id=’xxxx’ and Fversion=V1
3、支付安全设计
a、先获取交易单号
算法:Snowflake,Twitter分布式ID算法等
b、检验签名:防止入参内容被修改
c、业务有效性检验:from方转账余额后的总数不能<0
d、插入转账记录:
幂等性保证:通过主键防重,避免重复转账
对账:记载单笔转账记录的发起方、接收方和转账金额信息
操作安全:只允许insert和select, 禁止update和delete, 如果要取消流水记录,也是新增一条取消流水记录
e、CAS更新:
基于版本号,更新发起方和接受方
四、海量数据处理方案
冷热数据分离 -》 读流量分片 -》 写流量分片 -》 业务拆分
应用场景 | 解决方案 | 应用系统 | 数据库 |
高并发 | 水平扩展(复制) | 多机集群,提升并发力 |
读写分离(将流量打到不同DB) 如:商品读库、商品写库 |
垂直拆分(不同业务拆分) |
按业务域划分系统 如:商品系统、交易系统 |
按业务分库 (将流量打到不同DB) 如:商品库、订单库 |
|
大数据 | 业务分片(同业务分片) |
按功能点分开部署 如:秒杀系统 |
分库分表,提高数据容量 如:订单库按ID分库分表 |
水平拆分(稳定与易变分离) |
服务分层 功能与非功能分开 |
冷热数据分离、历史数据分离 | |
HA可用性 | 主备自动选举机制 | 服务网关汇报心跳、统一nacos地址访问 | 主从切换、选举机制 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)