分库分表与到底要不要用自增ID?

简介: 抛开具体业务需求和场景谈论技术方案,无异于纸上谈兵。没有哪一项技术或解决方案有绝对的好坏、优劣之分。都是相对意义上的区分,否则这些项技术或方案是怎么产生的?一定也是为了解决某类具体场景的问题而产生的,在彼时彼刻都可谓 “先进”技术。

抛开具体业务需求和场景谈论技术方案,无异于纸上谈兵。没有哪一项技术或解决方案有绝对的好坏、优劣之分。都是相对意义上的区分,否则这些项技术或方案是怎么产生的?一定也是为了解决某类具体场景的问题而产生的,在彼时彼刻都可谓 “先进”技术。


从0到1


       在系统新生的时候,预估业务量和数据量都不大。后来,业务越做越好,数据量越来越大,发现单库单表已经不能满足需求了,需要分库分表。你数据库的发展方向大概是这样的:


20.png


       很少会有业务一开始就会设计为分库分表,虽说这样会减少后续的坑,但部分公司刚开始都是以业务为主。


水平 VS 垂直


       如果是单个库太大,这时我们要看是因为表多而导致数据多,还是因为单张表里面的数据多。 如果是因为表多而数据多,使用垂直切分,根据业务切分成不同的库。


      如果是因为单张表的数据量太大,这时要用水平切分,即把表的数据按某种规则切分成多张表,甚至多个库上的多张表。 分库分表的顺序应该是先垂直分,后水平分。 因为垂直分更简单,更符合我们处理现实世界问题的方式。


  • 垂直分表
    也就是“大表拆小表”,基于列字段进行的。一般是表中的字段较多,将不常用的, 数据较大,长度较长(比如text类型字段)的拆分到“扩展表“。一般是针对那种几百列的大表,也避免查询时,数据量太大造成的“跨页”问题。
  • 垂直分库
    垂直分库针对的是一个系统中的不同业务进行拆分,比如用户User一个库,商品Producet一个库,订单Order一个库。
  • 水平分表
    针对数据量巨大的单张表(比如订单表),按照某种规则(RANGE,HASH取模等),切分到多张表里面去。
  • 水平分库分表
    将单张表的数据切分到多个服务器上去,每个服务器具有相应的库与表,只是表中数据集合不同


       于是你开始分表了:也就是将一张大表数据通过某种路由算法将数据尽可能的均匀分配到 N 张小表中。


21.jpg


 而分表策略也有好几种,分别适用不同的场景。比如通过创建时间、主键ID,或流行的 hash+mod 的组合(类似HashMap的策略)


22.jpg


  这里的 hash 便是将我们需要分表的字段进行一次散列运算,使得经过散列的数据尽可能的均匀并且不重复。当然如果本身这个字段就是一个整形并且不重复也可以省略这个步骤,直接进行 Mod 得到分表下标即可。


       当然分表只是第一步,还要做数据迁移,除非是一开始就做好了分表。后面还有分页查询、groupby、多表join和事务等坑需要填。


       目前市面上的分库分表中间件相对较多,可能拿来解决上述提到的问题。比如Atlas(360)、MySQL-Proxy、DBProxy(美团在Atlas上做的改进)、Mycat( 是 Cobar 的进化版本 ,cobar,是 Amoeba 的进化版本,都是阿里的 )。


       关于分库分表的细节和坑这里就不讨论了,也不是本文的重点,都扯远了。


记录标识


       我们回到表的记录标识上来,我们对这个标识有两个主要需求:

  • 全局唯一
  • 趋势有序

       

于是有了以下方法:


  1. 使用数据库自增 auto_increment 来生成全局唯一递增ID。这本没什么问题,如果你使用MySQL,这也是官方建议的。优点不多说了,说下缺点:
    1) 可用性难以保证:数据库常见架构是一主多从+读写分离;
    2) 生成自增ID是写请求,主库挂了就玩不转了
    3) 扩展性差,性能有上限:因为写入是单点,数据库主库的写性能决定ID的生成性能上限,并且难以扩展


  1. 改进的方法:如果我们采用了分库分表的设计,可以每个写库设置不同的auto_increment初始值,以及相同的增长步长。以保证每个数据库生成的ID是不同的。但缺点是丧失了ID生成的“绝对递增性”,数据库的写压力依然很大,每次生成ID都要访问数据库。这时候我们可以采用单点批量ID生成服务,用一个ID生成服务,先批量生成多个ID。这样应用访问ID生成服务索要ID,ID生成服务不需要每次访问数据库,这样好多了,但问题还有,就是服务还是单点。


  1. UUID保证在同一时空中的所有机器都是唯一的。且可以在本地生成,扩展性好,基本可以认为没有性能上限。是个方案,但UUID的也有缺点:无法保证趋势递增、uuid过长,往往用字符串表示,作为主键建立索引查询效率低(B+树为了维持平衡,会引起B+树的节点页分裂和碎片问题)。


  1. Twitter的SnowFlake是一个非常优秀的ID生成方案,实现也非常简单,8Byte 是一个Long,8Byte等于64bit,核心代码就是毫秒级时间41位+10位机器ID+毫秒内序列12位,也可以调整机器位数和毫秒内序列位数比例。借鉴snowflake的思想,结合各公司的业务逻辑和并发量,可以实现自己的分布式ID生成算法。比如:


22.png


缺点是“没有一个全局时钟”,每台服务器分配的ID是绝对递增的,但从全局看,生成的ID只是趋势递增的(有些服务器的时间早,有些服务器的时间晚)美团的Leaf就是一个类SnowFlake的解决方案。


5.甚至还可以利用redis的incr原子性操作自增,但安全性不足。


6.使用TiDB  如果你大胆调整数据库,不使用MySQL了,而使用TiDB,自动扩容,业务不关心分库分表。TiDB 是由 PingCAP 研发的一款定位于在线事务处理 / 在线分析处理(HTAP)的开源融合型数据库产品,实现了一键水平伸缩,强一致性的多副本数据安全,分布式事务,实时 OLAP 等重要特性,目前已广泛应用于金融服务、互联网、制造等行业。


但问题是TiDB 的自增 ID (AUTO_INCREMENT) 只保证自增且唯一,并不保证连续分配。TiDB 目前采用批量分配的方式,所以如果在多台 TiDB 上同时插入数据,分配的自增 ID 会不连续。当多个线程并发往不同的 tidb-server 插入数据的时候,有可能会出现后插入的数据自增 ID 小的情况。此外,TiDB允许给整型类型的字段指定 AUTO_INCREMENT,且一个表只允许一个属性为 AUTO_INCREMENT 的字段。不过虽然有问题也有解决方案,感兴趣的小伙伴可以查找下相关资料。


相关文章
|
9月前
|
人工智能 区块链 数据库
去中心化身份(DID)体系解析:我们真的需要“没有平台”的身份吗?
去中心化身份(DID)体系解析:我们真的需要“没有平台”的身份吗?
988 2
去中心化身份(DID)体系解析:我们真的需要“没有平台”的身份吗?
|
6月前
|
SQL 关系型数据库 MySQL
5款好用的免费MySQL客户端,新手必备!
告别枯燥命令行!数据库小学妹精选5款免费MySQL图形化工具:Workbench(官方全能)、phpMyAdmin(免安装Web版)、DBeaver(多库支持)、HeidiSQL(Windows轻量之选)、TablePlus(高颜值跨平台)。小白友好,语法高亮、自动补全、可视化结构一应俱全,助你高效学SQL!
|
缓存 监控 数据可视化
|
运维 Devops 持续交付
揭秘 Docker 自动部署神器 Websoft9:热门开源软件一键部署
在企业IT建设中,软件部署常面临效率低、易出错等问题。通过Docker与自动化工具,可实现高效、标准化和可追溯的部署流程,提升企业应用交付效率,降低运维门槛,助力中小企业实现自动化部署。
790 5
揭秘 Docker 自动部署神器 Websoft9:热门开源软件一键部署
|
Java Spring
SpringBoot: 启动Banner在线生成工具
SpringBoot: 启动Banner在线生成工具
42913 1
SpringBoot: 启动Banner在线生成工具
|
人工智能 自然语言处理 Java
效率飙升!3 款免费 AI 神器,让代码编写快到飞起
在快节奏的软件开发中,效率至关重要。本文推荐三款免费AI工具助力开发者:ChatCode基于自然语言生成高质量代码框架;CodeChecker实时检查语法与风格问题,提升代码规范性;飞算JavaAI通过一键生成完整工程代码,大幅缩短开发周期。这些工具从不同角度优化开发流程,让开发者事半功倍。
|
9月前
|
存储 弹性计算 安全
新手上云:阿里云服务器ECS租用流程,2026年最新版(图文指南)
2026年阿里云ECS租用最新指南:从账号注册、实名认证到三种购买方式(自定义、快速、活动),图文详解配置选型、支付开通及初始化连接全流程。新手3分钟可完成,支持灵活部署与高性价比选择,官网/控制台一站式操作。
|
存储 数据挖掘 Apache
浩瀚深度:从 ClickHouse 到 Doris, 支撑单表 13PB、534 万亿行的超大规模数据分析场景
浩瀚深度旗下企业级大数据平台选择 Apache Doris 作为核心数据库解决方案,目前已在全国范围内十余个生产环境中稳步运行,其中最大规模集群部署于 117 个高性能服务器节点,单表原始数据量超 13PB,行数突破 534 万亿,日均导入数据约 145TB,节假日峰值达 158TB,是目前已知国内最大单表。
1962 10
浩瀚深度:从 ClickHouse 到 Doris, 支撑单表 13PB、534 万亿行的超大规模数据分析场景
|
SQL 数据可视化 关系型数据库
【MySQL-11】多表查询全解-【多表关系/内外自连接/子查询/多表查询案例链接】(可cv代码&案例演示)
【MySQL-11】多表查询全解-【多表关系/内外自连接/子查询/多表查询案例链接】(可cv代码&案例演示)
|
开发框架 .NET API
.NET 体系概览图集 - 2024 最全总结
.NET Core 是一个免费、跨平台、开源的开发平台,用于一站式构建不同类型的应用程序。 .NET Core 是以 .NET Framework 为基础,但是经过重新设计、实现的的新一代框架,实现了原 .NET Framework 中的几乎所有功能,核心特点就是开源、跨平台。
1850 0
.NET 体系概览图集 - 2024 最全总结