当前位置: 首页 > 知识库问答 >
问题:

数据库 - 或许我们都被分库分表约束了思维?

齐航
2024-02-22

概述
这篇文章没什么太多的干货,纯纯是一篇讨论和思考帖。

从业数据库领域三年有余了,从分库分表中间件到数据库团队内核学到了很多东西。也接触了很多项目,包括TiDB、Vitess、Polardb、StarDB等等。

国内的项目好像很多都聚焦于分库分表的概念,包括很多的数据库团队都在尝试这个概念的落地和沉溺于性能的跑分。

最近我在预览MySQL官方,看到了Partitioning的概念,而且占据了很大的篇幅。不由得引人思考,为什么这个概念在我接触的业务中没有被广泛的使用呢?或许我们将来可以有分库分区的概念?

接下来从头缕一下数据库选型的问题吧(以下均以MySQL的Innodb场景为例):

分表、分区、分库有什么用处
在那个远古的时代,物理机器的配置很低,当数据量增大的时候,传统的B+树的高度会越来越高,我们对硬件资源的要求很高,机器往往内存爆仓、IO打满等等。

这导致:

查询速度显著下降。复杂的查询、索引失效、全表扫描等操作变得缓慢。

在大表中创建和维护索引可能会消耗大量的时间和资源。插入、更新和删除操作可能需要花费更长的时间来维护索引,导致性能下降。

读写操作可能导致锁冲突,降低系统的并发处理能力,甚至引发死锁问题。

备份、恢复、数据清理、空间管理等操作变得困难,维护成本和风险增加。

等等。。

后来我们引出了第一个概念:分表

分表
在 5.1版本以前,MySQL并没有分区的概念,为了解决这个问题,无非是单表拆成双表、多表之类的,这样将一个表要面临的问题分散成了两个表或者多个表共同承受。

反思当下,在当前这个物理资源冗余的时代,大部分业务场景下我们的单表真的会比分表的性能差很多吗?有多少时候我们是为了分表而分表?我们的分表逻辑或许需要我们支持更多的功能,比如弹性、事务、一些查询语句的改写,然后一遍一遍的造轮子给运维带来无尽的痛苦。

分库
分表的解决能力还是有限的,我们一台物理机器的能力也是有限的,这时候或许我们可以采用分表的形式,来避免热点问题或者单机器压力过载的问题。

将一个库要面临的问题分散成了两个库或者多个库共同承受。

分区
相关文档

在5.1版本以后MySQL出了一个国内几乎无人问津的分区表的功能。

分区表的实现原理其实和分表差不太多,不过它更靠近文件系统,而没有经过MySQL的应用层或者引擎层。MySQL的物理数据,存储在表空间文件(.ibdata1和.ibd)中,这里讲的分区的意思是指将同一表中不同行的记录分配到不同的物理文件中,几个分区就有几个.idb文件。

随着 MySQL 版本的更新迭代,分区功能也在后续版本中不断得到改进和增强。具体的分区功能支持情况如下:

•MySQL 5.1:引入了 Range 和 List 两种分区类型。支持基本的分区管理和查询优化。
•MySQL 5.5:对分区表的查询优化有所改进,提升了性能。
•MySQL 5.6:引入了更多的分区管理功能,包括 subpartition 子分区、分区交换操作、CHECK 约束等。
•MySQL 5.7:进一步增强了分区表的功能,包括 hash 分区类型、NOWAIT 选项、ALTER TABLE ... EXCHANGE PARTITION 和 ALTER TABLE ... REBUILD PARTITION 等操作。
•MySQL 8.0:继续对分区表进行优化和增强,包括对于自动生成分区键值、分区表的查询性能提升等方面的改进。
这样看起来,这不完全Cover住了分表的概念吗?甚至,这不比业界的分表做的还要好吗。

那为什么我们还要痴迷于分表,或许我们可以采用分区的逻辑吧?

当然,还有一些延伸到运维操作,举个例子:

分区表怎么扩容
详见 ALTER TABLE 语句

1.创建新分区:使用 ALTER TABLE 命令添加新的分区。例如,如果是按照时间范围分区的表,可以增加新的时间范围的分区。
ALTER TABLE your_partitioned_table
ADD PARTITION (PARTITION p_new VALUES LESS THAN (new_value));
这里的 new_value 是新的分区范围。

  1. 数据迁移:使用 ALTER TABLE ... REORGANIZE PARTITION 命令将现有分区中的数据迁移到新的分区中。例如,可以通过将旧分区的数据移动到新分区来实现。

ALTER TABLE your_partitioned_table
REORGANIZE PARTITION old_partition INTO
(PARTITION p_new VALUES LESS THAN (new_value));
这里的 old_partition 是要移动数据的旧分区。

  1. 数据清理(可选):在确认数据迁移成功后,可以考虑清理不再需要的旧分区。使用 ALTER TABLE ... DROP PARTITION 命令可以删除不再需要的旧分区。

ALTER TABLE your_partitioned_table
DROP PARTITION old_partition;
这里的 old_partition 是要删除的旧分区。

显而易见,这是一个原地扩容操作,我们或许不需要引入什么复杂的组建或者逻辑去做resharding。

落地方案猜测
我们或许可以在单表业务场景下遇到问题瓶颈后采用分区的概念,如果分区不够可以采用原地扩容逻辑。当机器达到瓶颈后采用分库的概念达成分库分区的逻辑。

这只是一个猜想,对于我们的数据库厂商,其实只需要将这套逻辑维护好做到高可用的逻辑即可。

当然,围绕着分区和物理数据库我们还有很多扩展内容可以去做,但是这篇文章旨在说明,或许我们不应该被分库分表约束了思维,或许我们不需要做分布式的逻辑,或许在机器性能良好的场景下我们单机器就可以cover住我们的数据量。

此外,一个数据库产品或许应该做到serverless的概念,我们用户不需要理解这么多的逻辑,至于分区或许这个看MySQL文档都可以学习到。

共有1个答案

禄光霁
2024-02-22

作者在这篇文章中提出的主要观点是:

作者认为,分库分表的概念在当今的物理资源冗余的时代可能并不是必须的,因为单表在大部分业务场景下可能并不会比分表的性能差很多。此外,分库分表会给运维带来无尽的痛苦,包括需要支持更多的功能、一遍一遍的造轮子等。

作者提出,我们可以考虑采用分区的逻辑,这类似于分表,但更靠近文件系统,没有经过MySQL的应用层或者引擎层。分区表的实现原理是将同一表中不同行的记录分配到不同的物理文件中,几个分区就有几个.idb文件。分区功能在MySQL的不同版本中得到了改进和增强,包括Range和List两种分区类型、查询优化、subpartition子分区、分区交换操作、CHECK约束等。

作者认为,分区表可以实现原地扩容操作,不需要引入复杂的组件或者逻辑去做resharding。在单表业务场景下遇到问题瓶颈后可以采用分区的概念,如果分区不够可以采用原地扩容逻辑。当机器达到瓶颈后可以采用分库的概念达成分库分区的逻辑。

最后,作者认为,一个数据库产品应该做到serverless的概念,用户不需要理解这么多的逻辑,至于分区这个可以学习到MySQL文档。

 类似资料:
  • 9.4.2.数据库约束 再次运行这个Service,你会发现它执行失败,而在logcat中得到许多SQLException。而这都是数据库约束(database constraint)抛出的异常。 这是因为我们插入了重复的ID。前面从服务端抓取消息数据时,获得了消息的ID字段,并作为主键一并插入本地数据库。但是我们每分钟都会通过getFriendsTimeline()重新抓取最近24小时的20条消

  • 我有一个Oracle表,它有10列-col1、col2、COL3...COL10。我的要求是-对于col1、col2、col3的唯一值集,即(col1、col2、col3)只允许col4的唯一值,即使它是多次。例如:如果有10行COL1=3,COL2='A005',COL3=10,则所有10行的col4值应相同。 我如何在Oracle中放置此限制?

  • 主要内容:1.ShardingSphere概念,2.功能列表,3.项目状态,4.分库分表_结果归并1.ShardingSphere概念 ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈,它由、和 这3款相互独立的产品组成。 他们均提供标准化的数据分片、分布式事务 和 数据库治理功能,可适用于如Java同构、异构语言、云原生等各种多样化的应用场景。 Apache ShardingSphere 旨在充分合理地在分布式的场景下利用关系型数据库的计算和存储能力,而并非实现

  • 问题内容: 以我有一个表的示例为例,该表包含大学课程,一个表包含学生。一堂课有很多学生,一个学生只能上一堂课。(一对多关系)。如果我在其中有一列存储了一个班级的学生总数,那感觉它应该违反了3NF。但是依赖关系在单独的表中。这种依赖关系叫做什么?我们可以说这违反了3NF吗?因为从某种意义上说,它具有违反3NF的所有问题。我想知道这是否是一个相关案例。 问题答案: TL; DR 但是依赖关系在单独的表

  • 问题内容: 我试图在表中插入值。但是只插入一个值。尝试插入新值时,日志猫出现错误。 日志猫显示: 插入行时,这两行显示错误。 EventTableHelper 如何解决呢? 问题答案: 您的代码可能违反了字段上主键的唯一性约束。 两种可能的解决方案是: 确保您为每个对象返回唯一值。现在,我看不到您将任何标识符传递给其构造函数,并且可能所有事件都以相同的值插入。 如果您不希望自己生成ID,则可以将设

  • 本文向大家介绍超大数据量存储常用数据库分表分库算法总结,包括了超大数据量存储常用数据库分表分库算法总结的使用技巧和注意事项,需要的朋友参考一下 当一个应用的数据量大的时候,我们用单表和单库来存储会严重影响操作速度,如mysql的myisam存储,我们经过测试,200w以下的时候,mysql的访问速度都很快,但是如果超过200w以上的数据,他的访问速度会急剧下降,影响到我们webapp的访问速度,而