数据库分片与分区的区别

334

最近我一直在研究可扩展的架构。在这种情况下,涉及到数据库的两个词是分片(sharding)分区(partitioning)。我查看了它们的描述,但仍然感到困惑。

请Stackoverflow的专家帮助我正确理解基础知识:

  • 分片分区之间有什么区别?
  • “所有分片数据库本质上都是在不同节点上进行了分区,但并非所有分区数据库都必须是分片的。”这种说法是否正确?

2
这个可能会有所帮助:了解数据库分片技术。 - mchawre
7个回答

259

划分是将数据在表格或数据库之间分割的通用术语。Sharding是水平划分中的一种具体类型。

在这里,你可以通过一些逻辑或标识符来跨多个实例或服务器复制架构,以知道要查找数据的实例或服务器。这种标识符通常称为“分片密钥”。

常用的无关键逻辑是使用字母表来划分数据。 A-D 是第 1 个实例,E-G 是第 2 个实例等。客户数据非常适合此项技术,但如果划分不考虑某些字母比其他字母更常用,则在实例之间其大小会有所不同。

另一种常见的技术是使用键同步系统或逻辑来确保跨实例的唯一键。

一个众所周知的例子是Instagram在早期如何解决其分区问题(请参见下面的链接)。他们开始将数据从一开始就分割到非常少的服务器上,使用Postgres进行划分。我相信那几个物理块上有数千个逻辑分片。阅读他们 2012 年的精彩文章:Instagram 工程 - Sharding & IDs

请参见此处:http://www.quora.com/Whats-the-difference-between-sharding-and-partition


31
分片是一种HP类型,但它并不是HP。 - NoChance
3
我理解的水平分区是将表中的行拆分成几个子表(可能在同一模式或数据库实例中),而分片是对水平分区的进一步操作,将子表放入单个数据库中的不同模式,或将它们放入不同机器上的独立数据库实例中。是否正确? - Jonathan Hartley
难道说分片不是将模式划分而不是复制它吗? - Adelin
1
@Adelin 实际上,我认为这是不正确的,因为分片是指通过行将数据分散到多个节点中,而不是列(水平分区)。如果您垂直分区您的数据,则按列拆分表格。例如,在DB1中放置名称为A-N的用户,在DB2中放置名称为O-Z的用户,其中模式相同,这是分片(水平分区),而在DB1中放置用户名,在DB2中放置电子邮件,并使用user_id链接它们,将是垂直分区。 - Canis

81

我也一直在研究这个问题,虽然远非权威,但我已经收集了一些关键事实和要点,想分享一下:

分区是将逻辑数据库或其构成元素划分为不同的独立部分。通常通过数据库分区来进行可管理性、性能或可用性方面的处理,以实现负载均衡。

https://en.wikipedia.org/wiki/Partition_(database)

分片是分区的一种类型,如水平分区(HP)。

还有垂直分区(VP),它将表拆分为更小的不同部分。规范化也涉及到将列分割成多个表,但垂直分区甚至在已经规范化的情况下仍会对列进行分区。

https://en.wikipedia.org/wiki/Shard_(database_architecture)

我非常喜欢Tony Baco在Quora上的回答,他让你从模式(而不是列和行)的角度思考。他说...

"水平分区"或分片是复制[拷贝]模式,然后基于分片键划分数据的过程。

"垂直分区"涉及将模式分割(数据也随之移动)。

https://www.quora.com/Whats-the-difference-between-sharding-DB-tables-and-partitioning-them

Oracle的数据库分区指南有一些不错的图表。我从文章中摘录了一些内容。

https://docs.oracle.com/cd/B28359_01/server.111/b32024/partition.htm

何时分区表

以下是一些应当考虑对表进行分区的建议:

  • 大于 2 GB 的表应始终被视为候选对象进行分区。
  • 包含历史数据的表,在其中新数据添加到最新的分区中。典型的例子是一个历史表,只有当前月份的数据可以更新,其余 11 个月份为只读。
  • 当需要将表的内容分布在不同类型的存储设备上时。

分区剪枝

分区剪枝是使用分区的最简单和最重要的手段来提高性能。分区剪枝通常可以将查询性能提高数个数量级。例如,假设一个应用程序包含一个订单表,其中记录了历史订单,该表按周进行了分区。请求单个星期的订单的查询仅访问订单表的一个分区。如果订单表拥有两年的历史数据,则该查询将仅访问一个分区,而不是 104 个分区。这个查询可能会因为分区剪枝而执行得快100倍。

分区策略

  • 范围
  • 哈希
  • 列表

您可以阅读它们的文本并可视化它们的图像,这些都很好地解释了它们。

最后,重要的是要理解数据库非常耗费资源:

  • CPU
  • 磁盘
  • I/O
  • 内存

许多 DBA 会在同一台机器上进行分区,其中分区将共享所有资源,但通过分割数据和/或索引提供磁盘和 I/O 改进。

其他策略将采用“共享无物”架构,其中分片将驻留在单独且不同的计算单元(节点)上,拥有100%的CPU、磁盘、I/O和内存。这样做提供了自己的一套优势和复杂性。

https://zh.wikipedia.org/wiki/共享无事架构


"水平分区"或"分片"是复制模式,然后根据分片键将数据划分为多个部分。这种说法是自我重复的。" - 8bitjunkie
1
所以有一面镜子,它是破碎的,因此有了这个词源学。 - mckenzm
我希望人们停止将规范化与分区/分片混为一谈 - 这只会让事情变得更加混乱,掩盖了规范化的要点。数据的物理和逻辑存储方式不同,它们出于不同的原因,并且具有不同的后果。此外,规范化几乎总是需要在数据库设计中执行/成为一部分,而分区/分片仅在涉及性能和可用性的规模问题时才相关。 - Bob

58
看起来这个回答解决了您的两个问题:
水平分区将一个或多个表按行进行拆分,通常在模式和数据库服务器的单个实例中。如果存在一种明显的、稳健的、隐式的方式可以识别哪个表格中包含特定行,而不需要先查询索引,则它可能通过减少索引大小(从而减轻搜索工作量)提供优势,例如,“CustomersEast”和“CustomersWest”表的经典示例,其中他们的邮政编码已经指示了他们将被找到的位置。
分片超越了这个范畴:它以相同的方式将有问题的表格进行分区,但它跨越潜在的模式实例进行。明显的优点是,大型分区表的搜索负载现在可以分布在多台服务器上(逻辑或物理),而不仅仅是分布在同一逻辑服务器上的多个索引。
来源: 维基-Shard
分片是将数据记录存储在多台机器上的过程,是MongoDB应对数据增长需求的方法。随着数据量的增加,单台机器可能无法足够存储数据或提供可接受的读写吞吐量。分片通过水平扩展来解决这个问题。通过分片,您可以添加更多机器来支持数据增长和读写操作的需求。
来源:MongoDB

26
考虑一个数据库中有100列和1百万行的表格,在分区中,可以将表格分成2个或多个具有以下属性的表格:
  1. 0.4百万行(table1),0.6百万行(table2)

  2. 一百万行和60列(table1)以及一百万行和40列(table2)

    可能会有多种情况。

这是一般的分区方式。但是,Sharding仅涉及第一种情况,即我们基于行来划分数据。如果我们将表格划分为多个表格,则需要维护多个相似的模式副本,因为现在我们有了多个表格。

1
这使得它非常清晰,谢谢! - Chen Ni

23
关于分区,请勿使用“复制”一词。复制是一个不同的概念,不在本页面的讨论范围内。 当我们谈论分区时,更合适的词是“划分”,而当我们谈论分片时,更合适的词是“分配”。 在分区中(通常和常规理解下),大型数据表的行被划分为两个或更多个不重叠(不共享任何行)的组。您可以将每个组称为一个分区。这些组或所有分区仍然在单个RDMB实例的控制之下,这是全部逻辑。每个组的基础可以是哈希、范围等等。如果您有一张包含十年数据的表,则可以根据非空列CREATE_DATE设置分区边界,将每年的数据存储在单独的分区中。查询数据库时,如果您指定了一个介于1999年1月1日和2000年12月31日之间的创建日期,则只会命中两个分区,并且是顺序的。我在处理超过十亿条记录的DB上做过类似的操作,使用索引等工具后,SQL查询时间从30秒缩短到50毫秒左右。 分片是将每个分区放置在不同的节点/机器上。现在可以并行地在分区/分片中搜索。

这完全有道理。 - Paramvir Singh Karwal

7

Sharding水平分区的一种特殊情况,其中分区跨越多个数据库实例。如果数据库进行了分片,则意味着它被划分了。


3

水平分区在移动到另一个数据库实例*时,变成了一个数据库分片

数据库实例可以在同一台机器上或另一台机器上。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接