首页 > 其他分享 >分库分表 Sharding: 4. 路由 / 映射:如何找到要操作的表

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

时间:2022-10-10 20:40:39浏览次数:61  
标签:分库 userid 分表 分片 Sharding orders 路由

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 框架的值进行填充。

标签:分库,userid,分表,分片,Sharding,orders,路由
From: https://blog.51cto.com/u_15822049/5745204

相关文章

  • 分库分表 Sharding: 5. 分片流程与 Sharding 核心问题
    5.   分片流程与Sharding核心问题5.1   Bee(JDBC部分)的转换流程Bee基于JDBC操作数据库的流程如下:1)使用实体Javabean(+条件表达式Condtion,对应SQL......
  • 分库分表 Sharding:7. Bee 对分片的优化
    7.   Bee对分片的优化7.1   对一库一表的优化最终路由到一库一表,即不会造成分片,因此Bee将其优化为单点操作。7.2   对一库多表的分页查询的优化对一库多表的......
  • 分库分表 Sharding:8. 主流的数据库中间件实现对比
    8.   主流的数据库中间件实现对比8.1   数据库代理与数据源代理典型的数据库中间件设计方案有2种:服务端代理(proxy:代理数据库)、客户端代理(datasource:代理数据......
  • sharding 目前支持和不支持的 sql
     描述:使用sharding 中间件,不支持一些sql具体看官网:​​https://shardingsphere.apache.org/document/current/cn/features/sharding/use-norms/sql/​​......
  • 分库分表中间件 sharding
     任何一个技术的出现,都不是为了秀肌肉而产生的。  sharding jdbc 这个分库分表技术要解决的问题就是,随着数据量级的提升,物理硬件达到瓶颈,单表的性能优化也带来了瓶......
  • 分库分表
     这篇文章主要介绍分库分表,以及分库分表带来的问题、 ## 分库分表的几种形式 水平分库,本质是把相同的表放在不同的机器上。 垂直分库:本质是将多个表拆分到不同的机器......
  • sharding 的遇到的相关坑
    org.springframework.dao.InvalidDataAccessApiUsageException:Can'tfindindex:AggregationSelectItem 这个问题是用 sharding,要对聚合函数起一个别名。 看官网给......
  • 使用sharding 做分库分表以后,插入报错 Executing an update/delete query
    这个问题倘若没有 sharding,那就是在service层缺少了事务注解@Transaction这个问题具体看这里​ 我是跑测试类跑出来的问题,好像做分库分表,不能用测试类来测,只能通过 con......
  • 使用sharding做分库分表,使用jpa,发生的save不报错,数据库缺插不进去数据的问题
     先讲讲问题的诞生,我们项目起初没有引进 sharding分库,而是在项目上线前,才做的分库分表。也就是之前的业务都写好的,所以知道业务代码没有任何问题。 然后引入 sharding......
  • mybatis-plus还可以这样分表
    mybatis-plus还可以这样分表 为什么要分表Mysql是当前互联网系统中使用非常广泛的关系数据库,具有ACID的特性。但是mysql的单表性能会受到表中数据量的限制,主要原因......