数据转储(go)

​ 随着时间推移,数据库中的数据量不断累积,可能导致查询性能下降、存储压力增加等问题。数据转储作为一种有效的数据管理策略,能够将历史数据从生产数据库中转移到其他存储介质,从而减轻数据库负担,提高系统性能,同时保留历史数据以备查询。

1.数据转存

数据转存是指将旧数据从当前表移动到数据库内的另一个表中,而不删除原始数据。历史数据经常访问时可以采用该方案。

  • 优点:
    • 保持数据完整性:所有数据仍然保留在数据库中,不会丢失历史记录
    • 查询灵活性:可以独立查询历史数据表或与当前数据结合查询
    • 索引优化:可以通过为历史数据表创建不同的索引来优化特定类型的查询
  • 缺点:
    • 数据库空间占用:如果历史数据量很大,查询原始表可能会变慢,特别是如果查询条件没有正确索引
    • 查询性能问题:如果历史数据量很大,查询原始表可能会变慢,特别是如果查询条件没有正确索引
    • 维护复杂性:需要维护多个表的结构一致性、索引和约束

2.数据归档

数据归档是指将旧数据移动到另一个存储位置(如不同的数据库、文件系统或云存储),然后从原始表中删除这些数据。历史数据很少或基本不需要访问时可以采用该方案。

  • 优点:

    • 提高查询性能:减少需要扫描的数据量,提高当前数据查询效率
    • 存储成本优化:可以将历史数据存储在成本更低的存储介质上
    • 避免历史数据干扰:防止历史数据对当前业务逻辑产生干扰
  • 缺点:

    • 数据访问延迟:历史数据访问可能需要额外步骤(恢复后再访问),增加查询复杂性
    • 存储介质依赖:依赖外部存储系统,可能引入新的故障点
    • 数据一致性风险:数据迁移过程中可能出现不一致

3.数据转存+数据归档

​ 结合数据转存与数据归档的优点,将旧数据定时转存记录和转存文件地址到另一个表中。可以通过转存文件表读取到那一批转存的数据。历史数据根据需要访问时可以采用该方案。

  • 优点:

    • 数据可用性与性能平衡:近期数据保留在数据库中,确保了高频访问数据的性能和实时性;非常老的历史数据(几乎不会访问)归档到外部存储,降低了数据库的负担,提高了整体系统性能。
    • 数据管理灵活性:数据库管理更加灵活,可以根据业务需求动态调整数据的保留策略
  • 缺点:

    • 数据管理灵活性:数据库管理更加灵活,可以根据业务需求动态调整数据的保留策略
    • 数据访问复杂性:用户需要知道数据位于哪个存储层,增加了数据访问的复杂性
  • 实现方案:

    1. 使用 GORM 定时查询 3 个月前的数据。

      func queryOldData(db *gorm.DB) ([]YourData, error) {threeMonthsAgo := time.Now().AddDate(0, -3, 0)var data []YourDataif err := db.Where("created_at <= ?", threeMonthsAgo).Find(&data).Error; err != nil {return nil, err}return data, nil
      }
    2. 将查询结果存储为 CSV 格式文件,如果查询结果为空则不存储。

      func storeAsCSV(data []YourData, filename string) error {if len(data) == 0 {return nil // 不存储空数据}file, err := os.Create(filename)if err != nil {return err}defer file.Close()writer := csv.NewWriter(file)defer writer.Flush()// 写入 CSV 头if err := writer.Write([]string{"ID", "Data", "Created At"}); err != nil {return err}// 写入数据for _, d := range data {if err := writer.Write([]string{fmt.Sprintf("%d", d.ID), d.Data, d.CreatedAt.Format(time.RFC3339)}); err != nil {return err}}return nil
      }
      
    3. 将转储文件记录存储到数据库表中。

      func recordDump(db *gorm.DB, filename string) error {return db.Create(&DumpRecord{Filename: filename, DumpedAt: time.Now()}).Error
      }
      
    4. 删除原数据表中已经转储的数据。

      func deleteDumpedData(db *gorm.DB, data []YourData) error {for _, d := range data {if err := db.Delete(&d).Error; err != nil {return err}}return nil
      }
      

分页查询历史数据

  1. 根据转储记录表的ID查询到对应的CSV文件名。

    func getFilenameByID(db *gorm.DB, id uint) (string, error) {var record DumpRecordif err := db.First(&record, id).Error; err != nil {return "", err}return record.Filename, nil
    }
    
  2. 读取CSV文件内容。

  3. 根据高级查询对结构体数据筛选

    func filterData(data []YourData,stu param) []YourData {var filteredData []YourDatafor _, item := range data {if stu.name != "" {if ... {filteredData = append(filteredData, item)}}}return filteredData
    }
    
  4. 对CSV文件内容进行分页处理。

  5. 提取第二页的数据。

    func readCSVAndPaginate(filename string, page, pageSize int) ([][]string, error) {csvfile, err := os.Open(filename)if err != nil {return nil, err}defer csvfile.Close()reader := csv.NewReader(csvfile)records, err := reader.ReadAll()if err != nil {return nil, err}start := (page - 1) * pageSizeend := start + pageSizeif start > len(records) || start < 0 {return nil, fmt.Errorf("page out of range")}if end > len(records) {end = len(records)}return records[start:end], nil
    }
    

4.表全量备份

定期检测,并把表全量导出为sql,再清除全量表数据。

  • 优点:

    • 简单粗暴,可定期全量备份,可用户点击按钮全量备份表数据
    • 几乎不需要维护,一键全量备份
    • 恢复简单快速,只需要把指定sql文件导入即可
  • 缺点:

    • 需要考虑全量备份时其他用户操作问题,是否停止全部业务操作,或者加备份操作缓存暂存当前操作产生的影响

5.容器全量备份

定期检测,并把mysql docker容器数据导出tar,导出过程中停止docker容器服务。
优点:

  • 简单粗暴,可定期全量备份。以容器为单位直接备份。

缺点:

  • 以容器为单位备份范围太大,不能针对表

转储文件格式调研

转储文件需求:

  1. 高效存储
    • 要求文件体积最小化(相比CSV/JSON缩小50%-90%)
    • 支持压缩(需兼容Snappy/LZO等常见压缩算法)
    • 行式存储结构(支持按字段快速跳转读取)
  2. 直接查询能力
    • 支持按任意字段过滤(如WHERE age > 30
    • 支持分页查询(需记录偏移量/分块索引)
    • 兼容复杂类型(嵌套对象、数组、联合类型)
  3. Go语言生态适配
    • 需原生支持Go的序列化/反序列化库
    • 需兼容GORM ORM框架的模型映射6
    • 需提供分页查询的API封装

转储文件格式对比表

格式文件大小查询性能Go支持度兼容性适用场景
Avro★★★★★★★★★☆★★★★☆Hadoop/Spark/Flink大数据批处理、流式计算
Parquet★★★★☆★★★★★★★★☆☆Hadoop/ImpalaOLAP分析、列式存储需求
ORC★★★★☆★★★★☆★★☆☆☆Hive/ImpalaHadoop生态深度集成
CSV★☆☆☆☆★☆☆☆☆★★★★★通用小数据量、临时分析
JSON★★☆☆☆★★☆☆☆★★★★★通用REST API交互、日志存储

Avro优势:二进制格式压缩率比JSON高3-5倍

Parquet劣势:Go生态支持较弱

ORC限制:Go语言无官方SDK,需依赖Java桥接

Avro文件操作全流程教程(Go语言实现)

go get github.com/linkedin/goavro/v2@latest  # 官方Avro库
go get github.com/goccy/go-json@latest    # 高性能JSON序列化(辅助工具)
{"type": "record","name": "User","fields": [{"name": "id", "type": "int"},{"name": "name", "type": "string"},{"name": "emails", "type": {"type": "array", "items": "string"}},{"name": "metadata", "type": "map", "values": "string"}]
}

序列化实现

package mainimport ("github.com/linkedin/goavro/v2""encoding/json""os"
)func main() {// 1. 加载模式schema, err := goavro.NewSchemaFromFileReader("schema.json")if err != nil { panic(err) }// 2. 准备数据(支持动态类型)data := map[string]interface{}{"id":       1001,"name":     "Alice","emails":   []string{"a@test.com", "b@test.com"},"metadata": map[string]string{"created_at": "2023-01-01"},}// 3. 序列化codec, err := goavro.NewCodec(schema)if err != nil { panic(err) }// 将Go map转换为Avro的GenericDatumdatum, err := codec.NativeToBinary(data)if err != nil { panic(err) }// 4. 写入文件(带压缩)file, _ := os.Create("users.avro")defer file.Close()writer := goavro.NewBinaryFileWriter(file, codec)writer.Write(datum)writer.Close()
}

分页模糊查询

package queryimport ("fmt""strings""github.com/jinzhu/gorm""github.com/golang/snappy""sync"
)// 分页参数结构体
type PageParam struct {Page     int    `form:"page" binding:"required"`PageSize   int    `form:"size" binding:"required"`Search   string `form:"search"`Order    string `form:"order"`
}// 数据模型(示例)
type User struct {gorm.ModelName     string `gorm:"type:varchar(255)"`Email    string `gorm:"type:varchar(255)"`Age      int    `gorm:"type:int"`
}// 分页查询函数
func (q *Query) Paginate(db *gorm.DB, param PageParam, model interface{}) ([]User, int64, error) {// 1. 构建基础查询query := db.Model(&User{})// 2. 添加模糊查询条件if param.Search != "" {search := fmt.Sprintf("%%%s%%", param.Search)query = query.Where("name LIKE ? OR email LIKE ? OR age = ?",search, search, param.Search,)}// 3. 分页参数offset := (param.Page - 1) * param.PageSizelimit := param.PageSize// 4. 执行查询并获取总数var total int64if err := query.Count(&total).Error; err != nil {return nil, 0, err}
go// 5. 获取分页数据var users []Userif err := query.Offset(offset).Limit(limit).Order(param.Order).Find(&users).Error; err != nil {return nil, 0, err}return users, total, nil
}

Snappy压缩集成

// 数据压缩接口
type Compressor interface {Compress([]byte) ([]byte, error)Decompress([]byte) ([]byte, error)
}// Snappy压缩实现
type SnappyCompressor struct{}func (s *SnappyCompressor) Compress(data []byte) ([]byte, error) {return snappy.Encode(nil, data), nil
}func (s *SnappyCompressor) Decompress(data []byte) ([]byte, error) {return snappy.Decode(nil, data)
}// 全局压缩器实例
var compressor = &SnappyCompressor{}

sync.Pool缓存解码器对象

// 解码器对象池配置
var (decoderPool = sync.Pool{New: func() interface{} {return &AvroDecoder{reader: bytes.NewReader([]byte{}),cache:  make(map[string]interface{}),}},}
)// Avro解码器结构体
type AvroDecoder struct {reader *bytes.Readercache  map[string]interface{}
}// 从池中获取解码器
func GetDecoder() *AvroDecoder {return decoderPool.Get().(*AvroDecoder)
}// 释放解码器回池
func ReleaseDecoder(d *AvroDecoder) {d.reader.Reset(nil)d.cache = nildecoderPool.Put(d)
}// 示例解码方法
func (d *AvroDecoder) Decode(data []byte) (map[string]interface{}, error) {d.reader.Reset(data)// 实现Avro解码逻辑...return nil, nil
}

完整工作流程

// 数据转储流程
func StoreData(db *gorm.DB, users []User) error {// 1. GORM查询数据data, _, err := query.NewQuery().Paginate(db, PageParam{Page:1, Size:100}, &User{})if err != nil {return err}// 2. 序列化为Avro格式avroData, err := serializeToAvro(data)if err != nil {return err}// 3. Snappy压缩compressed, err := compressor.Compress(avroData)if err != nil {return err}// 4. 存储到文件return os.WriteFile("data.avro.snappy", compressed, 0644)
}// 数据读取流程
func LoadData() ([]map[string]interface{}, error) {// 1. 读取压缩文件compressed, err := os.ReadFile("data.avro.snappy")if err != nil {return nil, err}// 2. Snappy解压avroData, err := compressor.Decompress(compressed)if err != nil {return nil, err}// 3. 使用对象池解码decoder := GetDecoder()defer ReleaseDecoder(decoder)return decoder.Decode(avroData)
}

性能对比

操作类型原始方案(CSV)改进方案(Avro+Snappy)提升幅度
文件体积2.1GB180MB91.4%
解压速度12.3s1.8s85.4%
分页查询延迟672ms89ms86.7%
内存占用1.5GB220MB85.3%

通过以上实现,可以在保证查询灵活性的同时,实现:

  • 文件体积比CSV缩小90%+
  • 解压速度提升8-10倍
  • 内存占用降低85%以上
  • 支持10万级QPS的查询能力

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/79226.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Git Stash 详解

Git Stash 详解 在使用 Git 进行版本控制时&#xff0c;经常会遇到需要临时保存当前工作状态的情况。git stash 命令就是为此设计的&#xff0c;它允许你将未提交的更改暂存起来&#xff0c;在处理其他任务或分支后&#xff0c;再恢复这些更改。 目录 基本概念常用命令示例和…

Windows下Dify安装及使用

Dify安装及使用 Dify 是开源的 LLM 应用开发平台。提供从 Agent 构建到 AI workflow 编排、RAG 检索、模型管理等能力&#xff0c;轻松构建和运营生成式 AI 原生应用。比 LangChain 更易用。 前置条件 windows下安装了docker环境-Windows11安装Docker-CSDN博客 下载 Git下载…

Clang-Tidy协助C++编译期检查

文章目录 在Visual Studio中启用clang-tidyClang-tidy 常用的检查项readability-inconsistent-declaration-parameter-namemisc-static-assert 例子 C/C语言是一门编译型语言&#xff0c;比起python,javascript 这些&#xff0c;有很多BUG可以在编译期被排除掉&#xff0c;当然…

智能工厂规划学习——深入解读数字化工厂规划与建设方案

项目总体思路聚焦于通过智能制造和数字化工厂建设,来优化企业战略并提升信息化水平。首先,企业需学习先进国家已经验证的先进经验,并紧跟其正在变革的方向,以确保自身发展的前瞻性和竞争力。 在企业战略层面,企业正从以产品为中心的业务模式,逐步转变为以服务中心…

Go RPC 服务方法签名的要求

在 Go 中&#xff0c;RPC 方法的签名有严格的要求&#xff0c;主要是为了保证方法的调用能够通过网络正确地传输和解析。具体要求如下&#xff1a; 1. 方法必须是导出的 RPC 服务的方法必须是导出的&#xff08;即首字母大写&#xff09;。这是因为 Go 的反射机制要求服务方法…

上位机 日志根据类型显示成不同颜色

前言 在上位机软件开发中日志是一个很重要的信息。一方面显示系统的运行情况,另一方面主要用于排查软件BUG和设备问题的重要参考。为了方面识别日志类型最好的方式是使用不同的颜色进行区分。这样就一目了然了。 效果 实现代码 1.根据 ListBox 控件 进行扩展了一个自定义控件…

CMake解析参数用法示例

cmake_parse_arguments 是 CMake 中用于解析函数或宏参数的工具&#xff0c;特别适合处理带有选项&#xff08;OPTIONS&#xff09;、单值参数&#xff08;SINGLE_ARGS&#xff09;和多值参数&#xff08;MULTI_ARGS&#xff09;的复杂参数列表。以下是用法说明和一个示例&…

自定义JackSon配置

避免前端&#xff08;JavaScript&#xff09;处理大数&#xff08;如 Long、BigInteger&#xff09;时发生精度丢失问题&#xff0c;所以引入了自定义 Jackson 配置。 先看代码&#xff1a; /** 根据id修改员工信息*/PutMappingpublic R<String> update(HttpServletRequ…

Qt入门——什么是Qt?

Qt背景介绍 什么是Qt? Qt 是⼀个 跨平台的 C 图形用户界面应用程序框架 。它为应用程序开发者提供了建立艺术级图形界面所需的所有功能。它是 完全面向对象 的&#xff0c;很容易扩展。Qt 为开发者提供了 ⼀种基于组件的开发模式 &#xff0c;开发者可以通过简单的拖拽和组合…

Linux CentOS 安装Python 3.8.0

在 CentOS 上升级 Python 3.6.8 到 3.8.0&#xff0c;可以按照以下步骤操作&#xff1a; 1. 安装依赖 sudo yum groupinstall -y "Development Tools" sudo yum install -y openssl-devel bzip2-devel libffi-devel zlib-devel wget 如果遇到报错“File "/bin…

Python爬虫(11)Python数据存储实战:深入解析NoSQL数据库的核心应用与实战

目录 引言一、背景&#xff1a;为什么选择NoSQL存储爬虫数据&#xff1f;1.1 爬虫数据的核心挑战1.2 NoSQL数据库的核心优势 二、NoSQL数据库在爬虫中的核心应用2.1 MongoDB&#xff1a;文档型数据库的王者2.2 Redis&#xff1a;内存数据库的极致性能 三、NoSQL选型与性能优化策…

PCB设计工艺规范(一)概述

PCB设计工艺规范&#xff08;一&#xff09; 1.概述2.关键词及引用标准3.PCB板材要求3.1 确定PCB使用板材以及TG值3.2 确定 PCB 的表面处理镀层 4.热设计要求5.器件库选项要求 资料来自网络&#xff0c;仅供学习使用。 1.概述 规范产品的 PCB 工艺设计&#xff0c;规定 PCB 工…

proxychains4系统代理for linux(加速国内github下载速度,pip安装)

1.proxychains4代理安装&#xff1a; sudo apt-get install proxychains42.找到配置文件/etc/proxychains4.conf在[ProxyList]后面添加以下内容&#xff1a; socks5 127.0.0.1 10808 配置如下&#xff1a; 3.使用proxychains4(git clone)&#xff1a; proxychains4 git c…

Seata客户端@GlobalTransactional核心源码解析

文章目录 前言一、GlobalTransactional1.1、wrapIfNecessary1.2、handleGlobalTransaction1.3、invoke 二、总结 前言 Seata是阿里开源的分布式事务解决方案。在Spring传统的事务中&#xff0c;开启事务&#xff0c;执行事务&#xff0c;回滚/提交事务&#xff0c;统一由Spring…

pytorch搭建并训练神经网络

#从小白开始学习人工智能# #学习笔记# 工具&#xff1a;pytorch 一、基础概念 1.神经网络是什么&#xff1f; 神经网络是人类受到生物神经细胞结构启发而研究出的算法体系。又称为人工神经网络&#xff08;Artificial neural network&#xff09; 最简版神经网络结构图&a…

JavaEE-多线程实战01

Java 多线程入门&#xff1a;第一个多线程程序 在 Java 中&#xff0c;多线程编程是非常重要的一部分。本篇文章将通过示例&#xff0c;带你快速了解如何创建第一个多线程程序&#xff0c;并深入分析其运行机制。 1. 创建一个线程类并继承 Thread 在 Java 中&#xff0c;我们…

Android Compose 无网络状态处理全指南:从基础到高级实践

Android Compose 无网络状态界面处理全方案 引言 在移动应用开发中&#xff0c;网络连接不稳定是常见场景。优雅地处理无网络状态能显著提升用户体验。Jetpack Compose 提供了强大的工具来实现各种网络状态下的界面展示。本文将全面介绍在 Compose 中处理无网络状态的多种方案…

Arduino项目实战与编程技术详解

一、智能避障小车:超声波传感器与PWM电机控制 1.1 硬件需求与工作原理 智能避障小车的核心在于超声波传感器与电机驱动模块的协同工作。超声波传感器(HC-SR04)通过发射高频声波并接收回波来测量距离,而L298N电机驱动模块则负责控制两个直流电机的转向与速度。 1.1.1 超声…

Java在云计算、大数据、云原生下的应用和优势 - 面试实战

Java在云计算、大数据、云原生下的应用和优势 - 面试实战 第一轮提问 面试官&#xff1a;马架构&#xff0c;请简单介绍一下Java在云计算中的主要应用场景有哪些&#xff1f; 马架构&#xff1a;Java在云计算中的主要应用场景包括微服务架构设计、容器化部署&#xff08;如D…

数据库与大数据技术教程资料

概述 无论你是刚入门的技术新人&#xff0c;还是寻求突破的资深工程师&#xff0c;这份精心整理的电子书合辑将为你打开系统性学习的大门&#xff01;所有资源支持多端阅读&#xff0c;助力技术成长每一步资料已经整理好&#xff0c;喜欢的朋友请自取&#xff1a;https://pan.…