V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
maitiantuzi
V2EX  ›  数据库

数据库设计时,主表中有唯一业务编码字段,关联表还需要设计外键吗

  •  
  •   maitiantuzi · 2023-12-11 09:32:00 +08:00 · 3418 次点击
    这是一个创建于 382 天前的主题,其中的信息可能已经有所发展或是发生改变。

    举个例子, 主表 - 物料表 material: id: 主键 ID code: 物料唯一编码 name: 物料名称

    物料入库记录表: stock_in: id: 主键 ID material_id: 外键 - 物料 ID (这里需要吗?) mateiral_code: 物料唯一编码 in_date: 入库时间

    32 条回复    2024-03-21 12:18:00 +08:00
    abcdexx
        1
    abcdexx  
       2023-12-11 09:35:16 +08:00
    我是很少用数据库的外键,中间表有字段关联就可以了吧。
    forgottencoast
        2
    forgottencoast  
       2023-12-11 09:42:43 +08:00
    为了方便你只查物料 ID 的入库记录时不用连表查,间接在这个场景下提高性能,如果没有这需要可以不要。
    yuyuf
        3
    yuyuf  
       2023-12-11 09:47:41 +08:00
    主键 id 是数据库层面的唯一字段,物料唯一编码是业务层面的唯一字段。
    看你们是用哪个字段做关联的
    拿不准的情况,都存着,冗余一点总比后期加强
    JYii
        4
    JYii  
       2023-12-11 09:56:08 +08:00
    外键比较少用了,做删除时有点麻烦,如果有 db 迁移也麻烦
    charmToby
        5
    charmToby  
       2023-12-11 10:04:02 +08:00   ❤️ 5
    早就不用物理外键了,都是逻辑外键。
    themostlazyman
        6
    themostlazyman  
       2023-12-11 10:05:07 +08:00
    "物料 ID" 逻辑外键也不需要,联表查的话,主表设置"物料唯一编码"唯一约束、唯一索引即可。
    tomatocici2333
        7
    tomatocici2333  
       2023-12-11 10:05:45 +08:00
    别用物理外键 大坑
    sss15
        8
    sss15  
       2023-12-11 10:14:19 +08:00
    实际生产中严格按照第三范式设计的数据库比较少
    生产上我觉得唯一索引还是非常非常有必要的,靠代码层面无法杜绝脏数据进去,还是得靠唯一索引
    yuyuf
        9
    yuyuf  
       2023-12-11 10:16:14 +08:00
    楼上说不用物理外键的,这还是要看具体情况。
    一些项目并发不高,数据量不大,但对数据准确性要求高,还是能用外键的。
    一般大部分互联网公司不用外键
    看楼主的描述,可能是一些工业项目呢
    nothingistrue
        10
    nothingistrue  
       2023-12-11 10:22:58 +08:00
    实体关联,不管你是数据库层面的物理外键,还是程序层面的逻辑外键,都要用物理主键,否则你也没必要再在自然键之外设计一个代理主键。

    对于你的 stock_in 来说,用 material_id 做关联键,才能发挥代理主键的性能。mateiral_code 也有用,但它更多的是作为 stock_in 自身的属性来用。
    jucelin
        11
    jucelin  
       2023-12-11 10:28:37 +08:00
    material_id 才是主键,mateiral_code 在入库记录中只是为了查询冗余。

    mateiral_code 是业务层面的唯一,说不定哪天就 变成 mateiral_code+xxx 是唯一的了。
    bugmaker1024
        12
    bugmaker1024  
       2023-12-11 10:34:24 +08:00
    逻辑外键+1
    liaojl
        13
    liaojl  
       2023-12-11 10:38:47 +08:00 via iPhone
    楼上有人提到了,要看具体业务,据我所了解到的,互联网公司很多都是不用物理外键的,但金融行业,比如我目前就职的某个外资银行,就有很多地方会用到,物理外键能在数据库层面保证数据的一致性,逻辑外键的话,代码要是有 bug ,导致的数据问题,要修复的话很麻烦。
    dif
        14
    dif  
       2023-12-11 10:41:56 +08:00
    印象中外键已经是学生阶段老师讲的了,毕业工作这么多年,还真很少见到外键。
    adoal
        15
    adoal  
       2023-12-11 11:01:31 +08:00   ❤️ 3
    如果数据错了只要赔几个站内积分甚至只要道歉甚至连道歉都不用就能吧用户糊弄过去,那啥都不用搞。

    如果是要真金白银赔钱,通报批评,记过处分,甚至可能坐牢,还是好好设计一下数据库,各种约束加上去。
    chendy
        16
    chendy  
       2023-12-11 11:10:43 +08:00
    具体情况具体分析,好处大于坏处就上,反过来就不上
    比如说:
    1. 加外键是否会对性能产生重大影响
    2. 不加外键,系统逻辑是否足够完善避免脏数据产生
    等等…
    xuanbg
        17
    xuanbg  
       2023-12-11 11:35:53 +08:00
    没必要有外键,但外键也不是什么大坑,相关言论有点过于耸人听闻了。
    wushigejiajia01
        18
    wushigejiajia01  
       2023-12-11 11:47:10 +08:00
    mateiral_code: 物料唯一编码
    能保证唯一,那物料 ID ,就没必要了啊,
    过度冗余数据也不是个好习惯
    totoro52
        19
    totoro52  
       2023-12-11 13:13:19 +08:00
    大学生才用数据库外键
    IvanLi127
        20
    IvanLi127  
       2023-12-11 14:22:43 +08:00
    只要你的数据库只有你的程序能写,并且你的程序能可靠地约束写入的数据的正确性,多步操作失败时能有效回滚,数据库可以不加外键。这个就看实力了。。如果项目不大也不用考虑后续运维菜鸡的问题,所以我建议数据库顶得住,加个外键约束挺好的。
    tietou
        21
    tietou  
       2023-12-11 16:31:38 +08:00
    一般是逻辑外键吧
    go522000
        22
    go522000  
       2023-12-11 16:39:45 +08:00
    加上去呗,占用不了多少空间,而且又不影响性能。
    i8086
        23
    i8086  
       2023-12-11 16:47:34 +08:00
    不考虑物理外键还是逻辑外键。物料 ID 是数据库表主键,性能是第一的。
    SilenceLL
        24
    SilenceLL  
       2023-12-11 18:09:10 +08:00
    现在很少有用外键的,性能受限
    forschers
        25
    forschers  
       2023-12-11 18:15:36 +08:00
    好像没有咋用外键
    lovelylain
        26
    lovelylain  
       2023-12-11 18:32:35 +08:00
    不用外键,而且你这个场景,一般给物料表的物料唯一编码加上唯一索引,其他表也直接用这个编码而不是引用物料表的主键 ID 。
    kkwa56188
        27
    kkwa56188  
       2023-12-11 20:23:39 +08:00
    外键是在数据库层面保证数据的完整准确, 按照数据库的设计规范来说 最好能加,
    不加的话, 实际业务 要是能承受 出问题时候的情况, 也可以.

    我举三个例子, 按照数据出错的严重程度从轻到重 :
    1. 在商品评价表里 出现有一条评分来自未知用户, 不存在于用户主表里
    2. 在入库表里 发现 有一个 未知的物料, 不存在于物料主表里.
    3. 在 支出费用表里出现一张未知的发票, 不存在于发票主表里
    pheyx
        28
    pheyx  
       2023-12-11 21:22:23 +08:00 via Android
    @adoal 你个干图书馆的破 it 懂个屁
    akira
        29
    akira  
       2023-12-12 00:11:22 +08:00
    有 mateiral_code 做唯一索引就够了,另外你的 id 大概率是 自增 id ,不建议参与业务
    ChadGPT
        30
    ChadGPT  
       2023-12-12 08:54:32 +08:00
    自增 id 如果参与业务,未来不同类型数据库迁移的时候可能会有麻烦
    dyv9
        31
    dyv9  
       281 天前 via Android
    @jucelin 同一个型号的零件也有多个供应商呢。所以眼看到的编号不一定能用作唯一键。
    dyv9
        32
    dyv9  
       281 天前 via Android
    @JYii 麻烦是好事,正好阻止了一步破坏所有数据的能力,构造数据和修改数据都要理解数据否则操作不下去。我见过给数据打补丁的人不完全理解设计,直接把一批数据改一样的了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1739 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 16:32 · PVG 00:32 · LAX 08:32 · JFK 11:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.