[英]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.