繁体   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