我最近一直在阅读有关可伸缩架构的文章。在这种情况下,关于数据库不断出现的两个词是分片和分区。我查了一下描述,但最后还是懵了。

stackoverflow的专家能帮我弄清楚基本的东西吗?

分片和分区之间的区别是什么? “所有的分片数据库本质上都是分区的(在不同的节点上),但所有分区的数据库不一定都是分片的”,这是真的吗?


分区是跨表或数据库划分数据的通用术语。分片是一种特定类型的分区,是所谓水平分区的一部分。

在这里,您可以跨(通常)多个实例或服务器复制模式,使用某种逻辑或标识符来知道要在哪个实例或服务器上查找数据。这种标识符通常被称为“碎片键”。

一种常见的无键逻辑是使用字母表来划分数据。A-D是实例1,E-G是实例2,等等。客户数据非常适合这样做,但是如果分区没有考虑到某些字母比其他字母更常见,那么在实例之间的大小表示就会有些错误。

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

你可以研究的一个众所周知的例子是Instagram在早期是如何解决他们的划分问题的(见下面的链接)。他们开始在很少的服务器上进行分区,使用Postgres从一开始就划分数据。我相信是几千个逻辑碎片在那几个物理碎片上。在这里阅读他们2012年的精彩报道:Instagram工程-切分和id

在这里也可以看到:http://www.quora.com/Whats-the-difference-between-sharding-and-partition

看来这回答了你的两个问题

Horizontal partitioning splits one or more tables by row, usually within a single instance of a schema and a database server. It may offer an advantage by reducing index size (and thus search effort) provided that there is some obvious, robust, implicit way to identify in which table a particular row will be found, without first needing to search the index, e.g., the classic example of the 'CustomersEast' and 'CustomersWest' tables, where their zip code already indicates where they will be found. Sharding goes beyond this: it partitions the problematic table(s) in the same way, but it does this across potentially multiple instances of the schema. The obvious advantage would be that search load for the large partitioned table can now be split across multiple servers (logical or physical), not just multiple indexes on the same logical server.

来源:Wiki-Shard。

分片是跨多个存储数据记录的过程 这是MongoDB满足数据需求的方法 增长。随着数据大小的增加,单个机器可能无法实现 足以存储数据,也不能提供可接受的读写 吞吐量。分片解决了水平缩放的问题。与 通过分片,您可以添加更多的机器来支持数据增长和需求 读取和写入操作。

来源:MongoDB。

我也一直在研究这个问题,尽管到目前为止我是这个问题的参考,但我收集了一些关键的事实和观点,我想分享:

分区是将逻辑数据库或其组成元素划分为不同的独立部分。数据库分区通常是出于可管理性、性能或可用性的考虑,例如为了负载平衡。

https://en.wikipedia.org/wiki/Partition_(数据库)

分片是一种分区,例如水平分区(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个月的数据是只读的。 当一个表的内容需要分布在不同类型的存储设备上时。

分区修剪

Partition pruning is the simplest and also the most substantial means to improve performance using partitioning. Partition pruning can often improve query performance by several orders of magnitude. For example, suppose an application contains an Orders table containing a historical record of orders, and that this table has been partitioned by week. A query requesting orders for a single week would only access a single partition of the Orders table. If the Orders table had 2 years of historical data, then this query would access one partition instead of 104 partitions. This query could potentially execute 100 times faster simply because of partition pruning.

分区策略

范围 哈希 列表

你可以阅读他们的文字,想象他们的图像,这些图像很好地解释了一切。

最后,重要的是要理解数据库是极其资源密集型的:

CPU 磁盘 I / O 内存

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

而其他策略将采用“无共享”架构,其中碎片将驻留在独立的计算单元(节点)上,拥有100%的CPU、磁盘、I/O和内存。提供它自己的一组优势和复杂性。

https://en.wikipedia.org/wiki/Shared_nothing_architecture

假设数据库中的一个表有100万行和100列 在Partitioning中,你可以将表分成2个或更多具有如下属性的表:

40万行(表1),60万行(表2) 100万行60列(表1)和100万行40列(表2) 可能有很多这样的案例

这是一般分区

但Sharding仅指第一种情况,即我们根据行划分数据。如果我们将表划分为多个表,我们需要维护模式的多个类似副本,因为现在我们有多个表。

水平分区的特殊情况下的分片,当分区跨越多个数据库实例时。如果一个数据库是分片的,这意味着根据定义它是分区的。

When talking about partitioning please do not use term replicate or replication. Replication is a different concept and out of scope of this page. When we talk about partitioning then better word is divide and when we talk about sharding then better word is distribute. In partition (normally and in common understanding not always) the rows of large data set table are divided into two or more disjoint (not sharing any row) groups. You can call each group a partition. These groups or all the partitions remain under the control of once RDMB instance and this is all logical. The base of each group can be a hash or range or etc. If you have ten years data in a table then you can store each of the year's data in a separate partition and this can be achieved by setting partition boundaries on the basis of a non-null column CREATE_DATE. Once you query the db then if you specify a create date between 01-01-1999 and 31-12-2000 then only two partitions will be hit and it will be sequential. I did similar on DB for billion + records and sql time came to 50 millis from 30 seconds using indices etc all. Sharding is that you host each partition on a different node/machine. Now searching inside the partitions/shards can happen in parallel.

水平分区移动到另一个数据库实例*时将成为数据库碎片。

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