簡體   English   中英

如何在沒有base64編碼的情況下將blob數據從ruby提交到MySQL

[英]How to submit blob data into MySQL from ruby without base64 encoding

我搜索了如何最好地將二進制數據提交到 BLOB 類型的 MySQL 字段中,但沒有進行增加數據大小的 base64 編碼,但沒有取得多大成功。

到目前為止,我的 Ruby 代碼如下所示:

require 'zlib'
require 'base64'
require 'mysql'

#Initialization of connection function
  db = Mysql.init
  db.options(Mysql::OPT_COMPRESS, true)
  db.options(Mysql::SET_CHARSET_NAME, 'utf8')
  dbh = db.real_connect('hostname','username','password','database') #replace with appropriate connection details

#Saving the data function
  values=someVeryBigHash
  values=JSON.dump(values)
  values=Zlib::Deflate.deflate(values, Zlib::BEST_COMPRESSION)
  values=Base64.encode64(values)
  dbh.query("update `SomeTable` set Data='#{values}' where id=1")
  dbh.close if dbh

#Retrieving the data function
  res=dbh.query("select * from `SomeTable` where id=1")
  data=res['Data']
  data=Base64.decode64(data)
  data=Zlib::inflate(data)
  data=JSON.parse(data)

問題是使用 Base64 編碼/解碼效率不高,我正在尋找更簡潔的東西。

我還嘗試了使用 Marhsal 的替代方法(它不允許我在沒有 base64 編碼的情況下發送數據,但更緊湊)

 #In the saving function use Marshal.dump() instead of JSON.dump()
 values=Marshal.dump(values)

 #In Retrieve function use Marshal.load() (or Marshal.restore()) instead of JSON.parse(data)
 data=Marshal.load(data)

但是,我遇到了一些錯誤(也許有人發現我做錯了什么,或者有一些想法為什么會發生這種情況):

incompatible marshal file format (can't be read) version 4.8 required; 34.92 given

我嘗試了使用/不使用 Base64 編碼或解碼或使用/不使用 ZLib 壓縮的不同風格。 但我似乎一直收到錯誤。

在沒有 base64 編碼的情況下,如何使用 Ruby 和 mysql gem 發送二進制數據。 或者僅僅是要求使用 base64 編碼來發送數據?

問題是使用 Base64 編碼/解碼效率不高,我正在尋找更簡潔的東西。

您正在使用 JSON 將大哈希轉換為字符串,然后對二進制數據使用 ZLib 壓縮,然后對生成的二進制數據進行 Base64 編碼,您擔心效率......我假設您指的是空間效率而不是時間效率。

我想我最想知道為什么你首先使用 Base64 編碼——BLOB 是一種二進制數據格式,如果你將一個字節數組傳遞給 ZLib,它應該無論如何正確地膨脹它。

您是否嘗試過將二進制數據直接寫入數據庫? 你遇到了什么問題。

編輯:

update SomeTable set Data='xڍ ]o 0 K$ k; H Z *XATb U,where id=1' 導致錯誤......顯然這與二進制有關數據的性質。 這抓住了我的問題的本質。 希望你對這個問題有所了解。

您不能像這里那樣將二進制字符串作為查詢值傳遞 - 我認為您需要使用帶有綁定變量的查詢。

我不確定您使用的 mysql gem 是否支持查詢綁定參數,但您使用的查詢格式類似於:

@db.execute('update SomeTable set Data=? where id = 1', <binary data value>) 

這將允許 mysql 正確轉義或封裝要插入到數據庫表中的二進制數據。

總結 mcfinningan 的答案。 傳輸二進制數據是通過綁定參數來完成的。 在 ruby​​ 中,這可以使用 'mysql' gem 完成,這可以使用准備好的 statments 完成(參見MySQL Ruby 教程

代碼現在看起來像:

require 'zlib'
require 'mysql'

#Initialization of connection function
  db = Mysql.init
  db.options(Mysql::OPT_COMPRESS, true)
  db.options(Mysql::SET_CHARSET_NAME, 'utf8')
  dbh = db.real_connect('hostname','username','password','database') #replace with appropriate connection details

#Saving the data function (can skip Zlib compression if needed)
  values=someVeryBigHash
  values=Marshal.dump(values)
  values=Zlib::Deflate.deflate(values, Zlib::BEST_COMPRESSION)

  #Here is how to load the binary data into MySQL (assumes your schema has some tale with a Column Data of type BLOB
  dbh.prepare("update `SomeTable` set Data=? where id=1")
  dbh.execute(data)
  #End of Data loading

  dbh.close if dbh


#Retrieving the data function (can skip Zlib decompression if data is not compressed)
  res=dbh.query("select * from `SomeTable` where id=1")
  data=res['Data']
  data=Zlib::inflate(data)
  data=Marshal.restore(data)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM