V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yuyang1992test
V2EX  ›  程序员

高级程序员为什么喜欢建表的时候加个 ext 字段?

  •  2
     
  •   yuyang1992test · 247 天前 · 11435 次点击
    这是一个创建于 247 天前的主题,其中的信息可能已经有所发展或是发生改变。

    扩展字段,到时候有新的需求再加不可以吗?

    101 条回复    2023-11-07 16:23:07 +08:00
    1  2  
    flyqie
        1
    flyqie  
       247 天前   ❤️ 2
    因为,到那个时候就不好加了啊,一堆问题。。
    me1onsoda
        2
    me1onsoda  
       247 天前
    在一张千万级以上的表上加个字段,会导致锁表多长时间?
    yidinghe
        3
    yidinghe  
       247 天前
    习惯使然,大部分情况其实是不需要加的。一般的系统设计中,100 张表里面可能只有不到 10 张表记录数最多,其他的表可能只有几十到几千条记录,唯独这几张表记录数能达到千万上亿条。这在设计的时候就可以预见到,所以剩下 90% 的表都不需要 ext 字段。
    yuyang1992test
        4
    yuyang1992test  
    OP
       247 天前
    为什么不好加了?
    mightybruce
        5
    mightybruce  
       247 天前
    线上数据库是不能随便修改数据库结构, 如果没有做不停机迁移的方案,会导致事故。
    加这个,相当于考虑以后数据库变动了。
    这种扩展也是建立在该表多数字段都已经非常确定的情况下, 其实还可以通过元数据表和字段来做。
    Morii
        6
    Morii  
       247 天前
    @yuyang1992test

    一张 MySQL 表有 2000w 数据,这时候你 ALTER TABLE 一下,会发生什么?
    chendy
        7
    chendy  
       247 天前
    才加一个明显不够高级
    我们这系统预留 30 个 varchar20 个 number ,上面再包一层管理扩展字段的处理
    brader
        8
    brader  
       247 天前   ❤️ 19
    @Morii 会被通报批评
    devopsdogdog
        9
    devopsdogdog  
       247 天前   ❤️ 2
    一个垃圾运维,认为是 程序设计,模块化,后续扩展等考虑
    说锁表的大哥,可能是我经验少,mysql 不是 行锁+ online ddl ,千万级别在我看来问题不大,不要高峰期操作就行了
    wuwukai007
        10
    wuwukai007  
       247 天前
    mysql 8.0 之后不存在问题
    brader
        11
    brader  
       247 天前   ❤️ 2
    @devopsdogdog “不要高峰期操作”这点就能把人恶心坏。我曾经遇过一个傻逼领导,老项目,那时候发版又频繁,有时候难免会有需要改老表的字段结构,如果用你说的这个方案,那领导动不动就给我说,那你就加班搞下啊,我们那个业务低峰期大概是晚上 11 点多,每周都会发 1-2 个版,我加他 MMP 。
    从此之后,那些屎山老表,我是能不动就不动,也不优化,有需要我就直接扩表扩字段搞
    zxf9799
        12
    zxf9799  
       247 天前
    @devopsdogdog 不是高峰期根本就是句蠢话,有几个网络公司客户不是 24 小时跑业务的。还有就是你晚上 3.4 点爬起来给客户搞了一小时,你们公司是怎么调休的,有点好奇
    devopsdogdog
        13
    devopsdogdog  
       247 天前
    @brader 无论大小系统都会错开高峰期操作 ,作为运维 我只能说是正常。 也不一定要 最低峰高,错开最高峰就行了,对服务器和代码性能有信心的话,高峰期操作也无伤大雅
    pannanxu
        14
    pannanxu  
       247 天前
    很多情况下这个字段很好用,比如:不需要查询,但是字段太多,懒得加字段,前端直接构建 json 写入。当然这个仅限于内网项目可以这样玩。可以避免不必要的攻击。
    liprais
        15
    liprais  
       247 天前
    旧时代的眼泪
    lambdaq
        16
    lambdaq  
       247 天前   ❤️ 7
    mongodb:啊对对对
    Vegetable
        17
    Vegetable  
       247 天前
    如果预留了字段,开发自己直接就能用了,如果没有预留,发布流程会变得很麻烦。
    devopsdogdog
        18
    devopsdogdog  
       247 天前
    @zxf9799 可能我菜,没遇过这个量级的公司。如果支持 online ddl 非特殊情况 其实是不影响 运行的。

    不知道你是开发还是运维,反正干了好几年运维了,除非紧急更新,算操作规范吧,不然肯定是避开高峰期的。 你总不可能 24 小时 100%负责吧。
    dallaslu
        19
    dallaslu  
       247 天前
    这也不高级啊。十多年前经手的项目,每个表都有 200 多个字段,起名 a1,a2,a3, ...a200
    lovelylain
        20
    lovelylain  
       247 天前 via Android
    加个 text 类型的 ext 字段,新增字段如果不需要检索,直接改 proto 就完成了新增,比加一个表字段成本低多了,很多时候新增字段都没有检索需求。
    yolee599
        21
    yolee599  
       247 天前
    有一个 pt-online-schema-change 的方案,使用触发器把旧表数据迁移到新表上。
    cqx2005
        22
    cqx2005  
       247 天前
    mysql5.7 , 对于资料表,都会建立 extra 字段,JSON 类型。

    生产环境,单表上亿的表有 4-5 张。
    yinft
        23
    yinft  
       247 天前
    @lambdaq 你这句啊对对对 我耳边都有声音了 哈哈哈
    LDa
        24
    LDa  
       247 天前
    为了应对频繁的“小 X 啊,我想加个字段” 一个 JSON extra 完事
    beneo
        25
    beneo  
       247 天前
    @brader 其实你是领导也是一样这样要求,在凌晨做表变更。我觉得核心的问题是你不觉得公司的业务能给你带来价值,你觉得现在的工作占据了你的休息时间。
    Itesting
        26
    Itesting  
       247 天前
    @yolee599 也可用 GitHub 开源的 gh-ost 方案,加字段除了耗费时间对业务基本无感。
    brader
        27
    brader  
       247 天前
    @beneo 我就不吃这一套,免费加班爱找谁找谁
    xiaogezz
        28
    xiaogezz  
       247 天前
    真这么高的负载还用 mysql ?
    bigjack
        29
    bigjack  
       247 天前
    一般预留 10-20 个都属于正常的,变更数据库确实比较麻烦
    MeteorCat
        30
    MeteorCat  
       247 天前 via Android
    我们之前建表默认留了 ext1 ,2 ,3 字段,有些没用过但是有些频繁变动业务的时候完全不够,感觉看表是放什么业务
    veike
        31
    veike  
       247 天前
    加子表不行吗?
    lincanbin
        32
    lincanbin  
       247 天前
    ext1 、ext2 、ext3 、ext4……
    类型全部都是 string
    zhangxudong
        33
    zhangxudong  
       247 天前
    @devopsdogdog #9 mysql 5.7 的 online ddl 千万级的大表,还是有影响的。mysql8.0 的 online ddl 优化了加字段的操作,直接操作元数据了,大表可以秒级加字段
    encro
        34
    encro  
       247 天前
    @me1onsoda
    @Morii
    @zhangxudong

    8.0.12 instant 真爽!

    ```
    ALTER TABLE `user` ADD `status` (1) DEFAULT 0, ALGORITHM=instant
    ```
    yuyang1992test
        35
    yuyang1992test  
    OP
       247 天前   ❤️ 1
    总结:千万级的表,alter table 会导致锁表时间较长,mysql8.0 解决了这个问题
    runzekk
        36
    runzekk  
       246 天前
    不加。 容易引起误会的字段加了有啥用。 楼上说变更有问题的用的不是云数据库吗,云数据库变更早就有不锁表不停机方案了。 如果不是云数据库,自己怎么弄不行。
    peyppicp
        37
    peyppicp  
       246 天前
    我们一个分片 5kw 条数据,700+分片,没有这种扩展字段,每次上个需求都得慢死
    rophie123
        38
    rophie123  
       246 天前
    mysql5 ,亿级别的数据量,说加就加了,经常干
    BeautifulSoap
        39
    BeautifulSoap  
       246 天前 via Android
    这不光是 alter 的问题,改表的话发布流程多挺多步骤更麻烦也是一点。
    预留的话直接代码里用预留字段就行了不用改数据库。
    当然,无所谓这点工作成本的话最新版 mysql 倒是无所谓
    zhb1993
        40
    zhb1993  
       246 天前
    上次我在线上数据库( MySQL )中,直接修改了一个字段的长度,然后数据库挂了 10 分钟
    oneisall8955
        41
    oneisall8955  
       246 天前 via Android
    就奇怪了,加那么多 ext 字段,记得什么业务含义吗?没有语义的字段
    Daniel17
        42
    Daniel17  
       246 天前
    @oneisall8955 同问
    ntedshen
        43
    ntedshen  
       246 天前
    我们这边的 apache hive 基本上每个表都会留三到五个 ext ,最少也得留一个。。。
    主要改表结构这件事你不知道会导致什么后果,但是不改明显是没什么大问题的。。。

    改结构你改完 sql 脚本还要去数据同步里面改映射,改完映射整个数据流程得全部重新审批重新发布。。。
    然后外部 rds 和各种视图也要跟着全部改一遍,都不是不在一个部门的问题,可能要跨好几个部门。。。
    用通配符的部分全部都会报错,不用通配符的有的表百十个字段你最好也得通知一遍说不定有什么影响业务的问题。。。
    留个 ext 要哪天不够用大不了加个分隔块 concat 一下就完了。。。
    ljsh093
        44
    ljsh093  
       246 天前
    @yuyang1992test #4 加字段要走流程
    lanlanye
        45
    lanlanye  
       246 天前
    你们是没有文档库吗:(
    iseki
        46
    iseki  
       246 天前 via Android
    这不是高级不高级的问题,这是整天加字段加烦了,旧字段还变来变去改烦了。你看看没准这种情况下,程序里那个 ext 字段都按 any 类型处理的🤣
    tramm
        47
    tramm  
       246 天前
    看到这个问题, 联想到我们的数据库, 我想请教下各位大佬:
    我们有个数据库有几千万记录, 有两列是 Geometry 类型的数据, 整个表占用将近 1T 的空间, 该如何将这两列 Geometry 去掉?
    MySQL 8.0.31
    因为现在完全用不到这两列了.
    去年 5 月份, 想直接删除这两列的, 然后导致数据库直接挂了, 启动也启动不起来. 把那个表对应的物理文件删了才启动起来...
    xshell
        48
    xshell  
       246 天前
    MySQL8.X 以后 DDL 秒加字段。
    jsdi
        49
    jsdi  
       246 天前
    mysql8.0 有快速加列,能实现秒级加列,不锁表
    luzemin
        50
    luzemin  
       246 天前
    别的我不知道,就我经历的 java 项目

    之前数据库只有 a,b,c 三个字段
    mybatis 中:Select a,b,c (不允许写星号) from table
    java PO/DTO/VO 中:field a, field b, field c

    现在加个字段 d ,那就得从数据库开始一直到 VO 都得对应的增加,还可能有部分你不了解的地方未覆盖
    改动就意味着回归测试,挺麻烦的

    所以预先留 1 个字段,甚至多个,可以极大的简化这个流程。
    当然你说预留的还不够,不还得新加吗?如果预留不够,那说明改动真的不算“小”改动了,那就得专门创建个任务去做这个事情了
    sdwgyzyxy
        51
    sdwgyzyxy  
       246 天前
    对于上亿级的表,即使你把新增字段的 SQL 发给运维,他们也会直接拒绝,我们一般都是停服、复制表、加字段、删表、表名修改、启动服务,没其他好办法,只能停服。
    yph007595
        52
    yph007595  
       246 天前
    @chendy #7 你用的时候需要给预留字段改名吗?例如预留的是 ext1 ,ext2.。。,你会改成有意义的字段吗
    chendy
        53
    chendy  
       246 天前
    @yph007595 有专门的一个抽象层,管理字段定义和 sql 转义这些,使用的时候写的是字段名比如 userType ,实际执行查的是 c_ext_varchar_001 这样的字段
    pannanxu
        54
    pannanxu  
       246 天前
    @oneisall8955 ext 字段如果是 json 可以在 java 中直接映射为对象,mybatis 、jpa 都可以,所以只需要在代码中建立一个对象即可。
    jonsmith
        55
    jonsmith  
       246 天前
    与技术无关,跟公司管理有关。
    上家公司的很多表都有 exta 扩展字段,一个大 json ,什么垃圾数据都往里塞,导致历史数据不一致,层出不穷的 bug 。
    刚开始我也不习惯这么做,后来就从了。因为每次新增字段需要领导评审、一番掰扯,领导技术很垃圾、掰扯不清。
    SmiteChow
        56
    SmiteChow  
       246 天前   ❤️ 9
    面向未来屎山编程,面向一厢情愿的 7*24h 服务质量编程。

    影响国计民生的系统都允许闲时停水停电停服维护,就 TM 你做的系统了不起,不能停。
    wu00
        57
    wu00  
       246 天前
    屎山就是这么堆起来的
    十年前这样做属于有经验
    今天还在这样做就太那啥了...
    dzdh
        58
    dzdh  
       246 天前
    不怕加 ext 。怕的是这一个字段有不同作用。类型是 varchar ,存的数据一会儿是数字,一会儿是 string ,再隔一行还可能是 json
    salmon5
        59
    salmon5  
       246 天前
    这种现在数据库上应该不是问题,10 年前确实是个问题,现在应该不是问题
    zdking08135
        60
    zdking08135  
       246 天前 via Android
    增加不必要的字段就是有问题。比起这种意义不明的设计,还是想法避免单表千万行更靠谱。
    samin
        61
    samin  
       246 天前
    那你这高级程序员经验还不够,一般有经验都加 ext1,ext2,ext3 ,为什么没有 4 ? 老祖宗说过 事不过三
    oneisall8955
        62
    oneisall8955  
       246 天前 via Android
    @pannanxu 即使 mybatis 或 jpa 可以指定 column_name
    如果要写 mapper 或 native sql 的呢?即使代码里面没有写,自己查表数据时候也得写吧
    况且还会与别的团队,或新入职员工交流呢
    zdking08135
        63
    zdking08135  
       246 天前 via Android
    @tramm
    1.保证代码去掉对多余列的读写。这点最重要。join 也不要用这些列来 join
    2.写一个脚本循环将列值 update 成空值或者默认,一次循环处理几个。
    Huelse
        64
    Huelse  
       246 天前
    postgresql 随便改,不存在上述问题
    qiumaoyuan
        65
    qiumaoyuan  
       246 天前
    显得高级
    pannanxu
        66
    pannanxu  
       246 天前
    @oneisall8955 #62 自定义的 sql 一样可以映射呀,为什么不可以,已经创建实体对象了,还需要什么交流,看代码不就完了吗。再说了,extra 一般存储相对边缘的字段,谁常用的字段放那里啊。
    bwt
        67
    bwt  
       246 天前 via Android
    我们用的是 pt-online
    原理是创建一个新表,然后在老表新建一个触发器,将老表的写操作同步到新表,同时做数据迁移,迁移完成后 rename 表名
    这个流程不用停服
    Masoud2023
        68
    Masoud2023  
       246 天前
    单表千万你们不分表的? OLTP 这样玩真的 ok ?
    cwliang
        69
    cwliang  
       246 天前
    @tramm 把这些字段写为空不就行了
    ElmerZhang
        70
    ElmerZhang  
       246 天前
    首先,某业务表分了 1024 张表,每张表几百万数据,改一次表真的很麻烦。
    其次,有些不重要的不会作为查询条件的数据,直接一个 json 扔 ext 里是最简单的。
    用了 postgres 之后,我一般留一个 jsonb 字段作为 ext 。
    wuhao1
        71
    wuhao1  
       246 天前
    count(*) =266493624
    tairan2006
        72
    tairan2006  
       246 天前
    ext 放个 json ,还是挺实用的

    不过要搜索的字段还是老老实实加,或者加张新表
    yuyang1992test
        73
    yuyang1992test  
    OP
       246 天前
    @ljsh093 流程不就是审批个 sql 吗?难道随着业务发展,就不加新表,加新字段了吗?就磕着 ext 字段造?
    yuyang1992test
        74
    yuyang1992test  
    OP
       246 天前
    @lanlanye 文档型数据库吗?没怎么用过
    yuyang1992test
        75
    yuyang1992test  
    OP
       246 天前
    @luzemin 那你预留的这个字段以后用到了还改字段名字吗?
    yuyang1992test
        76
    yuyang1992test  
    OP
       246 天前
    @jonsmith 一般都会技术评审,最后审批的时候老板也不会看,直接通过
    yuyang1992test
        77
    yuyang1992test  
    OP
       246 天前
    @tairan2006 确定,需要查询的还是放新字段才能用到索引
    yuyang1992test
        78
    yuyang1992test  
    OP
       246 天前
    @ElmerZhang 我这边分表一般是按照 10 ,1000 来分,这样如果分表键是数字,就可以直接根据尾号就知道是哪张表了
    ElmerZhang
        79
    ElmerZhang  
       246 天前
    @yuyang1992test 按 2 的 N 次方来分的好处是,8 台机器抗不住时,可以扩到 16 台,再抗不住,扩到 32 台,依次类推。每台机器的压力始终是平均的。
    rahuahua
        80
    rahuahua  
       246 天前
    @yidinghe 10%的比例非常高了,哪怕有一次都能让你刻骨铭心,所以形成了肌肉记忆
    idblife
        81
    idblife  
       246 天前
    不是高级程序员,是没用过 oracle 和新版本 mysql 的老程序员
    pengtdyd
        82
    pengtdyd  
       246 天前
    你确定是高级吗?关系建模其中的一条是不要预留字段,需要了再加。
    zoharSoul
        83
    zoharSoul  
       246 天前
    没见过, 几个大厂都呆过
    darksheep9527
        84
    darksheep9527  
       246 天前
    @tramm 新建一个表 把除了 Geometry 类型之外的列数据导过去 然后删掉旧的那个表 不然清了列的数据 还要手动清理空间碎片
    8355
        85
    8355  
       246 天前
    重新定义高级程序员。。。。
    coala
        86
    coala  
       246 天前
    之前给千万条的订单表加字段,
    选择时间在凌晨 3 点,备足硬盘和内存, 跑了几十分钟..
    yc8332
        87
    yc8332  
       246 天前
    看来还是有不少人因为大表加字段挂过嘛。。。好人谁去大表加字段,而且正常线上挣钱的业务哪能停机维护让你加字段。。数据库升级更少了。大版本 N 年才会升级一次。
    nightsky
        88
    nightsky  
       246 天前
    不如联表
    seanzxx
        89
    seanzxx  
       246 天前
    我们公司的用户表预留了 20 个 varchar 做扩展,ext1~ext20 ,
    然后不同客户的用户,扩展字段的含义还不一样,
    还搞出一张扩展字段定义表,保存每个客户的扩展字段是什么意思
    fishily1993
        90
    fishily1993  
       246 天前
    alter 之后几个小时的主从延迟,告警邮件短信停不下来的时候,你就知道为啥了。
    luzemin
        91
    luzemin  
       246 天前
    @yuyang1992test #75 等“大”改动的时候一并优化,没改动前就“暂时”用这个语义很差的名字
    nekoneko
        92
    nekoneko  
       246 天前
    @Morii #6 #6
    @me1onsoda #2 #2

    PGSQL 如果 add column , 当默认值不是表达式时, 执行速度就是亚秒级, mysql 不知道是不是这样.
    yuyang1992test
        93
    yuyang1992test  
    OP
       246 天前
    @seanzxx toB 的系统?
    littlewing
        94
    littlewing  
       246 天前   ❤️ 1
    MySQL 5 时代遗留下来的一些规定,现在 MySQL 8.0 加列都是秒加的
    987N
        95
    987N  
       245 天前 via iPhone
    我们移动端数据库也是预留了几个 ext 的,不然更多数据库有可能失败
    tclm
        96
    tclm  
       245 天前 via Android
    不是很好的实践。
    MRlaopeng
        97
    MRlaopeng  
       205 天前
    @littlewing ,,2 亿数据的表,,,并不能秒加
    littlewing
        98
    littlewing  
       205 天前
    @MRlaopeng 不管多少都是一样秒加,因为只修改元数据,不动数据,和数据多少无关
    MRlaopeng
        99
    MRlaopeng  
       204 天前
    @littlewing ,,那为啥我的 MySQL8 加字段不能秒加,,
    littlewing
        100
    littlewing  
       204 天前
    @MRlaopeng 忘了说了,现在应该是只支持加到最后,不支持加到中间
    1  2  
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3098 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 78ms · UTC 11:00 · PVG 19:00 · LAX 04:00 · JFK 07:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.