上一篇:深夜看了张一鸣的微博,让我越想越后怕

作者:李瑜宁
来源:https://juejin.cn/post/6844903640990220302

笔者的动态字段扩展解决方案主要针对 Mysql 5.7.8 以下版本,在 Mysql 5.7.8 已经新增 JSON Data Type,同样适用该方案,而且情况变得更加简单。

痛点

软件行业唯一不变的就是变化,比如功能上线之后,客户或 PM 需要对已有的功能增加一些合理的需求,完成这些工作必须通过添加字段解决,或者某些功能的实现需要通过增加字段来降低实现的复杂性等等。

这些问题都会改动线上的数据库表结构,一旦改动就会导致锁表,会使所有的写入操作一直等待,直到表锁关闭,特别是对于数据量大的热点表,添加一个字段可能会因为锁表时间过长而导致部分请求超时,这可能会对企业间接造成经济上的损失

解决方案

增加 json 格式的扩展字段。

下面配合一些代码来描述这个解决方案,读者便于去理解。另外,MySQL 系列面试题和答案全部整理好了,微信搜索互联网架构师,在后台发送:2T,可以在线阅读。

mysql 数据库脚本:

DROP TABLE IF EXISTS `cs_dustbin`;
CREATE TABLE IF NOT EXISTS `cs_dustbin` (`id` VARCHAR(45) NOT NULL COMMENT '主键自增id',`rfid_no` VARCHAR(20) NOT NULL COMMENT 'rfid 卡号',`state` INT(1) NOT NULL COMMENT '垃圾桶状态:0:已注销;1:未使用;2:待使用;3:已使用(绑定收集点);',`user_id` INT NOT NULL COMMENT '登记人,负责录入垃圾桶的人',`type` INT(1) NOT NULL DEFAULT 1 COMMENT '垃圾桶类型:1:餐厨垃圾桶',`street_code` INT(11) DEFAULT NULL COMMENT '所在镇街 code,根据状态,这里的含义可能是领用镇街、退还镇街。',`create_time` DATETIME NOT NULL DEFAULT now() COMMENT '创建时间',`update_time` DATETIME NOT NULL DEFAULT now() COMMENT '更新时间',`ext` VARCHAR(1000) NOT NULL DEFAULT '{}' COMMENT '扩展字段',...PRIMARY KEY (`id`))
ENGINE = InnoDB
COMMENT = '垃圾桶表';

Java 代码:

import com.alibaba.fastjson.JSON;
import lombok.Data;import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.List;/*** 垃圾桶实体* Created by Blink on 6/28/2018 AD.** @author Blink*/
@Data
public class Dustbin {private String id;/*** rfid 卡号*/@NotNullprivate String rfidNo;/*** 垃圾桶状态:0:已注销;1:未使用;2:待使用;3:已使用(绑定收集点);* 对应 Dustbin.StateEnum 类*/@NotNullprivate Integer state;/*** 录入垃圾桶的人员id*/@NotNullprivate Long userId;/*** 垃圾桶类型:1:餐厨垃圾桶* DefaultValue: 1*/@NotNullprivate Integer type;/*** 所在镇街 code* 根据状态,这里的含义可能是领用镇街、退还镇街*/private Integer streetCode;/*** 创建时间* defaultValue : now()*/@NotNullprivate Date createTime;/*** 更新时间*/@NotNullprivate Date updateTime;/*** 扩展字段,详细数据查看 DustbinExt.java* DefaultValue: {}*/private String ext;...public DustbinExt getExtObject() {return JSON.parseObject(this.getExt(), DustbinExt.class);}public void setExtObject(DustbinExt ext) {this.ext = JSON.toJSONString(ext);}/*** 垃圾桶扩展属性* Created by Blink on 6/28/2018 AD.** @author Blink*/@Datapublic static class DustbinExt {/*** 所在镇街* 根据状态,这里的含义可能是领用镇街、退还镇街、绑定的镇街*/private String street;/*** 客户(收集点)id,绑定收集点的时候需要填入* 根据目前的需求(2018-06-29),当收集点解绑的时候* 需要保存垃圾桶最新绑定收集点名称,所以在解绑垃圾桶的时候不会把这个信息删掉* 只有当绑定收集点的时候才把他覆盖*/private Long customerId;/*** 客户(收集点)名称,绑定收集点的时候需要填入* 根据目前的需求(2018-06-29),当收集点解绑的时候* 需要保存垃圾桶最新绑定收集点名称,所以在解绑垃圾桶的时候不会把这个信息删掉* 只有当绑定收集点的时候才把他覆盖*/private String customer;/*** 损坏部位* 1:桶盖;2:桶口;3:桶身;4:桶轴;5:桶底;6:桶轮;* 对应 DustbinDamagePartEnum 类*/private List<Integer> parts;}...
}

mysql 脚本可以看到扩展字段的信息:

ext VARCHAR(1000) NOT NULL DEFAULT '{}' COMMENT '扩展字段'

可以看到这么一段 Java 代码:

.../*** 扩展字段,详细字段查看 DustbinExt 类* DefaultValue: {}*/
private String ext;public DustbinExt getExtObject() {return JSON.parseObject(this.getExt(), DustbinExt.class);
}public void setExtObject(DustbinExt ext) {this.ext = JSON.toJSONString(ext);
}...

可以看到 ext 字段就是用来存储 json 格式的数据,它可以动态地增加任何字段,甚至是对象,不需要通过 DDL(Data Definition Language) 去创建字段,非常适合用来解决上面提到的问题。

Java 代码在这里起到辅助性作用,通过定义一个内部类来管理扩展字段的属性,方便我们了解和管理扩展字段,提高代码的可读性和可维护性,java 这种方式也是笔者总结出来的较为优雅的做法(个人观点)。

局限性

有经验的读者可能会提出,ext 字段在 Mysql 5.7.8 以下版本无法对扩展字段中的某一个或一部分字段建立索引,因为 Mysql 5.7.8 版本以下不支持(Mysql 5.7.8 支持为 Json Data Type 建立索引)。

没错,这是这个解决方案的一个局限性,在 Mysql 5.7.8 以下版本,我的建议是, ext 扩展字段不要存储热点数据,只存储非热点数据,这样就可以避免查询操作,降低维护 ext 字段带来的成本和风险,那如何识别新增字段是不是热点数据呢?

这个需要结合实际业务需求来判断,也可以询问对业务和技术更有经验的同事,便于读者更快得出结论。

终极版解决方案

在一些极端的情况下,变化可能来得太快,而我们要的是减少变化带来的成本和风险,所以在表设计之初可以根据自身经验,或者找更有经验的人寻求帮助,预估一下需要预留多少个备用字段,再配合扩展字段,基本上可以把改变(添加字段)表结构的次数降至一个非常少的次数。

总结

在特殊情况下,通过扩展字段 + 预留字段基本上可以做到动态扩展字段,又不会影响为热点数据建立索引的情况,这样我们得到了一个非常灵活的表结构,便于我们应对未来的变化,但是请注意,要维护好我们的实体,包括里面的每一个字段,敬畏每一行代码。

感谢您的阅读,也欢迎您发表关于这篇文章的任何建议,关注我,技术不迷茫!小编到你上高速。

· END ·

最后,关注公众号互联网架构师,在后台回复:2T,可以获取我整理的 Java 系列面试题和答案,非常齐全。

正文结束

推荐阅读 ↓↓↓

1.不认命,从10年流水线工人,到谷歌上班的程序媛,一位湖南妹子的励志故事

2.如何才能成为优秀的架构师?

3.从零开始搭建创业公司后台技术栈

4.程序员一般可以从什么平台接私活?

5.37岁程序员被裁,120天没找到工作,无奈去小公司,结果懵了...

6.IntelliJ IDEA 2019.3 首个最新访问版本发布,新特性抢先看

7.漫画:程序员相亲图鉴,笑屎我了~

8.15张图看懂瞎忙和高效的区别!

一个人学习、工作很迷茫?

点击「阅读原文」加入我们的小圈子!

如何不改表结构动态扩展字段?相关推荐

  1. 不改表结构如何动态扩展字段

    笔者的动态字段扩展解决方案主要针对 Mysql 5.7.8 以下版本,在 Mysql 5.7.8 已经新增 JSON Data Type,同样适用该方案,而且情况变得更加简单. 痛点 软件行业唯一不变 ...

  2. 带你实现java根据表结构动态导入导出Excel

    你知道的越多,你不知道的越多 点赞再看,养成习惯 如果您有疑问或者见解,欢迎指教: 企鹅:869192208 前言 最近在甲方爸爸的要(威)求(逼)下,项目经理带来了客户的全新需求,希望能够在原有编辑 ...

  3. 11-【数据库】定义表结构的时间字段的两种方式

    1.方式一:定义时间字段默认值为NULL 若定义表结构的时间字段(eg:created_on.updated_on)是NULL.那在代码中连接数据库时要增加如下配置(红框中的配置):   来使得: 通 ...

  4. oracle改表结构非空字段类型,oracle 表结构的非完全复制

    今天有同事在问 复制表的时候 会把表的 not null 属性也复制过来,而他要求对复制过来的字段不加not null 字段 SQL> desc DW_ACCOUNT 名称            ...

  5. Mysql使用Key/Value方式存储动态扩展字段、对象与HashMap的相互转化

    1.背景 在项目刚刚进入开发阶段设计表时,后期表的字段很可能会增加,可以设计出预留字段来应对.但是假如你的数据数据非常庞大且,那么执行修改表语句时会长时间锁表.而且假如一张表支持许多个客户,每个客户的 ...

  6. SQL语句查看表结构和修改字段长度

    MySQL 和 SQLserver 数据库: 查看表结构: select * from information_schema.columns where table_name='表名' 修改字段长度: ...

  7. plsql 查看表结构所有的字段_产品操作MySQL第2篇 – 设计一张表

    本资料为产品岗位作为日常工作参考,语言口语化 At 2019/4/16 By David.Yang 了解数据表的"字段"概念 我们前面说到,Excel.数据表都有一个表头, 比如学 ...

  8. ABAP中不修改内表参照的结构,给内表/结构体增加字段

    参照的结构体中字段数不够,除了se11修改结构之外,还可以在声明时用INCLUDE,如果不修改结构,在SE37运行测试是看不到这个字段的. Definition TYPES|DATA:BEGIN OF ...

  9. Mysql表结构升级_mysql表结构升级时根据字段是否存在执行相应操作

    [问题描述] 某信息系统,使用MYSQL做数据库服务,版本5.0.45,在准备对表结构进行升级时,使用sql脚本对表结构进行更改,包括增加列.更改列等操作,为防止重复运行升级脚本而出现错误,拟在进行a ...

  10. tpshop表结构说明(整理中)

    TPshop表结构 tp_account_log -- 账户表 字段名 字段类型 默认值 描述 log_id mediumint(8) unsigned   日志id user_id mediumin ...

最新文章

  1. Git之回退已经提交到远程仓库的代码(已经push的代码)
  2. 计算机网络产生的历史背景,网络技术背景及sdn概述.pdf
  3. 图像处理中常见的时域与频域区别与关系
  4. 基于Docker搭建私有镜像仓库
  5. Logstash入门简介
  6. 基于JAVA+SpringMVC+Mybatis+MYSQL的网上相册展示系统
  7. 你可能不知道的10条SQL技巧,涨知识了!
  8. 智能优化算法:原子搜索优化算法 -附代码
  9. 源码编译安装screen
  10. 如何使用GitHub客户端
  11. 云计算机应用论文,关于云计算应用的研究(本科毕业论文)
  12. 小结——scanf和scanf_s的区别以及最近练习的一些习题
  13. A Survey on Conversational Recommender Systems(2021)阅读笔记
  14. Oracle greatest函数
  15. JavaScript:实现按字典顺序查找给定字符串的所有不同的非空子序列算法(附完整源码)
  16. 2022年国赛建模评估
  17. svn提交报错Unexpected HTTP status 413 'Request Entity Too Large' on
  18. 一对数的和等于给定的数
  19. 论文笔记|固定效应的解释和使用
  20. outlook你的邮件服务器证书无效,IMAP提示由于证书无效或不可信,无法连接到服务器...

热门文章

  1. Swift编程-闭包Closure
  2. 安装包被误删了可以用EasyRecovery恢复吗
  3. Docker 容器十诫
  4. [洛谷P3388]【模板】割点(割顶)
  5. Radon变换——MATLAB
  6. 图片加载库之Glide和Picasso对比
  7. angular4学习记录 -- 依赖注入
  8. 物联网在发展上,特别是消费性产品,为何进展如此缓慢?
  9. 配置zend studio的代码格式化文件及远程单步调试
  10. x5cloud云平台---------------网络彩讯