前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >分库分表之拆分键设计

分库分表之拆分键设计

作者头像
京东技术
发布2024-02-26 10:07:33
1260
发布2024-02-26 10:07:33
举报
文章被收录于专栏:京东技术京东技术

导读

在处理大规模数据库时,为了提高性能和可扩展性,常常需要将一个庞大的数据库拆分成多个小库或小表,这个过程被称为分库分表。拆分键的设计是这一过程中的关键决策,它影响数据的分布、查询效率以及系统的维护成本。本文将探讨如何根据业务需求和数据访问模式选择合适的拆分键,以实现数据库架构的优化,保证系统的高性能和高可用性。

01水平、垂直拆分

在今年的敏捷团队建设中,我通过Suite执行器实现了一键自动化单元测试。Juint除了Suite执行器还有哪些执行器呢?由此我的Runner探索之旅开始了!

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

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

  • 水平拆分:简单的说就是将一个库、一个表扩展为多个库,多个表,每一个拆分后的表中保存的依然是一个订单的完整信息。如电商数据库,我们按水平拆分数据库和表后,每一个拆分后的数据库表与现有未拆分前的都保持一致。
  • 常用拆分方法:上述仅从理论上讲解了可行的水平、垂直拆分方法,在实际的生产上,我们拆分一般是按照水平拆表、垂直拆库这一原则进行,在业务比较复杂的场景下也会对表进行垂直拆分。

02拆分键的选取

理解,首先 MCube 会依据模板缓存状态判断是否需要网络获取最新模板,当获取到模板后进行模板加载,加载阶段会将产物转换为视图树的结构,转换完成后将通过表达式引擎解析表达式并取得正确的值,通过事件解析引擎解析用户自定义事件并完成事件的绑定,完成解析赋值以及事件绑定后进行视图的渲染,最终将目标页面展示到屏幕。

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

当通过订单表里的订单号查运单表时,可以直接用订单号来查询其对应的运单信息。

03拆分键的生成

理解,首先 MCube 会依据模板缓存状态判断是否需要网络获取最新模板,当获取到模板后进行模板加载,加载阶段会将产物转换为视图树的结构,转换完成后将通过表达式引擎解析表达式并取得正确的值,通过事件解析引擎解析用户自定义事件并完成事件的绑定,完成解析赋值以及事件绑定后进行视图的渲染,最终将目标页面展示到屏幕。

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

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,导致数据重复。

4、 开源中间件

ID生成的开源中间件比较多,如美团的leaf,百度的Uid-Generator。在此就不做过多的展开,感兴趣的同学可去github获取对应的源码。

Leaf: https://github.com/Meituan-Dianping/Leaf

Uid-Generator: https://github.com/baidu/uid-generator

04提升总结

理解,首先 MCube 会依据模板缓存状态判断是否需要网络获取最新模板,当获取到模板后进行模板加载,加载阶段会将产物转换为视图树的结构,转换完成后将通过表达式引擎解析表达式并取得正确的值,通过事件解析引擎解析用户自定义事件并完成事件的绑定,完成解析赋值以及事件绑定后进行视图的渲染,最终将目

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-02-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 京东技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 导读
  • 01 、水平、垂直拆分
  • 02 、拆分键的选取
  • 03 、 拆分键的生成
  • 04 、提升总结
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档