当时我答的是单独新建一个表,做组合索引,写入成功就插入,没写入成功就失败。
1
encro 2023-06-17 10:23:49 +08:00 1
为难你了,
初级程序员面试架构师题目。。。 一般来说,不了解何时该分库分表的人,不配了解这个问题,这个问题只是为了让你早点知难而退。 |
2
gof817 2023-06-17 10:33:57 +08:00 1
这种最简单的就是用其他的 kv 库
|
3
LeegoYih 2023-06-17 10:45:29 +08:00 1
定义 2 个字段组合的路由规则
|
4
dode 2023-06-17 11:05:20 +08:00 via Android
pg 的分区表有并行查询,可以在整个表上加约束
|
5
unregister OP @encro 第一次我说使用分布式锁,第二次我说用中间表。大佬您有什么好的方案吗
|
6
realpg 2023-06-17 11:37:12 +08:00 3
分库分表规则中,涉及唯一性约束的字段的同值就不应该分到不同的表里面去
如果架构师只会按时间分表,那这公司不待也罢 |
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 保证唯一不一定非要唯一索引,也可以通过事务来保证 |
8
Azure99 2023-06-17 11:49:56 +08:00
有没有可能,有种分表策略叫哈希分表?
|
9
encro 2023-06-17 12:02:21 +08:00
@unregister
通常这个问题就是一个坑,我不知道原始问题是什么,所以没法估计这个出题的用意。 如果你是普通的分表,那么这个和你分表的 key 有关系, 如果是现成方案也是和分区 key 有关联。 先问清楚方案才能给解决方案。 |
10
IDAEngine 2023-06-17 12:11:03 +08:00
水平拆分还是垂直拆分,看具体问题。
|
11
echo1937 2023-06-17 12:30:12 +08:00 1
分表好办,
不支持全局索引的数据库,本地索引只支持分区内的唯一性,无法支持表上的唯一性,因此如果要用本地索引去给表做唯一性约束,则约束中必须要包括分区键列。 支持全局索引的数据库比如 Oracle ,没有这种限制,只是要接受全局索引比本地索引可用性低的现实。 分库麻烦一些, 如果是分布式数据库,基本上无需使用者担心,只要这个数据库实现了主键的唯一性约束, 如果是非分布式数据库,办法也是有的,比如结合 kv 库啊,用事务去解决啊,只是带来的代价未必小。 |
12
Ericcccccccc 2023-06-17 12:56:31 +08:00
分库分表的核心就在于你得自定义分表规则, 比如一个地区的用户在一张表里, 天然和其它地区的表是不冲突的.
|
13
bctdg 2023-06-17 16:25:56 +08:00 1
根据这两个 key 来做 partition 就好了吧?如果没有其他要求的话,这样是最简单的。这样做的问题可能是不同的分表数据量不均匀。
|
14
opengps 2023-06-17 18:57:47 +08:00 via Android
分库分表之后为什么会在一起?分裤分表本身就应该有个拆分逻辑作为前提,你这连基础的前提都没写出来
|
15
yueye115 2023-06-17 21:45:59 +08:00
@draymonder 我的想法是,把 user_id 和,user_type 进行字符串拼接,然后用 26 进制或者取字符串的字节等方法,把字符串转成一个数字,用这个数字进行分表可行否
|
16
yueye115 2023-06-17 21:47:38 +08:00
@draymonder 忘了说了,每个子表该字段加唯一索引
|
17
yueye115 2023-06-17 21:50:43 +08:00
@draymonder 不对啊,如果按照 user_id 进行分表,那直接在子表加 user_id 和 user_type 的联合唯一所以也能确保不重复。我感觉我理解错了
|
18
season8 2023-06-17 21:57:06 +08:00
我对着标题看了好半天才理解问题是啥:
是指有两个字段组合具有唯一性,分表后,如何保证分表之间的唯一性? hash 分表,无论几个字段,都可以用 hash ,只需要解决数据倾斜问题。 |
19
yueye115 2023-06-17 21:57:27 +08:00 1
如果把这个问题升级下,在以 id 进行分库的基础上,改造旧表,加个 user_id 和 user_type 的唯一验索引应该怎么搞
|
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 大小的,走老表,否则走新表 |
21
xuanbg 2023-06-18 08:20:32 +08:00
@realpg 大概率是有点分表需求,然后无脑使用某些分表中间件,自己对分表根本没有概念。。。要我说,对分表有概念的,根本用不上那些分表中间件。如果说分表会影响业务逻辑,那这个分表肯定就分错了。
|
22
xuanbg 2023-06-18 08:30:10 +08:00 1
推荐一个解决方案,就是利用 redis 的 setIfAbsent 方法,这个方法是如果 key 不存在,则 set k/v ,然后返回 true 。也就是说,返回 true 的话,就表明 key 是唯一。
|
23
LuckyLight 2023-06-19 00:21:43 +08:00
这两个字段有没有哪个字段是分表键?如果有,直接在分表里用这两个字段创建 unique key 。如果没有,简单的方式就是创建一个中间表,这两个字段创建 unique key ,除了这两个字段,再加上分表键和分表的主键,方便后续查询。
当然,更简单粗暴的就是上分布式数据库,比如 TiDB😂。 |