扩展字段,到时候有新的需求再加不可以吗?
![]() | 1 flyqie 2023-09-25 15:09:47 +08:00 ![]() 因为,到那个时候就不好加了啊,一堆问题。。 |
![]() | 2 me1onsoda 2023-09-25 15:12:31 +08:00 在一张千万级以上的表上加个字段,会导致锁表多长时间? |
![]() | 3 yidinghe 2023-09-25 15:14:45 +08:00 习惯使然,大部分情况其实是不需要加的。一般的系统设计中,100 张表里面可能只有不到 10 张表记录数最多,其他的表可能只有几十到几千条记录,唯独这几张表记录数能达到千万上亿条。这在设计的时候就可以预见到,所以剩下 90% 的表都不需要 ext 字段。 |
4 yuyang1992test OP 为什么不好加了? |
![]() | 5 mightybruce 2023-09-25 15:30:00 +08:00 线上数据库是不能随便修改数据库结构, 如果没有做不停机迁移的方案,会导致事故。 加这个,相当于考虑以后数据库变动了。 这种扩展也是建立在该表多数字段都已经非常确定的情况下, 其实还可以通过元数据表和字段来做。 |
6 28Sv0ngQfIE7Yloe 2023-09-25 15:31:57 +08:00 |
![]() | 7 chendy 2023-09-25 15:32:45 +08:00 才加一个明显不够高级 我们这系统预留 30 个 varchar20 个 number ,上面再包一层管理扩展字段的处理 |
9 devopsdogdog 2023-09-25 15:37:25 +08:00 ![]() 一个垃圾运维,认为是 程序设计,模块化,后续扩展等考虑 说锁表的大哥,可能是我经验少,mysql 不是 行锁+ online ddl ,千万级别在我看来问题不大,不要高峰期操作就行了 |
![]() | 10 wuwukai007 2023-09-25 15:37:33 +08:00 mysql 8.0 之后不存在问题 |
11 brader 2023-09-25 15:44:41 +08:00 ![]() @devopsdogdog “不要高峰期操作”这点就能把人恶心坏。我曾经遇过一个傻逼领导,老项目,那时候发版又频繁,有时候难免会有需要改老表的字段结构,如果用你说的这个方案,那领导动不动就给我说,那你就加班搞下啊,我们那个业务低峰期大概是晚上 11 点多,每周都会发 1-2 个版,我加他 MMP 。 从此之后,那些屎山老表,我是能不动就不动,也不优化,有需要我就直接扩表扩字段搞 |
12 zxf9799 2023-09-25 15:54:32 +08:00 @devopsdogdog 不是高峰期根本就是句蠢话,有几个网络公司客户不是 24 小时跑业务的。还有就是你晚上 3.4 点爬起来给客户搞了一小时,你们公司是怎么调休的,有点好奇 |
13 devopsdogdog 2023-09-25 15:56:21 +08:00 @brader 无论大小系统都会错开高峰期操作 ,作为运维 我只能说是正常。 也不一定要 最低峰高,错开最高峰就行了,对服务器和代码性能有信心的话,高峰期操作也无伤大雅 |
![]() | 14 pannanxu 2023-09-25 16:01:06 +08:00 很多情况下这个字段很好用,比如:不需要查询,但是字段太多,懒得加字段,前端直接构建 json 写入。当然这个仅限于内网项目可以这样玩。可以避免不必要的攻击。 |
![]() | 15 F281M6Dh8DXpD1g2 2023-09-25 16:01:55 +08:00 旧时代的眼泪 |
![]() | 16 lambdaq 2023-09-25 16:02:18 +08:00 ![]() mongodb:啊对对对 |
![]() | 17 Vegetable 2023-09-25 16:04:05 +08:00 如果预留了字段,开发自己直接就能用了,如果没有预留,发布流程会变得很麻烦。 |
18 devopsdogdog 2023-09-25 16:08:45 +08:00 @zxf9799 可能我菜,没遇过这个量级的公司。如果支持 online ddl 非特殊情况 其实是不影响 运行的。 不知道你是开发还是运维,反正干了好几年运维了,除非紧急更新,算操作规范吧,不然肯定是避开高峰期的。 你总不可能 24 小时 100%负责吧。 |
![]() | 19 dallaslu 2023-09-25 16:13:19 +08:00 这也不高级啊。十多年前经手的项目,每个表都有 200 多个字段,起名 a1,a2,a3, ...a200 |
20 lovelylain 2023-09-25 16:18:19 +08:00 via Android 加个 text 类型的 ext 字段,新增字段如果不需要检索,直接改 proto 就完成了新增,比加一个表字段成本低多了,很多时候新增字段都没有检索需求。 |
![]() | 21 yolee599 2023-09-25 16:26:40 +08:00 有一个 pt-online-schema-change 的方案,使用触发器把旧表数据迁移到新表上。 |
![]() | 22 cqx2005 2023-09-25 16:40:28 +08:00 mysql5.7 , 对于资料表,都会建立 extra 字段,JSON 类型。 生产环境,单表上亿的表有 4-5 张。 |
![]() | 24 LDa 2023-09-25 16:57:49 +08:00 为了应对频繁的“小 X 啊,我想加个字段” 一个 JSON extra 完事 |
![]() | 25 beneo 2023-09-25 16:59:33 +08:00 @brader 其实你是领导也是一样这样要求,在凌晨做表变更。我觉得核心的问题是你不觉得公司的业务能给你带来价值,你觉得现在的工作占据了你的休息时间。 |
28 xiaogezz 2023-09-25 17:36:21 +08:00 真这么高的负载还用 mysql ? |
![]() | 29 bigjack 2023-09-25 17:43:59 +08:00 一般预留 10-20 个都属于正常的,变更数据库确实比较麻烦 |
30 MeteorCat 2023-09-25 17:47:31 +08:00 via Android 我们之前建表默认留了 ext1 ,2 ,3 字段,有些没用过但是有些频繁变动业务的时候完全不够,感觉看表是放什么业务 |
![]() | 31 veike 2023-09-25 17:54:06 +08:00 加子表不行吗? |
![]() | 32 lincanbin 2023-09-25 17:55:42 +08:00 ext1 、ext2 、ext3 、ext4…… 类型全部都是 string |
![]() | 33 zhangxudong 2023-09-25 18:00:16 +08:00 @devopsdogdog #9 mysql 5.7 的 online ddl 千万级的大表,还是有影响的。mysql8.0 的 online ddl 优化了加字段的操作,直接操作元数据了,大表可以秒级加字段 |
![]() | 34 encro 2023-09-25 18:26:17 +08:00 @me1onsoda @Morii @zhangxudong 8.0.12 instant 真爽! ``` ALTER TABLE `user` ADD `status` (1) DEFAULT 0, ALGORITHM=instant ``` |
35 yuyang1992test OP ![]() 总结:千万级的表,alter table 会导致锁表时间较长,mysql8.0 解决了这个问题 |
36 runzekk 2023-09-25 19:22:05 +08:00 不加。 容易引起误会的字段加了有啥用。 楼上说变更有问题的用的不是云数据库吗,云数据库变更早就有不锁表不停机方案了。 如果不是云数据库,自己怎么弄不行。 |
37 peyppicp 2023-09-25 20:05:43 +08:00 我们一个分片 5kw 条数据,700+分片,没有这种扩展字段,每次上个需求都得慢死 |
38 rophie123 2023-09-25 21:16:13 +08:00 mysql5 ,亿级别的数据量,说加就加了,经常干 |
![]() | 39 BeautifulSoap 2023-09-25 21:24:02 +08:00 via Android 这不光是 alter 的问题,改表的话发布流程多挺多步骤更麻烦也是一点。 预留的话直接代码里用预留字段就行了不用改数据库。 当然,无所谓这点工作成本的话最新版 mysql 倒是无所谓 |
![]() | 40 zhb1993 2023-09-25 21:35:40 +08:00 上次我在线上数据库( MySQL )中,直接修改了一个字段的长度,然后数据库挂了 10 分钟 |
![]() | 41 itechify PRO 就奇怪了,加那么多 ext 字段,记得什么业务含义吗?没有语义的字段 |
![]() | 42 Daniel17 2023-09-25 21:51:50 +08:00 @oneisall8955 同问 |
43 ntedshen 2023-09-25 22:03:52 +08:00 我们这边的 apache hive 基本上每个表都会留三到五个 ext ,最少也得留一个。。。 主要改表结构这件事你不知道会导致什么后果,但是不改明显是没什么大问题的。。。 改结构你改完 sql 脚本还要去数据同步里面改映射,改完映射整个数据流程得全部重新审批重新发布。。。 然后外部 rds 和各种视图也要跟着全部改一遍,都不是不在一个部门的问题,可能要跨好几个部门。。。 用通配符的部分全部都会报错,不用通配符的有的表百十个字段你最好也得通知一遍说不定有什么影响业务的问题。。。 留个 ext 要哪天不够用大不了加个分隔块 concat 一下就完了。。。 |
![]() | 44 ljsh093 2023-09-25 23:24:56 +08:00 @yuyang1992test #4 加字段要走流程 ![]() |
45 lanlanye 2023-09-26 02:17:21 +08:00 你们是没有文档库吗:( |
46 iseki 2023-09-26 07:54:52 +08:00 via Android 这不是高级不高级的问题,这是整天加字段加烦了,旧字段还变来变去改烦了。你看看没准这种情况下,程序里那个 ext 字段都按 any 类型处理的 |
![]() | 47 tramm 2023-09-26 08:27:15 +08:00 看到这个问题, 联想到我们的数据库, 我想请教下各位大佬: 我们有个数据库有几千万记录, 有两列是 Geometry 类型的数据, 整个表占用将近 1T 的空间, 该如何将这两列 Geometry 去掉? MySQL 8.0.31 因为现在完全用不到这两列了. 去年 5 月份, 想直接删除这两列的, 然后导致数据库直接挂了, 启动也启动不起来. 把那个表对应的物理文件删了才启动起来... |
![]() | 48 xshell 2023-09-26 08:52:24 +08:00 MySQL8.X 以后 DDL 秒加字段。 |
![]() | 49 jsdi 2023-09-26 08:54:38 +08:00 mysql8.0 有快速加列,能实现秒级加列,不锁表 |
![]() | 50 luzein 2023-09-26 08:58:52 +08:00 别的我不知道,就我经历的 java 项目 之前数据库只有 a,b,c 三个字段 mybatis 中:Select a,b,c (不允许写星号) from table java PO/DTO/VO 中:field a, field b, field c 现在加个字段 d ,那就得从数据库开始一直到 VO 都得对应的增加,还可能有部分你不了解的地方未覆盖 改动就意味着回归测试,挺麻烦的 所以预先留 1 个字段,甚至多个,可以极大的简化这个流程。 当然你说预留的还不够,不还得新加吗?如果预留不够,那说明改动真的不算“小”改动了,那就得专门创建个任务去做这个事情了 |
51 sdwgyzyxy 2023-09-26 09:21:02 +08:00 对于上亿级的表,即使你把新增字段的 SQL 发给运维,他们也会直接拒绝,我们一般都是停服、复制表、加字段、删表、表名修改、启动服务,没其他好办法,只能停服。 |
![]() | 53 chendy 2023-09-26 09:27:50 +08:00 @yph007595 有专门的一个抽象层,管理字段定义和 sql 转义这些,使用的时候写的是字段名比如 userType ,实际执行查的是 c_ext_varchar_001 这样的字段 |
![]() | 54 pannanxu 2023-09-26 09:28:46 +08:00 @oneisall8955 ext 字段如果是 json 可以在 java 中直接映射为对象,mybatis 、jpa 都可以,所以只需要在代码中建立一个对象即可。 |
55 jonsmith 2023-09-26 09:38:03 +08:00 与技术无关,跟公司管理有关。 上家公司的很多表都有 exta 扩展字段,一个大 json ,什么垃圾数据都往里塞,导致历史数据不一致,层出不穷的 bug 。 刚开始我也不习惯这么做,后来就从了。因为每次新增字段需要领导评审、一番掰扯,领导技术很垃圾、掰扯不清。 |
![]() | 56 SmiteChow 2023-09-26 09:38:11 +08:00 ![]() 面向未来屎山编程,面向一厢情愿的 7*24h 服务质量编程。 影响国计民生的系统都允许闲时停水停电停服维护,就 TM 你做的系统了不起,不能停。 |
57 wu00 2023-09-26 09:42:10 +08:00 屎山就是这么堆起来的 十年前这样做属于有经验 今天还在这样做就太那啥了... |
![]() | 58 dzdh 2023-09-26 09:47:12 +08:00 不怕加 ext 。怕的是这一个字段有不同作用。类型是 varchar ,存的数据一会儿是数字,一会儿是 string ,再隔一行还可能是 json |
59 salmon5 2023-09-26 09:48:18 +08:00 这种现在数据库上应该不是问题,10 年前确实是个问题,现在应该不是问题 |
![]() | 60 zdking08135 2023-09-26 09:48:20 +08:00 via Android 增加不必要的字段就是有问题。比起这种意义不明的设计,还是想法避免单表千万行更靠谱。 |
![]() | 61 samin 2023-09-26 09:50:38 +08:00 那你这高级程序员经验还不够,一般有经验都加 ext1,ext2,ext3 ,为什么没有 4 ? 老祖宗说过 事不过三 |
![]() | 62 itechify PRO @pannanxu 即使 mybatis 或 jpa 可以指定 column_name 如果要写 mapper 或 native sql 的呢?即使代码里面没有写,自己查表数据时候也得写吧 况且还会与别的团队,或新入职员工交流呢 |
![]() | 63 zdking08135 2023-09-26 09:52:30 +08:00 via Android |
64 Huelse 2023-09-26 09:56:57 +08:00 postgresql 随便改,不存在上述问题 |
![]() | 65 qiumaoyuan 2023-09-26 10:00:43 +08:00 显得高级 |
![]() | 66 pannanxu 2023-09-26 10:04:51 +08:00 @oneisall8955 #62 自定义的 sql 一样可以映射呀,为什么不可以,已经创建实体对象了,还需要什么交流,看代码不就完了吗。再说了,extra 一般存储相对边缘的字段,谁常用的字段放那里啊。 |
67 bwt 2023-09-26 10:05:01 +08:00 via Android 我们用的是 pt-online 原理是创建一个新表,然后在老表新建一个触发器,将老表的写操作同步到新表,同时做数据迁移,迁移完成后 rename 表名 这个流程不用停服 |
68 Masoud2023 2023-09-26 10:08:46 +08:00 单表千万你们不分表的? OLTP 这样玩真的 ok ? |
![]() | 70 ElmerZhang 2023-09-26 10:34:41 +08:00 首先,某业务表分了 1024 张表,每张表几百万数据,改一次表真的很麻烦。 其次,有些不重要的不会作为查询条件的数据,直接一个 json 扔 ext 里是最简单的。 用了 postgres 之后,我一般留一个 jsonb 字段作为 ext 。 |
![]() | 71 wuhao1 2023-09-26 10:37:50 +08:00 count(*) =266493624 |
72 tairan2006 2023-09-26 10:47:46 +08:00 ext 放个 json ,还是挺实用的 不过要搜索的字段还是老老实实加,或者加张新表 |
73 yuyang1992test OP @ljsh093 流程不就是审批个 sql 吗?难道随着业务发展,就不加新表,加新字段了吗?就磕着 ext 字段造? |
74 yuyang1992test OP @lanlanye 文档型数据库吗?没怎么用过 |
75 yuyang1992test OP @luzemin 那你预留的这个字段以后用到了还改字段名字吗? |
76 yuyang1992test OP @jonsmith 一般都会技术评审,最后审批的时候老板也不会看,直接通过 |
77 yuyang1992test OP @tairan2006 确定,需要查询的还是放新字段才能用到索引 |
78 yuyang1992test OP @ElmerZhang 我这边分表一般是按照 10 ,1000 来分,这样如果分表键是数字,就可以直接根据尾号就知道是哪张表了 |
![]() | 79 ElmerZhang 2023-09-26 12:01:08 +08:00 @yuyang1992test 按 2 的 N 次方来分的好处是,8 台机器抗不住时,可以扩到 16 台,再抗不住,扩到 32 台,依次类推。每台机器的压力始终是平均的。 |
![]() | 81 idblife 2023-09-26 13:11:51 +08:00 不是高级程序员,是没用过 oracle 和新版本 mysql 的老程序员 |
![]() | 82 pengtdyd 2023-09-26 13:14:40 +08:00 你确定是高级吗?关系建模其中的一条是不要预留字段,需要了再加。 |
![]() | 83 zoharSoul 2023-09-26 13:19:12 +08:00 没见过, 几个大厂都呆过 |
![]() | 84 darksheep9527 2023-09-26 13:32:36 +08:00 @tramm 新建一个表 把除了 Geometry 类型之外的列数据导过去 然后删掉旧的那个表 不然清了列的数据 还要手动清理空间碎片 |
![]() | 85 8355 2023-09-26 13:53:24 +08:00 |
![]() | 86 coala 2023-09-26 14:00:32 +08:00 之前给千万条的订单表加字段, 选择时间在凌晨 3 点,备足硬盘和内存, 跑了几十分钟.. |
87 yc8332 2023-09-26 14:10:45 +08:00 看来还是有不少人因为大表加字段挂过嘛。。。好人谁去大表加字段,而且正常线上挣钱的业务哪能停机维护让你加字段。。数据库升级更少了。大版本 N 年才会升级一次。 |
![]() | 88 nightsky 2023-09-26 14:16:34 +08:00 不如联表 |
89 seanzxx 2023-09-26 14:59:02 +08:00 我们公司的用户表预留了 20 个 varchar 做扩展,ext1~ext20 , 然后不同客户的用户,扩展字段的含义还不一样, 还搞出一张扩展字段定义表,保存每个客户的扩展字段是什么意思 |
90 fishily1993 2023-09-26 15:08:06 +08:00 alter 之后几个小时的主从延迟,告警邮件短信停不下来的时候,你就知道为啥了。 |
![]() | 91 luzemin 2023-09-26 17:18:50 +08:00 @yuyang1992test #75 等“大”改动的时候一并优化,没改动前就“暂时”用这个语义很差的名字 |
![]() | 92 nekoneko 2023-09-26 17:45:21 +08:00 |
93 yuyang1992test OP @seanzxx toB 的系统? |
94 littlewing 2023-09-26 18:55:00 +08:00 ![]() MySQL 5 时代遗留下来的一些规定,现在 MySQL 8.0 加列都是秒加的 |
96 tclm 2023-09-27 07:06:39 +08:00 via Android 不是很好的实践。 |
97 MRlaopeng 2023-11-06 11:45:43 +08:00 @littlewing ,,2 亿数据的表,,,并不能秒加 |
98 littlewing 2023-11-06 12:05:37 +08:00 @MRlaopeng 不管多少都是一样秒加,因为只修改元数据,不动数据,和数据多少无关 |
99 MRlaopeng 2023-11-07 15:22:30 +08:00 @littlewing ,,那为啥我的 MySQL8 加字段不能秒加,, |
100 littlewing 2023-11-07 15:31:26 +08:00 @MRlaopeng 忘了说了,现在应该是只支持加到最后,不支持加到中间 |