進程間傳遞 SQL 文的方法

SQL 文組成

SQL 文有 2 部分組成:

  • SQL 原型,如:INSERT INTO `test1` (`id`,`name`) VALUES (?,?)
  • Args ,? 號對應的值列表

有時,生成 SQL 文的進程和處理 SQL 文的進程,可能不是同一個

這里就涉及到如何高效的把 SQL 文從一個進程傳遞給另外一個進程

EscapeSQL

MySQL 原生 C Api 叫mysql_real_escape_string

該方法可以把 SQL 文兩部分構成轉義為一條 SQL 字符串

因為是字符串 SQL 語句,因此可以方便的從一個進程傳遞到另外一個進程

但是這種方法,有 2 個缺點:

  • 流量變大, Args 是需要轉義的,會插入很多很多的\
  • 無法使用 MySQL 的預處理(PREPARE STATEMENT),使用 MySQL 的性能會變差

Gorm 庫中,無 EscapeSQL API

項目用的是 Gorm

為了調通流程,首先考慮的是通過EscapeSQL傳遞 SQL 字符串

令人驚訝的是,Gorm 庫并無EscapeSQL相關的 API

考慮到,Gorm 庫也是使用 go-sql-driver/mysql 庫和 MySQL 交互

因此查看 go-sql-driver/mysql 庫

結果,go-sql-driver/mysql 庫也無EscapeSQL相關的 API

GitHub 上搜了下 Issues ,發現 golang 庫也有類似的提問、討論: https://github.com/golang/go/issues/18478

說明,EscapeSQL 本身是不建議被使用的

go-sql-driver/mysql 庫 SQL 文處理流程

單步調試了下 go-sql-driver/mysql 的簡易例子

發現內部自動以下流程:

  • 判斷 Args 是是否長度大于 0
    • 否,直接執行 SQL 文
    • 是,
      • PREPARE STATEMENT預處理 SQL 原型
      • 執行預處理,傳遞 Args

借鑒 go-sql-driver/mysql 庫的思路,可以得出以下結論:

  • 進程間傳遞 SQL 文也可以分 2 個步驟:
    • 傳遞 SQL 原型
    • 傳遞 Args

因此問題轉化為如何高效的傳遞 Args

進程間傳遞 Args

通常進程間傳遞數據,可以定義協議。這樣另一個進程可以根據協議理解數據是什么

Args 值列表,存在任意組合性

因此,協議的定義需要一點技巧

粗糙的思路類似:

值部分說明
type指明數據類型
data具體數據

這樣傳遞給另一個進程也能理解

protobuf 的 protowire 包

google.golang.org/protobuf/encoding/protowire protobuf 的編碼器

因為項目中使用 protobuf ,那么可以使用它,減少重復構造輪子

protowire 庫序列化方法,類似:

var b []byteb = protowire.AppendTag(b, protowire.Number(index), protowire.VarintType)
b = protowire.AppendVarint(b, uint64(val))b = protowire.AppendTag(b, protowire.Number(index), protowire.Fixed32Type)
vv := math.Float32bits(val)
b = protowire.AppendFixed32(b, vv)b = protowire.AppendTag(b, protowire.Number(index), protowire.Fixed64Type)
vv := math.Float64bits(val)
b = protowire.AppendFixed64(b, vv)b = protowire.AppendTag(b, protowire.Number(index), protowire.BytesType)
b = protowire.AppendString(b, val)

protowire 庫反序列化方法,類似:

// b data
var vals []interface{}
_, t, i := protowire.ConsumeTag(b)
switch t {
case protowire.VarintType: v, n := protowire.ConsumeVarint(b)b = b[n:]vals = append(vals, v)
case protowire.BytesType: v, n := protowire.ConsumeString(b)b = b[n:]vals = append(vals, v)
case protowire.Fixed32Type:v, n := protowire.ConsumeFixed32(b)b = b[n:]vals = append(vals, math.Float32frombits(v))
case protowire.Fixed64Type: v, n := protowire.ConsumeFixed64(b)b = b[n:]vals = append(vals, math.Float64frombits(v))
}

方法匯總

2 個進程間傳遞 SQL 文

方法建議
使用 EscapeSQL不推薦
SQL 原型 + 自定義 Args 序列化規則看項目情況
SQL 原型 + Args Protobuf 序列化規則推薦

擴展

因為每個項目的存儲方式會有差異。這樣 2 個進程間傳遞 SQL 文還可以進一步適配具體項目,做調整

具體就不展開說明了

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/697730.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/697730.shtml
英文地址,請注明出處:http://en.pswp.cn/news/697730.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

免費搭建個人網盤

免費搭建一個屬于個人的網盤。 服務端 詳情請參考原網站的服務端下載和安裝虛擬磁盤Fuse4Ui可以支持把網盤內容掛載成系統的分區; 掛載工具效果圖:應用端應用端的下載 效果圖

藍橋杯第1374題——鍛造兵器

題目描述 小明一共有n塊鍛造石,第塊鍛造石的屬性值為ai. 現在小明決定從這n塊鍛造石中任取兩塊來鍛造兵器 通過周密計算,小明得出,只有當兩塊鍛造石的屬性值的差值等于C,兵器才能鍛造成功 請你幫小明算算,他有多少種選…

人工智能幾個關鍵節點:深藍,AlphaGo,ChatGPT,Sora

近30年,人工智能幾個關鍵節點:深藍,AlphaGo,ChatGPT,Sora 深藍: 1997年,深藍擊敗卡斯帕羅夫的比賽是通過一系列復雜的算法和策略實現的。深藍的開發團隊使用了一種名為“暴力搜索”的技術&…

OGG-00918 映射中缺少鍵列 id.

2024-02-23 14:54:49 INFO OGG-02756 從線索文件獲取了表 GISTAR.PXPH_PON_ROUTE 的定義。. The following columns did not default because of type mismatches: id OGG-00918 映射中缺少鍵列 id. 目標端有字段ID,由于mysql自增,所以只能是b…

短劇小程序系統,重塑視頻觀看體驗的科技革命

隨著科技的飛速發展,人們對于數字化內容的消費需求也在不斷增長。在這個大背景下,短劇小程序作為一種新型的視頻觀看方式,正逐漸受到大眾的青睞。本文將探討短劇小程序的發展背景、特點以及市場前景,分析其在重塑視頻觀看體驗方面…

如何使用Inno Setup制作Unity構建程序的Windows安裝程序

1. 準備 (1)準備好Unity構建的程序集合 必須包括: Data文件夾(xxx_Data) Mono文件夾(MonoBleedingEdge) 打包的應用程序文件(xxx.exe) Unity播放器dll文件&#xff…

SpringBoot+Docker:高效容器化的最佳實踐

首先為什么要使用 Docker? Docker 是一個強大的工具,它允許開發者將他們的應用程序打包到容器中,以便可以在任何平臺上輕松部署和運行。當涉及到對 Spring Boot 應用程序進行 Docker 化時,每個開發人員都應該遵循一些最佳實踐&am…

編程筆記 Golang基礎 017 數據類型:字符串類型

編程筆記 Golang基礎 017 數據類型:字符串類型 一、字符串類型小結 在Go語言中,字符串(string)是一種基本的數據類型,用于表示文本數據。它是一個不可變的字符序列,由UTF-8編碼的字節組成,支持U…

深入URP之Shader篇15: Shader關鍵字和變體

之前說了很多shader關鍵字的事情,本篇好好說一下關鍵字和變體。 關鍵字是干什么的 我們寫shader的時候,經常會遇到需要處理不同的情況,比如是否啟用霧,光源是平行光還是點光源,是否使用法線貼圖等等。如果為每一種情…

基于springboot+vue的大創管理系統(前后端分離)

博主主頁:貓頭鷹源碼 博主簡介:Java領域優質創作者、CSDN博客專家、阿里云專家博主、公司架構師、全網粉絲5萬、專注Java技術領域和畢業設計項目實戰,歡迎高校老師\講師\同行交流合作 ?主要內容:畢業設計(Javaweb項目|小程序|Pyt…

【selenium】執行 Javascript 腳本 滾動、元素的特殊操作等

某些特殊情況下,使用selenium的api無法操作頁面元素,點擊、滾動實現的某些功能,可以考慮通過執行js來完成。 為什么不用js寫自動化?——selenium第一版是js寫的,但js兼容性存在問題,所以引入webdriver 現在…

ad15 PCB3D模型導出到SOLIDWORKS

注意,工程文件目錄不能用中文,否則導出的文件會不存在 將這個文件直接拖到 SOLIDWORKS 中 下一步很關鍵 顯示出來了 另存為一個轉配體就可以了

12 個對開發人員有用的 Python 腳本

目錄 Create strong random passwordsExtract text from a PDFText processing with PandocManipulate audio with PydubFilter textLocate addressesConvert a CSV to ExcelPattern match with regular expressionsConvert images to JPGCompress imagesGet content from Wiki…

FPS游戲之漫談網絡抖動引發客戶端的卡頓優化

話說各位大神 你們遇到過因為網絡抖動導致客戶端的卡頓現象嗎,或者說測試反饋模擬弱網環境的時候某個功能點會卡頓一下,然后通過各種定位,發現原來是一次性下發了好多包???? 問題來了如果我們在…

海思SD3403,SS928/926,hi3519dv500,hi3516dv500移植yolov7,yolov8(14)

自己挖了一個坑,準備做SS928/SD3403的Yolov8的移植,主要是后臺私信太多人在問相關的問題。先別著急去寫代碼,因為在hi3516dv500下的移植還是比較順利。之前在hi3519av100和hi3559av100系列時遇到過一些問題,所以沒有繼續去移植新的算法。 SS928架構乍一看和hi3559av100特別…

Ubuntu系統本地部署Inis博客結合內網穿透實現遠程訪問本地站點

文章目錄 前言1. Inis博客網站搭建1.1. Inis博客網站下載和安裝1.2 Inis博客網站測試1.3 cpolar的安裝和注冊 2. 本地網頁發布2.1 Cpolar臨時數據隧道2.2 Cpolar穩定隧道(云端設置)2.3.Cpolar穩定隧道(本地設置) 3. 公網訪問測試總…

git 使用總結

文章目錄 git merge 和 git rebasegit mergegit rebase總結 git merge 和 git rebase git merge git merge 最終效果說明: 假設有一個倉庫情況如下,現需要進行 merge: merge 操作流程: merge 的回退操作: git reba…

Java適配器模式 - 靈活應對不匹配的接口

Java適配器模式 - 靈活應對不匹配的接口 引言: 在軟件開發中,我們經常遇到不同系統、庫或框架之間的接口不兼容問題。為了解決這些問題,我們可以使用適配器模式。適配器模式是一種結構型設計模式,它允許不兼容的接口之間進行協作…

用Python采集動態網頁Requests就不那么好用了,試試Selenium

Requests + BeautifulSoup + 額外的庫: 對于一些簡單的動態內容,你能通過分析網絡請求來找到并直接獲取這些數據。 使用 requests 庫來發送 HTTP 請求,并使用 BeautifulSoup 來解析 HTML。 對于 AJAX 請求,你可能需要使用額外的庫(如 mitmproxy 或 BrowserMob Proxy)來…

武漢AAA企業信用等級認證

AAA企業信用等級認證 1. 什么是AAA企業信用等級認證 AAA企業信用等級認證是由國家知名的第三方機構對企業的信用狀況進行評估和認證的一種方式。它是根據企業在市場經濟中所展示出的信用水平、經營實力、企業形象等方面的表現來確定企業的信用等級,以此為企業提供…