分表非Sharding-Key怎么查询
假设:有用户表user,订单表order,order表通过user_id分表了,如何通过order_id查询订单?
遍历
原始方法,union all查询所有遍历所有的order表。不建议,浪费大量系统资源。
引入外部缓存
将所有order信息冗余同步到ES,然后通过ES来查询。
索引表
建立user_id对应order_id表,先查询order_id对应的user_id,再通过user_id分表key查询对应的order表。
基因法
生成order_id时,将部分user_id包含到order_id中,通过order_id即可获取到相应user_id对应的order表。
基因法举例
如下图所示,user_id=20160169(二进制:1001100111001111010101001)的用户创建订单,order表16分片
- 使用user_id % 16 分片,决定这行数据要插入到哪个分片中;
- log (16, 2) = 4,分库基因是user_id的最后4个bit,即1001;
- 在生成order_id时,先使用一种分布式ID生成算法生成前60bit(图中青色部分);
- 将分库基因加入到order_id的最后4个bit(图中粉色部分);
- 拼装成最终的64bit订单order_id(图中蓝色部分)。
这样保证了同一个用户创建的所有订单都落到了同一个分片上,order_id的最后4个bit都相同,于是:
- 通过user_id %16 能够定位到分片;
- 通过order_id % 16 也能定位到分片。.