您的位置:首页 > 数据库

如何向postgreSQL中添加bytea类型的大对象数据

2014-02-07 13:33 288 查看
1)请教大家,如何向postgreSQL中添加bytea类型的大对象数据?

和mysql的一样不,需要bind吗,那对应mysql_stmt_init和mysql_stmt_prepare、mysql_stmt_bind_param、mysql_stmt_execute对API是哪些楼主
– guojinshihuaidan:


1个回复


回复1楼
– guojinshihuaidan:添加成功了,用PQprepare和PQexecPrepared

2)

如果想要在PostgreSQL中存储二进制数据,例如存储Word、Excel文档,图片文件等,可以使用bytea类型的列。bytea类型是PostgreSQL特有的存储二进制数据的字段类型,与SQL标准中的BLOB和BINARY LARGE OBJECT类型异曲同工。这在PostgreSQL文档的bytea类型介绍中有所说明。

接下来先说说如何向表中插入、更新bytea数据。

PostgreSQL允许在SQL命令中包含bytea类型的数据,以便能够使用INSERT向表中插入含有二进制数据的记录,使用UPDATE和调用与bytea类型相关的函数更新和操作bytea类型数据。二进制数据是一个字节序列,然而SQL命令是文本字符串,怎样在SQL中写入二进制数据呢?答案很简单,把每一个字节转换成对应的三位十进制数字的八进制数字符串表示,以双斜线做为前缀,即0x00表示为\\000、0x2C表示为\\02C、0xFF表示为\\377,并按照bytea类型的要求在字符串前端的单引号外注明E。举例如下:

INSERT INTO table1 (fileid,filename,content) VALUES (1,'filename.doc',E'\\000\\001\\002');

INSERT INTO table1 (fileid,filename,content) VALUES (2,'anotherfile.jpg',E'\\000\\377');

UPDATE table1 SET content = E'\\000\\000\\000' WHERE fileid
= 1;

UPDATE table1 SET content = content || E'\\377\\377\\377' WHERE fileid
= 2;

可以在INSERT INTO中包含整个文件的bytea类型字符串,也可以像上面第四行那样,分块追加。对于短小的二进制数据,在命令控制台中编辑SQL命令也未尝不可。但是如果要存储一个图片文件或者Word文档之类的大型二进制数据的时候,就需要借助数据访问借口,或者自己写一个字节转换程序,直接操作SQL语句。

插入bytea数据后可以使用SELECT语句获取它。如下所示:

SELECT content FROM table1;

在命令控制台中,我们会看到以输入时的字符串格式输出二进制数据,这是PostgreSQL做的转换。在Python中使用psycopg2模块,执行上述SELECT语句后能够获得原始的二进制字节字符串,可以直接写入二进制文件。

顺便说明一下。对于字节的转换,PostgreSQL的文档说的非常详细,按照零字节、单引号、斜线,以及字符的可打印性分别作了讨论。原因是需要逃逸单引号和斜线字符,另外可打印字符可以不作转换,直接出现。

3)


PostgreSQL-Bytea存BlobDAta出错

用PostgreSQL-Bytea存BlobDAta,如mdb/mp3/jpg/doc等檔案,試了好幾天,是可以存進去,可是轉出來時老是無法使用,經研究發現它的體積會自動長大,且會以3.31的比率增加。這轉出來檔當然是不能用了。而且我用BlobField.BolbSize去看資料庫中的存檔大小就是這個轉出的Size,這表示是在存入時出了問題。這要如何處理?

設定可以處理Bytea-Blob存取BinaryData的功能

1.編修postgresql.conf:程式集->PostgreSQL8.2->編修控制檔->edit postgresql.conf。

2.改Connections and Authentication-section,加 listen_addresses = '*'

3.改Version/platform Compatibility加兩行

escape_string_warning = off

standard_conforming_strings = off

別小看這三行,小弟這三行可是花了三四個星期,把手冊全印出來裝釘研讀多次,還去PG姥姥家及Google翻江倒海了好久,最後還是靠Multics前輩指點才過關的。

真是眾裏尋它千百度,衣帶漸寬終不悔,再回頭已百年身。烏乎哀哉

4)

1. 比如有一个实体定义例如:

/**

*@generated

*@display 数据

*/

@Column(name = "f_data")

private byte[] data;

/**

*@generated

*@display 数据

*/

@Column(name = "f_data2")

private Integer[] data2;

要保存到postgres过程中会出现data读取数据混乱,不是原来的数据,data2会出现无法反序列化问题

解决办法:修改postgres的postgresql.conf配置文件

bytea_output = 'escape' # hex,escape

意思是设置bytea_output的输出类型设置为转义类型输出,而postgres默认是hex类型输出,所以导致转换数据混乱问题

参考文档:

8.4. Binary Data Types

The bytea data type allows storage of binary strings; see Table 8-6.

...

18.10. Client Connection Defaults

18.10.1. Statement Behavior

bytea_output (enum)

Sets the output format for values of type bytea. Valid values are hex (the default) and escape (the traditional PostgreSQL format). See Section 8.4 for more information. The bytea type always accepts both formats on input,regardless of this setting.

以上配置需要重启postgres服务才生效!!!

5)

参考资料

PostgreSQL Document:

http://www.postgresql.org/docs/9.2/static/datatype-binary.html

PostgreSQL public API(LargeObject): http://jdbc.postgresql.org/documentation/publicapi/index.html

PostgreSQL JDBC Interface:

http://jdbc.postgresql.org/documentation/head/binary-data.html

二进制类型bytea的操作(在最大值内,有内存限制)

1
Create
table
byteatable(id
int
,obj
 bytea);
①直接插入逃逸序列

bytea 文本逃逸八进制

http://www.postgresql.org/docs/9.2/interactive/datatype-binary.html#DATATYPE-BINARY-TABLE
十进制数值
描述
输入逃逸形式
例子
输出形式
0
八进制的零
E'\\000'
SELECT E'\\000'::bytea;
\000
39
单引号
'''' 或 E'\\047'
SELECT E'\''::bytea;
'
92
反斜杠
E'\\\\' 或 E'\\134'
SELECT E'\\\\'::bytea;
\\
0 到 31 以及 127 到 255
"不可打印"字节
E'\\xxx'(八进制值)
SELECT E'\\001'::bytea;
\001
1
Insert
 into byteatablevalues(
1
,
''
''
);
//插入一个单引号-‘
② 通过base64的encode编码字符串

encode在线编码器 http://www.opinionatedgeek.com/dotnet/tools/base64encode/

你好 编码为 5L2g5aW9

1
Insert
into
byteatable
values
(1,decode(‘5L2g5aW9’,’base64’));//5L2g5aW9是【你好】编码后的代码
③ 通过pg_read_binary_file()函数

1
Insert
 into byteatablevalues(
256
,pg_read_binary_file(
'lob/imagejpg'
));
//插入一张图片-
 ../data/lob/image.jpg
注意:函数pg_read_binary_file()中的路径必须是相对路径,默认路径是data目录下,并且必须在data目录下或者data目录的子目录下。
Name
Return Type
Description
pg_read_file(filename text [,offset bigint,length bigint])
text
Return the contents of a text file
pg_read_binary_file(filename text [,offset bigint,length bigint])
bytea
Return the contents of a file
大对象类型oid的操作(在最大值内,没有内存限制)

1
Create
table
oidtable(id
int
,
 obj oid);
2
Insert
into
oidtable(id,obj)
values
(1,lo_import(‘d:/1.jpg’));
3
select
lo_export(obj,
 ‘e:/11.jpg’)
from
oidtable
where
id=1;  
 //将以上插入的1.jp从表中取出来存成e盘的11.jpg。
大对象数据在pg_largeobject表中是以其创建时的OID标识的。每个大对象都分解成足够小的小段或者"页面"以便以行的形式存储在pg_largeobject 里。每页的数据定义为LOBLKSIZE(目前是BLCKSZ/4 或者通常是 2K 字)。





Bytea与oid的比较

资料:http://www.microolap.com/products/connectivity/postgresdac/help/TipsAndTricks/ByteaVsOid.htm

BYTEA vs OID (Large Objects)

Comparative table
Characteristic
BYTEA
OID
Max. allowed space
1 GB
2 GB
Data access
As a whole
Stream-style
Storage
In defined table
In pg_largeobject system table
Data manipulation
Using SQL and escaping sequnces
Only within transaction block by special functions
Loading
Preload
On demand
6)


ZippyZ asked this question · 0
karma · Jun
27 '12 at 03:38 PM

Is there a way to use the easy binary installer to install the bundled tomcat / jira install but use mysql or postegres instead of hsqldb?

373 views


One Answer:

Upvote0Downvote






Rodrigo Girardi Adami [Atlassian] · 2,885
karma · Aug
05 '13 at 01:26 PM

Hi Zippy,

After you install confluence with the binary installer,you can hit confluence in the browser,put the license over there,and choose between evaluation or production. As you choose production,you can select the database which
you would like to run confluence with.

More information can be found here and here.

I hope this helps!

Rodrigo
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: