什么是分表
分表是指根据数据量的增长,将一张表分成多张表存储数据的过程。对于大数据量的应用系统,核心是数据管理,如何存储、管理和使用数据是系统稳定性和可扩展性的关键。
在分表策略中,通常会将一张表中的数据分成若干个区域,每个区域单独拆成一张表,这样可以缓解单表数据量过大的压力,提高系统的可扩展性和性能。
为什么需要分表
1. 数据量过大
在数据量超过1亿的情况下,如果单个表存储,查询时需要采取分页查询的方式来查找,查询效率会变得很低。另外,在数据量巨大的情况下,程序的运行效率也会变得极低。因此,为了提高数据检索效率,需要将数据拆成多个表来存储。
2. 表过多导致存储空间不足
如果将大量数据存储在单个表中,将会占用很多存储空间,直接影响数据库的效率。为了充分利用存储空间和优化数据库性能,可以将单张表分成多张表。
3. 数据表被频繁锁定
当单个表中的数据量过大时,对这张表进行增删改查操作时,会经常性地对这张表进行锁定,从而导致其它相关操作不能进行。而将数据表分割成多个表,则可以避免数据表的频繁锁定,提高数据库的性能。
分表策略
1. 以时间为分区
按照时间来拆分我们的数据表,例如可以每天或者每小时或者每分钟为一个数据表,采用分表策略就可以避免将所有的数据都存放放进一个数据表中,这样会导致数据的查询速度变慢。
例如:
//建立以年为单位的表
CREATE TABLE orders_2016(..);
CREATE TABLE orders_2017(..);
CREATE TABLE orders_2018(..);
CREATE TABLE orders_2019(..);
优点:
查询效率高,可快速查询到特定时间段内的记录。
缺点:
表格数量会过多,增加管理复杂度。
对数据结构和业务逻辑要求较高。
2. 明确字段区分不同区域
在表中增加字段以明确不同区域,可以基于区域进行拆分
例如:
CREATE TABLE orders (
order_id int(11) NOT NULL,
order_date datetime NOT NULL,
customer_id int(11) NOT NULL,
order_total decimal(10,2) NOT NULL,
order_region varchar(15) NOT NULL
);
优点:
表格数量不会过多,简化管理。
数据结构和业务逻辑要求较低。
缺点:
若区域数量增多,则会造成单表数据量过大。
数据无法自动分配到不同表中,需要手动控制。
3. 基于ID取模分表
根据表中字段的ID值进行取模分表。
例如:
//建立6张数据表,基于ID将数据存储到不同的表中
CREATE TABLE `orders_0` (
..) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `orders_1` (
..) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `orders_2` (
..) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `orders_3` (
..) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `orders_4` (
..) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `orders_5` (
..) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
优点:
能够自动分配到不同的数据表中,无需手动控制。
琐碎的数据操作能够在特定的数据表中进行。
缺点:
删除操作比较耗时,需要遍历多个表。
当ID冲突时,需要重新计算,可能会造成数据错乱。
MongoDB分表策略
1. Hashed分片策略
按照指定的Key值进行哈希,同样的哈希值落到同一个分片上。MongoDB针对Hashed分片策略提供了自动分片功能,在MongoDB自动分片集群的拓扑结构中,mongos会根据Hashed分片键值范围,将数据自动平均分配至多个Shard中。
优点:
分片均衡,保证负载均衡。
可灵活调整,对集群的节点数进行扩缩容时,不需要手动迁移数据。
缺点:
数据分散,不适合进行跨分片的复杂查询。
数据需要预先Hash,无法支持动态的Schema设计。
2. Range分片策略
按照指定Key值范围进行数据的分片,每个Shard节点有指定的数据范围。MongoDB也能够根据Range分片策略实现自动分片,将数据自动平均分配至多个Shard中。
优点:
分片范围定义灵活,适合多条件检索。
数据隔离较强,适合高并发以及海量数据的处理。
缺点:
Shard的负载不均衡,需要频繁地进行拆分和合并。
总结
在处理大型数据时,采用分表策略是一种非常常用的技术,可以从根本上解决单表数据量过大的问题。分表可以通过时间分区、字段明确分区和ID取模分区等方式进行拆分,而在MongoDB中则可以采用Hashed分片策略和Range分片策略,根据业务需求来选择分表策略。