數據轉儲(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.pswp.cn/bicheng/79226.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/79226.shtml
英文地址,請注明出處:http://en.pswp.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.…