首页 » Web前端 » phpci分表技巧_分布式系统进阶四之分库分表

phpci分表技巧_分布式系统进阶四之分库分表

访客 2024-12-08 0

扫一扫用手机浏览

文章目录 [+]

对付互联网企业来说,大部份数据都是与用户有关联的,因此,用户ID是最常用的分表字段。
由于大部分查询都须要带上用户ID,这样既不影响查询,又能够使数据较为均衡地分布到各个表中。

phpci分表技巧_分布式系统进阶四之分库分表

假设有一张记录用户购买信息的订单表order,由于order表记录条数太多,将被拆分成256张表。
拆分的记录根据user_id%256取到对应的表进行存储,前台运用则根据对应的user_id%256,找到对应订单存储的表进行访问。
这样一来,user_id便成为一个必需的查询条件,否则将会由于无法定位数据存储的表而无法对数据进行访问。

phpci分表技巧_分布式系统进阶四之分库分表
(图片来自网络侵删)

假设订单order 表构造如下:

CREATE TABLE `order` (`order_id` bigint(20) unsigned NOT NULL COMMENT '订单ID,分布式ID',`user_id` bigint(20) unsigned NOT NULL COMMENT '用户ID',`nick_name` varchar(32) NOT NULL COMMENT '用户昵称',`shop_id` bigint(20) unsigned NOT NULL COMMENT '店铺ID',`total` bigint(20) unsigned NOT NULL COMMENT '总金额,分',`create_time` datetime NOT NULL COMMENT '创建韶光',PRIMARY KEY (`order_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='订单表';

那么分表往后,假设user_id =257,并且shop_id = 100,须要根据shop_id来查询对应的订单信息,则对应的SQL语句如下:

SELECT FROM order_1 where user_id = 257 and shop_id = 100;DbTableUtil 分表工具类

DbTableUtil 工具类,可以天生 0001 到 9999张表记录,如订单表 order,利用DbTableUtil 天生表如下:

order_0001,order_0002,order_0003,order_0004.........order_9999

public class DbTableUtil { private static final int TABLE_SIZE = 256; public DbTableUtil() { } public static String getTableIndex(Object shardKey, int sliceSize) { int hashValue = Math.abs(shardKey.hashCode()); int tableIndex = hashValue % sliceSize + 1; return String.format("%04d", tableIndex); } public static String hash(long key, int sliceSize) { long hashValue = Math.abs(key); int tableIndex = (int)(hashValue % (long)sliceSize + 1L); return String.format("%04d", tableIndex); } public static String hash(long key) { return hash(key, 256); }}分库策略

个中,order_1根据 257%256打算得出,表示分表之后的第一张order表。

分表能够办理单表数据量过大带来的查询效率低下的问题,但是,却无法给数据库的并发处理能力带来质的提升。
面对高并发的读写访问,当数据库Master做事器无法承载写操作压力时,不管如何扩展Slave做事器,此时都没故意义了。
因此,我们必须换一种思路,对数据库进行拆分,从而提高数据库的写入能力,这便是所谓的分库。

与分表策略相似,分库也可以采取通过一个关键字段去取模的办法,来对数据库访问进行路由,如图:

分库分表策略

还是之前的订单表,假设user_id字段的值为257,将原有的单库分为256个库,那么运用程序对数据库的访问要求将被路由到第一个库 257%256=1。

有时数据库可能既面临着并发访问的压力,又须要面对海量数据的存储问题,这时须要对数据库即采取分表策略,又采取分库策略,以便同时扩展系统的并发处理能力,以及提升单表的查询性能,这便是所谓的分库分表。

分库分表的策略比前面的仅分表的策略要更为繁芜,一种分库分表的路由策略如下:

中间变量=user_id%(库数量 每个库的表数量)库=取整(中间变量/每个库的表数量)表=中间变量 % 每个库的表数量

同样采取user_id作为路由字段,首先利用user_id对库数量 每个库的表的数量取模,得到一个中间变量;然后利用中间变量除以每个库表的数量,取整,得到对应的库;而中间变量对每个库表的数量取模,即得到对应的表。
分库分表策略如图:

假设将原来的单库单表 order 拆分成256个库,每个库包含1024个表,那么按照前面所提到的路由策略,对付 user_id= 262145的访问,路由打算过程如下:

中间变量 = 262145 % (256 1024 ) = 1;库= 取整(1/1024) = 0表= 1%1024 =1

这意味着,对付 user_id= 262145 的订单记录的查询和修正,将被路由到第 0个库的第1个表中实行。

ShardingSphere

下期我们会先容ShardingSphere,它是一套开源的分布式数据库中间件办理方案。
可以大大减轻我们开拓的压力。
其架构图:

标签:

相关文章