免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 18260 | 回复: 3
打印 上一主题 下一主题

PHP中PostgreSQL数据库bytea字段插入和读取问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-09-10 22:03 |只看该作者 |倒序浏览
想用bytea类似存储图片,结果却失败了。在网上查了许多资料,但最后测试都失败。

数据库很简单:
  1. CREATE TABLE images
  2. (
  3.     id serial;
  4.     data bytea;
  5.     enc varchar;
  6. );
复制代码
这个是我前面在MySQL中测试BLOB的一个数据库,当然类型在MySQL中用的是MEDIUMBLOB。

最开始遇到的问题是直接插报错,加上
  1. $db->exec("SET client_encoding = 'Latin1';");
复制代码
后可以了,但读的地方得到的数据无法使用,用strlen()也会报错(PHP的strlen是可以处理binary
string的,前面我在测试MySQL时用过)。

后来看PHP手册中说插入之前需要用pg_escape_bytea()转换,读取之后再用pg_unescape_bytea()
转换回来,但测试还是不行。
在插入之间读取escape之后的长度,和读出来的数据库是完全不同的,并且读出来之后unesacpe
后长度和原来是一样的。用一个文本文件测试了一下,发现escape之后只替换了少数字符,略增长
一些;但读出来之后就完成不一样了,是形如:
  1. x7b23212f7573722f62696e2f656e762070797......
复制代码
的一串数据。似乎还需要做个什么转换,但查了半天也都只提到上述两个转换。

我怕是PDO和PostgreSQL的binary操作不兼容,特地用PHP中的pg_xxx测试了一下,结果更奇怪,
读取的地方unesacpe之后和原来长度是一样的,但直接从库中读到的data字段比它长度大1。

代码很简单:
  1. $sql = $db->prepare("INSERT INTO images(data, enc) VALUES(?, ?)");
  2. $data_escaped = pg_escape_bytea($data);
  3. $ret = $sql->execute(array($data_escaped, $enc));
复制代码
$data是前面通过POST传上来的文件数据,这部分没什么问题,前面使用MySQL时是测试过的。

查询的地方:
  1. $sql = $db->prepare("SELECT * FROM images WHERE id = ?");
  2. $ret = $sql->execute(array($image_id));
  3. $sql->bindColumn("id", $id);
  4. $sql->bindColumn("data", $data);
  5. $sql->bindColumn("enc", $enc);
  6. $sql->fetch(PDO::FETCH_BOUND);
  7. $data_escaped = pg_unescape_bytea($data);
复制代码
另外我有一个疑问,binary数据通常相对是比较大的数据,PostgreSQL如果对于binary数据一定要
escape一下不是运行效率和存储效率都比较低?在上述表中,enc是我用来测试base64编码的,在
测试时发现104642字节大小的图片,base64编码之后是139524,而pg_escape之后是316581,
从这个上说还不如用base64转换的效率。

同一个图片,插入到bytea之后,读出来的长度是209937。我怀疑应该是个低级错误
导致的,但从网上查来查去就是找不出原因在哪了




论坛徽章:
0
2 [报告]
发表于 2013-09-18 09:45 |只看该作者
自己踢一下,没人知道,还是这个问题太弱智了?

论坛徽章:
1
数据库技术版块每日发帖之星
日期:2015-06-20 22:20:00
3 [报告]
发表于 2013-09-29 11:02 |只看该作者
这个资料很少,上回做客户端回存数据遇到和你一样的问题,有人说为什么一样要把图片写进数据库呢,上传到服务器,再记录一笔路径就行了。
好在费了很大劲,弄好了,有时为了图片信息安全,还真需要像你这样做。

这样吧,把你写入的数据,x7b23212f7573722f62696e2f656e762070797......  就这一段,上传一张小图片,复制一个完整的出来。

我用我现成的客户端程序,看能不能读取还原成图片,先进行问题定位,确认你写入的数据没有问题,然后再说下一步,php读取bytea数据,并还原成图片等格式。

论坛徽章:
0
4 [报告]
发表于 2013-11-18 12:52 |只看该作者
本帖最后由 Cyberman.Wu 于 2013-11-18 12:55 编辑

回复 3# crykun


最近太忙,好久不来论坛了。你是指原始图片吗?可能要找个时间重新测试,原来测试用的代码和图片都不知道在哪了。

因为License问题,其实挺想换成PostgreSQL的(我们要在C/C++中使用数据库,但MySQL的C库是GPL License而不是LGPL),
但我们要涉及到存储大量的图片,如果存储需要编码,使用时再解码,可能性能会有所损失。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP