首页 > 其他分享 >分库分表之拆分键设计

分库分表之拆分键设计

时间:2023-09-20 09:05:38浏览次数:34  
标签:分库 运单 数据库 订单号 生成 订单 拆分 分表

众所周知,在现实世界中,每一个资源都有其提供能力的最大上限,当单一资源达到最大上限后就得让多个资源同时提供其能力来满足使用方的需求。同理,在计算机世界中,单一数据库资源不能满足使用需求时,我们也会考虑使用多个数据库同时提供服务来满足需求。当使用了多个数据库来提供服务时,最为关键的点是如何让每一个数据库比较均匀的承担压力,而不至于其中的某些数据库压力过大,某些数据库没什么压力。这其中的关键点之一就是拆分键的设计。

一、 水平、垂直拆分

在关系数据库中,当单个库的负载、连接数、并发数等达到数据库的最大上限时,就得考虑做数据库和表的拆分。如一个简单的电商数据库,在业务初期,为了快速验证业务模式,把用户、商品、订单都放到一个数据库中,随着业务的发展及用户量的增长,单数据库逐渐不能支撑业务(MySQL中单记录容量超过1K时,单表数据量建议不超过一千万条),这时就得考虑把数据库和表做出拆分。
  • 垂直拆分:简单的说就是将数据库及表由一个拆分为多个,如我们这里的电商数据库,可以垂直拆分为用户数据库、商品数据库和订单数据库,订单表可以垂直拆分为订单基本信息表,订单收货地址表、订单商品表等,每一个表里保存了一个订单的一部分数据。
图片
  • 水平拆分:简单地说就是将一个库、一个表扩展为多个库,多个表,每一个拆分后的表中保存的依然是一个订单的完整信息。如电商数据库,我们按水平拆分数据库和表后,每一个拆分后的数据库表与现有未拆分前的都保持一致。
图片
  • 常用拆分方法:上述仅从理论上讲解了可行的水平、垂直拆分方法,在实际的生产上,我们拆分一般是按照水平拆表、垂直拆库这一原则进行,在业务比较复杂的场景下也会对表进行垂直拆分。
图片
二、 拆分键的选取
分库分表的关键项之一是拆分键的选取,一般情况下,拆分键的选取遵循以什么维度进行查询就选取该维度为拆分键。如:订单表就以订单号作为拆分键,商品表就以商品编号作为拆分键。拆分键选取后,对于一些非拆分键的单条件查询,我们需要怎么支持呢?在这里提供3种方法供参考。
1、等值法:
对于非拆分键的单条件查询,对这一个单条件的赋值,可以将其值与拆分键保持一致。比如在电商场景中,用户下订单后,需要通过物流给用户把商品送到用户手上。对于用户来说仅能看到订单信息,订单上展示的物流信息用户也是通过订单号查询而来;但对于物流系统来说,其系统里的业务主键(拆分键)是运单号,此时,运单号如果和订单号相同,即可完美解决这一问题。订单表和运单表的基本数据模型如下:
订单表:
拆分键 商品编号 收货地址
Order_id Sku_code address
运单表:
拆分键 订单号 重量
Waybill_code Order_Id weight
2、索引法:
对于常用的非拆分键,我们可以将其与拆分键之间建立一个索引关系,当按该条件进行查询时,先查询对应的拆分键,再通过拆分键查询对应的数据信息。订单表的索引法查询表模型如下:
索引表:
非拆分键查询条件 拆分键
用户编码 订单号
运单号 订单号
3、基因法:
拆分键与非拆分键的单号生成规则中,存在相同规则的部分且该部分被用作拆分键来进行库表的定位。比如:订单号生成时,生成一个Long类型的单号,由于Long是64位的,我们可以用其低4位取模来定位该订单存储的数据库及表,其他的表的拆分键也用Long类型的低4位取模来定位对应的数据库及表。还是用订单表和运单表的模型做解释如下:
订单表:
拆分键 商品编号 收货地址
Order_id Sku_code address
运单表:
拆分键 订单号 重量
Waybill_code Order_Id weight
当通过订单表里的订单号查运单表时,可以直接用订单号来查询其对应的运单信息。

三、 拆分键的生成

拆分键选取后,接下来是拆分键的生成,拆分键的生成有多种方式,建议根据业务量及并发量的大小来确定拆分键生成的规则,在这里介绍几种常用的拆分键生成规则。
1、数据库自增主键
在并发量不大的情况下,我们可以使用MySQL数据库里的自增主键来实现拆分键。
2、UUID
在Java里,可以使用Java自带的UUID工具类直接生成,UUID的组成:UUID=当前日期和时间+时钟序列+全局唯一的IEEE机器识别号组成。其中,全局唯一的IEEE机器识别号一般是通过网卡的MAC地址获得,没有网卡时以其他的方式获得。UUID生成的编号不会重复,但不利于阅读和理解。
3、雪花算法
雪花算法生成的ID是一个64位大小的整数,结构如下:
图片
从其结构可以看出,第一位是符号位,在使用时一般不使用,后面的41位是时间位,是由时间戳来确定的,后面的10位是机器位,最后的12位是生成的ID序列,是每毫秒生成的ID数,即每毫秒可以生成4096个ID。从该结构可以看出,10位机器位决定了使用机器的上限,在某些业务场景下,需要所有的机器使用同一个业务空间,这可能导致机器超限;同时,每一个机器分配后如果机器宕机需要更换时,对ID的回收也需要有相应的策略;最为关键的一点是机器的时间是动态调整的,有可能会出现时间回退几毫秒的情况,如果这个时候获取到这个时间,则会生成重复的ID,导致数据重复。
四、 提升总结
单数据库不能满足业务场景的情况下,主要的思路还是要进行拆分,无论是NoSQL还是关系数据库,随着业务量的增长,都得需要把多个服务器资源组合成一个整体共同来支撑业务。数据库拆分后,如果业务上有多个复杂查询条件的需求,一般就得把数据同步到NoSQL数据库里,由NoSQL来提供支持。无论什么时候,数据库提供的主要能力是存储能力,对于复杂的计算需求,一般是需要在业务逻辑里实现。
-end-
作者|廖宗雄

标签:分库,运单,数据库,订单号,生成,订单,拆分,分表
From: https://www.cnblogs.com/88223100/p/Design-of-Splitting-Keys-for-Database-and-Table-Segment

相关文章

  • 编程语言中:什么是方法?方法应该怎么拆分?
    在一个群聊里面,无意间听到很多人说不知道应该怎么去拆分方法,总是写出一个大的方法体。其实这个和编程思想有关系。在这里草草的给他们写一下说明,其他东西也不展开说了。......
  • MySQL存储过程、索引、分表对比
    MySQL存储过程、索引和分表是用于提高查询效率的三种不同方法,它们各自对查询效率有不同的影响和应用场景。以下是它们的对比:MySQL存储过程:影响查询效率:存储过程通常不直接影响查询效率,因为它们是用于封装查询逻辑和执行多个SQL语句的数据库对象。存储过程主要有助于减少网络......
  • MySQL 分表查询
    分表是一种数据库分割技术,用于将大表拆分成多个小表,以提高数据库的性能和可管理性。在MySQL中,可以使用多种方法进行分表,例如基于范围、哈希或列表等。下面将详细介绍MySQL如何分表以及分表后如何进行数据查询。基于哈希的分表基于哈希的分表是一种将数据分散到多个子表中的数据......
  • 将pandas某列中的字符串按空格或换行符拆分成列表,然后剔除列表中的中文字符串
    要删除PandasDataFrame中某一列中的汉字字符,然后将该列的字符串按空格或换行符拆分成列表,可以按照以下步骤进行:假设你有一个名为df的DataFrame,要操作的列名为'某列':importpandasaspd#创建示例DataFramedata={'某列':['Hello你好','Thisisatest','Python编......
  • list集合分组拆分
    #n组publicstatic<T>List<List<T>>averageAssign(List<T>source,intn){List<List<T>>result=Lists.newArrayList();intrenumber=source.size()%n;intnumber=source.size()/n;......
  • 数据库分表如何设计的?
    水平分表:以字段为依据,按照一定策略(hash、range等),将一个表中的数据拆分到多个表中。垂直分表:以字段为依据,按照字段的活跃性,将表中字段拆到不同的表(主表和扩展表)中。水平分表的方式:1.范围路路由:选取有序的数据列(例如,整形、时间戳等)作为路路由的条件,不不同分段分散到不同的数据库表2.Hash......
  • pandas-数据合并和拆分
    pandas-数据合并和拆分目录pandas-数据合并和拆分数据拆分拆分行拆分列按条件拆分数据合并appendmergeconcatjoin参考资料数据集拆分是将一个大型的数据集拆分为多个较小的数据集,可以让数据更加清晰易懂,也方便对单个数据集进行分析和处理。同时,分开的数据集也可以分别应用不同......
  • 【mysql】mysql分表分库
     MySQL按日期分表sql语句创建+XORM基于XORM框架实现分表MySQL数据库按时间分表的查询方法Mysqlunion与unionall究竟怎么用?到底有什么区别 #gorm分库分表https://gitee.com/lemontree/gorm-shardinghttps://blog.csdn.net/wyhstars/article/details/80609652http......
  • 3数据库分区分表分库
    分区、分表、分库分区由数据库系统来分将一张表拆分多个文件存储在多个物理文件里分表:是将总表分成多个独立的表格与分区的差别是分成多个表但是不利于分布式分库:都有利于提升性能           分区                ......
  • 【很难啊、拆分数、观察】P6944 [ICPC2018 WF] Gem Island
    简要题面:求\(n+d\)的\(n\)正整数拆分中,最大的\(r\)个数之和的期望。首先是典中典:KeyObservation:最后的形态\(a_1\toa_n\)的概率都是一样的。Proof:考虑组合数\(\binom{d}{a_1-1,a_2-1.....,a_n-1}\)。然后我们每次在每一个\(a_i-1\)每次分裂有......