分库分表之拆分键设计

这篇具有很好参考价值的文章主要介绍了分库分表之拆分键设计。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

1 水平、垂直拆分

在关系数据库中,当单个库的负载、连接数、并发数等达到数据库的最大上限时,就得考虑做数据库和表的拆分。如一个简单的电商数据库,在业务初期,为了快速验证业务模式,把用户、商品、订单都放到一个数据库中,随着业务的发展及用户量的增长,单数据库逐渐不能支撑业务(MySQL中单记录容量超过1K时,单表数据量建议不超过一千万条),这时就得考虑把数据库和表做出拆分。

1.1 垂直拆分

简单的说就是将数据库及表由一个拆分为多个,如我们这里的电商数据库,可以垂直拆分为用户数据库、商品数据库和订单数据库,订单表可以垂直拆分为订单基本信息表,订单收货地址表、订单商品表等,每一个表里保存了一个订单的一部分数据。

分库分表之拆分键设计

1.2 水平拆分

简单的说就是将一个库、一个表扩展为多个库,多个表,每一个拆分后的表中保存的依然是一个订单的完整信息。如电商数据库,我们按水平拆分数据库和表后,每一个拆分后的数据库表与现有未拆分前的都保持一致。

分库分表之拆分键设计

1.3 常用拆分方法

上述仅从理论上讲解了可行的水平、垂直拆分方法,在实际的生产上,我们拆分一般是按照水平拆表、垂直拆库这一原则进行,在业务比较复杂的场景下也会对表进行垂直拆分。

分库分表之拆分键设计

2 拆分键的选取

分库分表的关键项之一是拆分键的选取,一般情况下,拆分键的选取遵循以什么维度进行查询就选取该维度为拆分键。如:订单表就以订单号作为拆分键,商品表就以商品编号作为拆分键。拆分键选取后,对于一些非拆分键的单条件查询,我们需要怎么支持呢?在这里提供3种方法供参考。

2.1 等值法

对于非拆分键的单条件查询,对这一个单条件的赋值,可以将其值与拆分键保持一致。比如在电商场景中,用户下订单后,需要通过物流给用户把商品送到用户手上。对于用户来说仅能看到订单信息,订单上展示的物流信息用户也是通过订单号查询而来;但对于物流系统来说,其系统里的业务主键(拆分键)是运单号,此时,运单号如果和订单号相同,即可完美解决这一问题。订单表和运单表的基本数据模型如下:

1)订单表

分库分表之拆分键设计

2)运单表

分库分表之拆分键设计

在订单表中,拆分键order_id与运单表中的拆分键waybill_code值相同,当按订单号查询运单表里的运单信息时,可以直接查询拆分键waybill_code获取订单对应的运单信息。

2.2 索引法

对于常用的非拆分键,我们可以将其与拆分键之间建立一个索引关系,当按该条件进行查询时,先查询对应的拆分键,再通过拆分键查询对应的数据信息。订单表的索引法查询表模型如下:

1)索引表

分库分表之拆分键设计

例:用户user001在商城上购买了一支笔下单的订单号为10001,商家发货后,物流公司给的运单号是Y0023

2)该用户的订单表、运单表模型如下:

订单表:

分库分表之拆分键设计

运单表:

分库分表之拆分键设计

索引表:

分库分表之拆分键设计

当查询用户(user001)的下单记录时,通过用户编码先查询索引表,查询出user001的所有下单的订单号(10001),再通过订单号查询订单表获取用户的订单信息;同理,根据运单号(Y00232)查询订单信息时,在索引表里先查询到对应的订单号,再根据订单号查询对应的订单信息。

2.3 基因法

拆分键与非拆分键的单号生成规则中,存在相同规则的部分且该部分被用作拆分键来进行库表的定位。比如:订单号生成时,生成一个Long类型的单号,由于Long是64位的,我们可以用其低4位取模来定位该订单存储的数据库及表,其他表的拆分键也用Long类型的低4位取模来定位对应的数据库及表。还是用订单表和运单表的模型做解释如下:

1)订单表

分库分表之拆分键设计

2)运单表

分库分表之拆分键设计

当通过订单表里的订单号查运单表时,通过订单号的低4位定位到该订单号在运单数据库及表的位置,再直接通过脚本查询出订单号对应的运单信息。

3 拆分键的生成

拆分键选取后,接下来是拆分键的生成,拆分键的生成有多种方式,建议根据业务量及并发量的大小来确定拆分键生成的规则,在这里介绍几种常用的拆分键生成规则。

3.1 数据库自增主键

在并发量不大的情况下,我们可以使用MySQL数据库里的自增主键来实现拆分键。

3.2 UUID

在Java里,可以使用Java自带的UUID工具类直接生成,UUID的组成:UUID=当前日期和时间+时钟序列+全局唯一的IEEE机器识别号组成。其中,全局唯一的IEEE机器识别号一般是通过网卡的MAC地址获得,没有网卡时以其他的方式获得。UUID生成的编号不会重复,但不利于阅读和理解。

import java.util.UUID;

public class UUIDTest {
    public static void main(String[] args) {
        UUID uuid = UUID.randomUUID();
        System.out.println(uuid.toString());
    }
}

3.3 雪花算法

雪花算法生成的ID是一个64位大小的整数,结构如下:

分库分表之拆分键设计

从其结构可以看出,第一位是符号位,在使用时一般不使用,后面的41位是时间位,是由时间戳来确定的,后面的10位是机器位,最后的12位是生成的ID序列,是每豪秒生成的ID数,即每毫秒可以生成4096个ID。从该结构可以看出,10位机器位决定了使用机器的上限,在某些业务场景下,需要所有的机器使用同一个业务空间,这可能导致机器超限;同时,每一个机器分配后如果机器宕机需要更换时,对ID的回收也需要有相应的策略;最为关键的一点是机器的时间是动态调整的,有可能会出现时间回退几毫秒的情况,如果这个时候获取到这个时间,则会生成重复的ID,导致数据重复。

4 提升总结

单数据库不能满足业务场景的情况下,主要的思路还是要进行拆分,无论是NoSQL还是关系数据库,随着业务量的增长,都得需要把多个服务器资源组合成一个整体共同来支撑业务。数据库拆分后,如果业务上有多个复杂查询条件的需求,一般就得把数据同步到NoSQL数据库里,由NoSQL来提供支持。无论什么时候,数据库提供的主要能力是存储能力,对于复杂的计算需求,一般是需要在业务逻辑里实现。

作者:京东物流 廖宗雄

来源:京东云开发者社区 自猿其说Tech 转载请注明来源文章来源地址https://www.toymoban.com/news/detail-664336.html

到了这里,关于分库分表之拆分键设计的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 分表?分库?分库分表?实践详谈 ShardingSphere-JDBC

    如果有不是很了解ShardingSphere的可以先看一下这个文章: 《ShardingSphere JDBC?Sharding JDBC?》基本小白脱坑问题         在很多开发场景下面,很多的技术难题都是出自于,大数据量级或者并发的场景下面的。这里就出现了我们要解决的。本文章重点讨论一下在java的spirng开发场

    2024年04月12日
    浏览(38)
  • 掌握MySQL分库分表(一)数据库性能优化思路、分库分表优缺点

    不能⼀上来就说分库分表! 根据实际情况分析,两个角度思考:不分库分表、分库分表 软优化 数据库参数调优 分析慢查询SQL语句,分析执行计划,进行sql改写和程序改写 优化数据库索引结构 优化数据表结构优化 引入NOSQL和程序架构调整 硬优化 提升系统硬件(更快的IO、更

    2023年04月19日
    浏览(59)
  • MySQL运维6-Mycat分库分表之垂直分库

    场景:在业务系统中,涉及一下表结构,但是由于用户与订单每天都会产生大量的数据,单台服务器的数据存储以及处理能力是有限的,可以对数据库表进行拆分,原有数据库如下 说明1:整个业务系统中的表,大致分为四个,商品信息类的表,订单相关的表,用户相关表及

    2024年02月04日
    浏览(48)
  • 如何确定分库还是 分表?

    分库分表 分库分表使用的场景不一样: 分表因为数据量比较大,导致事务执行缓慢;分库是因为单库的性能无法满足要求。 分片策略 1、垂直拆分 水平拆分 3 范围分片(range) 垂直水平拆分 4 如何解决数据查询问题? 分库分表引入的另外一个问题就是数据查询的问题在未分

    2024年02月21日
    浏览(39)
  • 为什么要分库分表?

    什么是分库分表? 分库:从单个数据库拆分成多个数据库的过程,将数据散落在多个数据库中。 分表:从单张表拆分成多张表的过程,将数据散落在多张表内。 为什么要分库分表? 主要为了提升性能、增加可用性。 分库分表前 分库分表后 并发支撑情况 MySQL 单机部署,扛

    2024年02月09日
    浏览(44)
  • MySQL篇之分库分表

             1. 分担了访问压力    2. 解决存储压力         1. 前提,项目业务数据逐渐增多,或业务发展迅速,单表的数据量达1000W或20G以后。         2. 优化已解决不了性能问题(主从读写分离、查询索引…)。         3. IO瓶颈(磁盘IO、网络IO)、CPU瓶颈(

    2024年02月21日
    浏览(52)
  • 数据库-分库分表初探

    数据量在百万以里,可以通过Tina集从库、优化索引等提升性能 数据量超过千万,为了减少数据库的负担,提升数据库响应速度,缩短查询时间,需要进行分库分表 推荐:采用垂直分库水平分表 总结:分库要解决的是硬件资源的问题,不管是拆分字段,还是拆分数据,都是要

    2024年01月25日
    浏览(44)
  • mysql运维------分库分表

    随着互联网以及移动互联网的发展,应用系统的数据量也是成指数式增长,若采用单数据库进行数据存储,存在以下性能瓶颈: IO瓶颈 :热点数据太多,数据库缓存不足,产生大量磁盘IO,效率较低。请求数据太多,带宽不够,网络IO瓶颈。 CPU瓶颈 :排序、分组、连接查询、

    2023年04月11日
    浏览(45)
  • 分库分表 21 招

    (一)好好的系统,为什么要分库分表? 咱们先介绍下在分库分表架构实施过程中,会接触到的一些通用概念,了解这些概念能够帮助理解市面上其他的分库分表工具,尽管它们的实现方法可能存在差异,但整体思路基本一致。因此,在开始实际操作之前,我们有必要先掌握

    2024年02月10日
    浏览(36)
  • Mysql的分库分表策略

    水平切分又称为 Sharding 策略 ,它是将同一个表中的记录拆分到多个结构相同的表中。 当一个表的数据不断增多时,Sharding 是必然的选择,它可以将数据分布到集群的不同节点上,从而缓存单个数据库的压力。 Sharding 策略 哈希取模: hash(key) % NUM_DB 范围: 可以是 ID 范围也可以

    2024年02月16日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包