✅什么是数据归档,一般是怎么做的?
典型回答
数据归档是指将**不再频繁使用的历史数据从主数据库(主表)中转移到低成本的存储位置**(如归档表、归档库或离线存储系统),以减轻系统的存储压力,提高数据库的查询性能,并满足数据保留和审计的需求。
因为对于任何一个系统来说,他的数据一定会区分冷、热,因为时间是不断地推移的,很多历史的数据,他就是不太会再去操作他了,而查询的次数也非常有限。所以就可以做数据归档,或者也叫冷热分离。
数据归档的常见做法
| 是否常见 | 实现成本 | 兼顾查询 | 查询性能 | |
|---|---|---|---|---|
| 分库分表归档 | 是 | 低 | 是 | 一般 |
| 分区归档 | 是 | 低 | 是 | 一般 |
| 数据备份归档 | 否 | 低 | 否 | - |
| 分布式存储归档 | 是 | 高 | 是 | 高 |
| 离线数仓归档 | 是 | 高 | 是 | 低 |
1. 分库分表归档(常见)
最常见的归档的方式就是在主库(表)之外,再建一个历史库(表),然后定期的将历史数据迁移到归档库(表)。一般来说,主表和归档表的表结构是一模一样的。也是一种分库分表的方案,就是历史数据和当前数据在不同的库表中
一般的实现方式就是根据时间、状态等字段,来筛选数据,然后把他们insert到新表中,再从旧表中删除:
-- 归档6个月以前的数据到归档表
INSERT INTO archive_table
SELECT * FROM main_table
WHERE modify_time < DATE_SUB(CURDATE(), INTERVAL 6 MONTH);;
-- 删除主表中的归档数据
DELETE FROM main_table WHERE modify_time < DATE_SUB(CURDATE(), INTERVAL 6 MONTH);;2. 基于分区表的归档(常见)
除了分库分表之外,MySQL 等数据库其实是支持分区表,最常见的就是按照时间分区。这样数据插入的时候就按照分区去插入了,而随着时间的推移,旧的分区慢慢就没有读写流量了。
CREATE TABLE large_table (
id INT NOT NULL,
data TEXT,
create_time DATETIME NOT NULL
) PARTITION BY RANGE (YEAR(create_time)) (
PARTITION p2022 VALUES LESS THAN (2023),
PARTITION p2023 VALUES LESS THAN (2024)
);3. 数据备份归档(互联网用的少,传统企业有用的)
还有一种归档方案,就是将归档数据从数据库中导出并存储在文件系统、对象存储或分布式存储系统中。
但是这个方案,归档后的数据无法做实时查询,只适用于数据留存,以及满足合规要求
# 使用 mysqldump 导出数据
mysqldump -u user -p database_name archive_table > archive_data.sql
# 将数据上传到对象存储
aws s3 cp archive_data.sql s3://archive-bucket/4. 基于分布式存储归档(常见)
除了把历史数据存放在关系型数据库中,还有一种比较常见的就就是把他们放到分布式存储系统(如 Hadoop、ClickHouse、Elasticsearch)存储归档数据。
这么做的好处是可以实现比较好的历史数据的查询性能,比直接用数据库要更好一些。但是成本也会更高一点。
5. 基于离线数仓归档(常见)
我们有很多数据,历史的数据“没用了”的情况,这里的没用指的是不需要查询了,只是会在数据分析、合规场景中会再用到,那么就可以把他们归档到离线数仓中。
这样既能实现数据留存,也能降低成本,而且如果一定要查询也能查,只不过性能差一点而已。
一般的数仓都有自动同步的能力,配置好数据库链接,他就能自动的做离线数据的同步了,还是比较方便的。