数据库分库分表之后,所有表在一起,两个字段怎么做组合唯一索引? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
unregister
V2EX    Java

数据库分库分表之后,所有表在一起,两个字段怎么做组合唯一索引?

  •  2
     
  •   unregister 2023-06-17 09:43:39 +08:00 3906 次点击
    这是一个创建于 883 天前的主题,其中的信息可能已经有所发展或是发生改变。

    当时我答的是单独新建一个表,做组合索引,写入成功就插入,没写入成功就失败。

    23 条回复    2023-06-19 00:21:43 +08:00
    encro
        1
    encro  
       2023-06-17 10:23:49 +08:00   1
    为难你了,
    初级程序员面试架构师题目。。。

    一般来说,不了解何时该分库分表的人,不配了解这个问题,这个问题只是为了让你早点知难而退。
    gof817
        2
    gof817  
       2023-06-17 10:33:57 +08:00   1
    这种最简单的就是用其他的 kv 库
    LeegoYih
        3
    LeegoYih  
       2023-06-17 10:45:29 +08:00   1
    定义 2 个字段组合的路由规则
    dode
        4
    dode  
       2023-06-17 11:05:20 +08:00 via Android
    pg 的分区表有并行查询,可以在整个表上加约束
    unregister
        5
    unregister  
    OP
       2023-06-17 11:34:17 +08:00
    @encro 第一次我说使用分布式锁,第二次我说用中间表。大佬您有什么好的方案吗
    realpg
        6
    realpg  
    PRO
       2023-06-17 11:37:12 +08:00   3
    分库分表规则中,涉及唯一性约束的字段的同值就不应该分到不同的表里面去

    如果架构师只会按时间分表,那这公司不待也罢
    draymonder
        7
    draymonder  
       2023-06-17 11:47:35 +08:00   2
    假设两个字段是 (user_id ,user_type)

    1. 方案一,将两个字段映射到一个 v_user_id 上,对 v_user_id 进行分库分表。
    v_user_id -> (user_id ,user_type) 的数据用一个 mysql 表存下来,( user_id ,user_type )-> v_user_id 通过 kv 数据库存储,这样双向映射都有了
    2. 方案二,对 user_id 进行分库分表,所有写入和查询操作都带上 user_type

    保证唯一不一定非要唯一索引,也可以通过事务来保证
    Azure99
        8
    Azure99  
       2023-06-17 11:49:56 +08:00
    有没有可能,有种分表策略叫哈希分表?
    encro
        9
    encro  
       2023-06-17 12:02:21 +08:00
    @unregister

    通常这个问题就是一个坑,我不知道原始问题是什么,所以没法估计这个出题的用意。

    如果你是普通的分表,那么这个和你分表的 key 有关系,

    如果是现成方案也是和分区 key 有关联。

    先问清楚方案才能给解决方案。
    IDAEngine
        10
    IDAEngine  
       2023-06-17 12:11:03 +08:00
    水平拆分还是垂直拆分,看具体问题。
    echo1937
        11
    echo1937  
       2023-06-17 12:30:12 +08:00   1
    分表好办,

    不支持全局索引的数据库,本地索引只支持分区内的唯一性,无法支持表上的唯一性,因此如果要用本地索引去给表做唯一性约束,则约束中必须要包括分区键列。

    支持全局索引的数据库比如 Oracle ,没有这种限制,只是要接受全局索引比本地索引可用性低的现实。

    分库麻烦一些,
    如果是分布式数据库,基本上无需使用者担心,只要这个数据库实现了主键的唯一性约束,

    如果是非分布式数据库,办法也是有的,比如结合 kv 库啊,用事务去解决啊,只是带来的代价未必小。
    Ericcccccccc
        12
    Ericcccccccc  
       2023-06-17 12:56:31 +08:00
    分库分表的核心就在于你得自定义分表规则, 比如一个地区的用户在一张表里, 天然和其它地区的表是不冲突的.
    bctdg
        13
    bctdg  
       2023-06-17 16:25:56 +08:00   1
    根据这两个 key 来做 partition 就好了吧?如果没有其他要求的话,这样是最简单的。这样做的问题可能是不同的分表数据量不均匀。
    opengps
        14
    opengps  
       2023-06-17 18:57:47 +08:00 via Android
    分库分表之后为什么会在一起?分裤分表本身就应该有个拆分逻辑作为前提,你这连基础的前提都没写出来
    yueye115
        15
    yueye115  
       2023-06-17 21:45:59 +08:00
    @draymonder 我的想法是,把 user_id 和,user_type 进行字符串拼接,然后用 26 进制或者取字符串的字节等方法,把字符串转成一个数字,用这个数字进行分表可行否
    yueye115
        16
    yueye115  
       2023-06-17 21:47:38 +08:00
    @draymonder 忘了说了,每个子表该字段加唯一索引
    yueye115
        17
    yueye115  
       2023-06-17 21:50:43 +08:00
    @draymonder 不对啊,如果按照 user_id 进行分表,那直接在子表加 user_id 和 user_type 的联合唯一所以也能确保不重复。我感觉我理解错了
    season8
        18
    season8  
       2023-06-17 21:57:06 +08:00
    我对着标题看了好半天才理解问题是啥:

    是指有两个字段组合具有唯一性,分表后,如何保证分表之间的唯一性?

    hash 分表,无论几个字段,都可以用 hash ,只需要解决数据倾斜问题。
    yueye115
        19
    yueye115  
       2023-06-17 21:57:27 +08:00   1
    如果把这个问题升级下,在以 id 进行分库的基础上,改造旧表,加个 user_id 和 user_type 的唯一验索引应该怎么搞
    draymonder
        20
    draymonder  
       2023-06-17 22:23:59 +08:00
    @yueye115
    1. ( user_id ,user_type )-> v_user_id 本质上是个 hash 的过程,我理解满足 `唯一映射` 就行,v_user_id 可以通过 id 生成器生成,也可以用字符串拼接而成
    2. 表迁移大多有成熟的方法
    2.1 扫存量的数据+通过 binlog 迁移,找个低峰时间,全量切到新的分库分表中
    2.2 代码做兼容,通过时间点 /id 大小,小于相应的时间点 /id 大小的,走老表,否则走新表
    xuanbg
        21
    xuanbg  
       2023-06-18 08:20:32 +08:00
    @realpg 大概率是有点分表需求,然后无脑使用某些分表中间件,自己对分表根本没有概念。。。要我说,对分表有概念的,根本用不上那些分表中间件。如果说分表会影响业务逻辑,那这个分表肯定就分错了。
    xuanbg
        22
    xuanbg  
       2023-06-18 08:30:10 +08:00   1
    推荐一个解决方案,就是利用 redis 的 setIfAbsent 方法,这个方法是如果 key 不存在,则 set k/v ,然后返回 true 。也就是说,返回 true 的话,就表明 key 是唯一。
    LuckyLight
        23
    LuckyLight  
       2023-06-19 00:21:43 +08:00
    这两个字段有没有哪个字段是分表键?如果有,直接在分表里用这两个字段创建 unique key 。如果没有,简单的方式就是创建一个中间表,这两个字段创建 unique key ,除了这两个字段,再加上分表键和分表的主键,方便后续查询。
    当然,更简单粗暴的就是上分布式数据库,比如 TiDB。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2480 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 02:33 PVG 10:33 LAX 18:33 JFK 21:33
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86