Atl*_*tli 12 php mysql binary insert
我听说有传言说在将二进制数据(文件等)插入MySQL时,你应该使用该bin2hex()函数并将其作为HEX编码值发送,而不是仅仅使用mysql_real_escape_string二进制字符串并使用它.
// That you should do
$hex = bin2hex($raw_bin);
$sql = "INSERT INTO `table`(`file`) VALUES (X'{$hex}')";
// Rather than
$bin = mysql_real_escape_string($raw_bin);
$sql = "INSERT INTO `table`(`file`) VALUES ('{$bin}')";
Run Code Online (Sandbox Code Playgroud)
据说这是出于性能原因.与MySQL如何处理大字符串以及如何处理HEX编码值有关
但是,我很难确认这一点.我所有的测试都表明确切的对话; 该bin2hex方法慢了约85%,使用了大约24%的内存.
(我在PHP 5.3,MySQL 5.1,Win7 x64上测试它 - 使用一个简单的插入循环.)
例如,此图显示了测试代码运行时mysqld进程的私有内存使用情况:
mysqld进程使用的私有字节http://atli.advefir.com/images/priv_mem_cropped.gif
有没有人有解释这个的解释或资源?
谢谢.
这听起来像是我的都市传奇.
bin2hex()将输入中的每个字节映射到输出中的两个字节('a'- > '61'),因此您应该注意到执行查询的脚本会显着增加内存 - 它应该至少使用与二进制数据的字节长度相同的内存量.插入.
此外,这意味着运行bin2hex()在一个长字符串采用多比跑步的时间延长mysql_real_escape string(),这-在解释MySQL的文档 -只是逃脱6个字符:NULL,\r,\n,\,,和"控制-Z".
那是PHP部分,现在是MySQL:服务器需要执行相反的操作才能正确存储数据.反转任一函数几乎与原始操作一样长 - mysql_real_escape_string()需要\\用非转义的(\)替换转义值()的反向函数,而反向bin2hex()需要用新字节替换每个字节元组.
由于调用mysql_real_escape_string()二进制数据是安全的(根据MySQL和PHP的文档,或者甚至只考虑操作不会执行上面列出的任何其他转换),执行如此昂贵的操作绝对没有意义.
我自己一直在测试,我得出了非常一致的结果.(即使我的测试有点粗糙.)
我测试了三台电脑
到目前为止,所有三个平台上的测试都表明了相同的情况:
bin2hex进入a X'...')平均使用更多内存. - MyISAM和InnoDB似乎都是如此.mysql_real_escape_string测试基本上只是一个简单的循环,它对原始数据进行转义或十六进制编码(在脚本顶部检索一次2.4 MiB图像),构造查询字符串,并通过mysql_query或mysqli::query函数执行. - 我测试了两个扩展.似乎没有任何区别.
我将Ubuntu 10.04(#3)的结果放在电子表格中.Ubuntu 9.10(#2)机器的结果几乎相同,所以我没有打扰它们:(
最后借口正确测试Google Docs的东西!xD)
这些图表显示了mysqldWin7(#1)计算机上进程的专用内存使用情况.