分库分表 Sharding: 4. 路由 / 映射:如何找到要操作的表

205 篇文章 0 订阅
47 篇文章 0 订阅

4.    路由 / 映射:如何找到要操作的表
4.1    实际表的分布种类
基本表与实际表的映射关系,可分为均匀顺序分布,均匀轮询分布,仅均匀分布和自定义分布 4 种形式。
现通过例子,说明各种表分布的特点。基本名称为 ds 的 3 数据库,有 6 个表,表基本名称为 user。以下为数据库与对应表下标的分布。
均匀顺序分布:
ds0=[ 0, 1],  ds1=[ 2, 3], ds2=[ 4, 5]
均匀轮询分布:
ds0=[0, 3] ,  ds1=[1, 4] ,ds2=[2, 5]
仅均匀分布:
ds0=[ 0, 1],  ds1=[ 0, 1],  ds2=[ 0, 1]
自定义:可能是
ds0=[ 0,],  ds1=[ 1,2, 3], ds2=[ 4, 5]
通过观察和判断,发现,仅均匀分布每个库中的表的名称是相同的,只知道表名,无法由表名推断表所对应的库,因此不适合用来通用分片处理;自定义,无规律可言,也不适合。

4.2    分片键
分片键,即用来寻找到对应库和表的表中字段。
4.2.1    分库键
表的字段中,使用其值,按一定算法找到唯一数据库的字段。如,orders 订单表中,userid 用户 id,可以作为分库键。
4.2.2    分表键
表的字段中,使用其值,按一定算法找到唯一实际的字段。如,orders 订单表中,userid 用户 id,可以作为分表键。分片键中,可以只使用分表键,然后根据确定的表名,推断所有的库;从而省略分库键。
4.2.3    分片键的选择
 


分片键即分库 / 分表字段,是在水平拆分过程中用于生成拆分规则的数据表字段。根据分片键的值将数据表水平拆分到每个物理分库中。
根据表拆分的首要原则,就是要尽可能找到数据表中的数据在业务逻辑上的主体,并确定大部分(或核心的)数据库操作都是围绕这个主体的数据进行,然后可使用该主体对应的字段作为分片键,进行分库分表。
业务逻辑上的主体,通常与业务的应用场景相关,下面的一些典型应用场景都有明确的业务逻辑主体,可用于分片键:
面向用户的互联网应用,都是围绕用户维度来做各种操作,那么业务逻辑主体就是用户,可使用用户对应的字段作为分片键;一般可以使用 userid 用户 id。
侧重于卖家的电商应用,都是围绕卖家维度来进行各种操作,那么业务逻辑主体就是卖家,可使用卖家对应的字段作为分片键;一般可以使用商家 id。
以此类推,其它类型的应用场景,大多也能找到合适的业务逻辑主体作为分片键的选择。
如果确实找不到合适的业务逻辑主体作为分片键,那么可以考虑下面的方法来选择分片键:
根据数据分布和访问的均衡度来考虑分片键,尽量将数据表中的数据相对均匀地分布在不同的物理分库 / 分表中,适用于大量分析型查询的应用场景(查询并发度大部分能维持为 1);
按照数字(字符串)类型与时间类型字段相结合作为分片键,进行分库和分表,适用于日志检索类的应用场景。
注意:无论选择什么拆分键,采用何种拆分策略,都要注意拆分值是否存在热点的问题,尽量规避热点数据来选择拆分键。
注意:不一定需要拿数据库主键当做分片键,也可以拿其他业务值当分片键。拿主键当分片键的好处是可以散列均衡,减少热点问题。但这种分法,会将业务逻辑相关的数据放到不同的表,甚至不同的库,从而引起跨库问题。
分片键中,可以只使用分表键,然后根据确定的表名,推断所有的库;从而省略分库键。
4.2.4    实践 — 用 userid 作为分表键的好处

4.3    分片算法及分片函数
分片算法,指由分片键及其值,找到对应的库和表的步骤与方法。
分片函数,指由分片值计算后得到相应的值的表达式或程序代码段。例如,分片键 userid 的值是 10, 通过求余表达式,userid%6,代入得 10%6=4;当是求映射的表,基本表是 orders,则得到目标表:orders4。
分片算法可以使用不同的分片函数,除了常用的数字求余,还有分片字段是字符串类型的求余,字符串或时间取其中部分子串。
正则表达式适合用作分库分表的分片函数吗?不适合,它不能由分片值,确定库和表。

4.4    默认分片函数及分片的自动化
Bee 采用最简单的求余表达式分片函数作为默认方式;还支持字符串类型的求余,最大程序实现自动化。最简单的配置,只需要指定实现表节点和分表键即可。

4.5    强制指定分片路由
用户可以指定使用的具体 ds 和 table,而无需使用分片值通过路由算法计算。在 Bee 中,可以使用

4.6    路由到的库与表种类
提醒:本小节说的表,都是指同一基本表下的。
在表节点,使用均匀顺序分布时,通过表可以反推表所在的库,因此只使用分表键即可。以下说明,假设基本名称为 ds 的 3 个数据库,有 6 个表,表基本名称为 orders。以下为数据库与对应表下标的分布。数据库与对应表下标的均匀顺序分布如下:
ds0=[ 0, 1],  ds1=[ 2, 3], ds2=[ 4, 5]
分片键为 userid, 分片算法中使用数字求余 userid%6,寻找映射的实际表。
4.6.1    一库一表
一库一表,指要执行的 SQL 操作,通过分片路由,只涉及一个库和一个表。如:
select * from orders where userid=1;
表分片键的值为 1,而 1%6=2, 得到实际表 orders2,而一个表,在均匀顺序分布中,只对应一个库。因此是路由到一库一表。从这个例子,也可以看出,只知道实际表名,在仅均匀分布下,是无法确定数据库的。
4.6.2    一库多表
一库多表,指要执行的 SQL 操作,通过分片路由,只涉及一个库和多个表。如:
select * from orders where userid=2 or userid=3;
2%6=2,3%6=3;涉及的表为 orders2, orders3,而 orders2 和 orders3 都属于数据库 ds1。因此是路由到一库多表的。
4.6.3    多库多表
select * from orders where userid=1 or userid=2;
涉及的表为 orders1, orders2;涉及的库为 ds0,ds1。因此是路由到多库多表的。
4.6.4    全库全表
全库全表,也称为:全域路由。
select * from orders;
涉及基本表 orders 所有实际表。
4.6.5    只指定表
select * from orders where userid=1;
只指定了表分片键,若是表不能反推库,则会涉及所有的库。
如表在仅均匀分布下,库与表下标对应关系为:
ds0=[ 0, 1],  ds1=[ 0, 1],  ds2=[ 0, 1]
通过 userid=1,得到实际表是 orders1,也会因找不到具体的库,而要在三个库中都查询一遍。因此变成多库一表。而表若使用均匀顺序分布,则可以变为一库一表。
4.6.6    只指定库
当有库分片键,又有表分片键,而 sql 中只指定了库分片键,则要在所在库下找所有的实际表。如 orders 分库键为 prod_type,分表键为 userid。
select * from orders where prod_type=1; 通过路由计算,只得到涉及的库为 ds0;
则在 ds0 下,要执行:
select * from orders0 where prod_type=1;
select * from orders1 where prod_type=1;

4.7    如何分片
4.7.1    SQL 触发的分片
如以下 SQL 语句: select * from orders where userid=1 or userid=2;
当配置了 orders 相关的分片信息,就会触发分片。这一般是解析 SQL 语句型的分片中间件,如 Sharding-JDBC。
4.7.2    面向对象触发的分片
通过解析实体对象的信息,判断实体对象是否是分片,分片键是否有键等,路由到具体的库与表。这种分片,利用了对象的结构化数据,不需要解析 SQL 语句字符串。ORM 工具 Bee,就是这种类型。
4.7.3    SQL 分片与面向对象分片的异同
4.8    分片优化与应该避免的问题

4.8.1    引起全域查询
在单节点单表时,我们用 select * from table_name 查询指定表的所有数据;但在分库分表时,因没有指定分片值(分片键及其值),不知道是要查询基本表 table_name 对应的哪张表,所以会查询基本表下所有的实际表,从而引起全库全表的查询,即全域查询。
所以指定精确的分片键的值,有助于优化查询。
4.8.2    插入的数据必须要找到归属
当插入一条数据时,若是没有指定分片值,就无法知道要将值插入哪个表;因此分片的表,要指定分片值。另外,广播表不需要指定分片键,进行更新操作会面向所有的表。
4.9    主键 (分布式唯一 ID)

Bee 提供具体分布式全局唯一的 id 作为主键,可以使用注解,也可以使用 properties 文件配置。当实体设置有值时,若是配置了不覆盖已有 id 的值,就不会使用使用 Bee 框架的值进行填充。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值