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

2023-06-17 09:43:39 +08:00
 unregister

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

3425 次点击
所在节点    Java
23 条回复
encro
2023-06-17 10:23:49 +08:00
为难你了,
初级程序员面试架构师题目。。。

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

如果架构师只会按时间分表,那这公司不待也罢
draymonder
2023-06-17 11:47:35 +08:00
假设两个字段是 (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
2023-06-17 11:49:56 +08:00
有没有可能,有种分表策略叫哈希分表?
encro
2023-06-17 12:02:21 +08:00
@unregister

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

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

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

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

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

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

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

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

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

hash 分表,无论几个字段,都可以用 hash ,只需要解决数据倾斜问题。
yueye115
2023-06-17 21:57:27 +08:00
如果把这个问题升级下,在以 id 进行分库的基础上,改造旧表,加个 user_id 和 user_type 的唯一验索引应该怎么搞
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 大小的,走老表,否则走新表

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/949463

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX