如何向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,如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的操作(在最大值内,有内存限制)
①直接插入逃逸序列
bytea 文本逃逸八进制
http://www.postgresql.org/docs/9.2/interactive/datatype-binary.html#DATATYPE-BINARY-TABLE
② 通过base64的encode编码字符串
encode在线编码器 http://www.opinionatedgeek.com/dotnet/tools/base64encode/
你好 编码为 5L2g5aW9
③ 通过pg_read_binary_file()函数
注意:函数pg_read_binary_file()中的路径必须是相对路径,默认路径是data目录下,并且必须在data目录下或者data目录的子目录下。
大对象类型oid的操作(在最大值内,没有内存限制)
大对象数据在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
6)
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
Upvote0Downvote
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
和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 , '' '' ); //插入一个单引号-‘ |
encode在线编码器 http://www.opinionatedgeek.com/dotnet/tools/base64encode/
你好 编码为 5L2g5aW9
1 | Insert into byteatable values (1,decode(‘5L2g5aW9’,’base64’));//5L2g5aW9是【你好】编码后的代码 |
1 | Insert into byteatablevalues( 256 ,pg_read_binary_file( 'lob/imagejpg' )); //插入一张图片- ../data/lob/image.jpg |
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 |
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。 |
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 |
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
相关文章推荐
- 如何向postgreSQL中添加b 4000 ytea类型的大对象数据
- 如何在已经绑定数据的dataGridView对象中动态添加记录?
- 【OC加强】枚举介绍、数组的排序、对象的排序、如何利用block排序以及一些数据类型知识
- hibernate如何对Blob类型字段进行数据添加
- Struts2中如何接收前台传递的数据之基本数据类型,对象,和对象数组
- 如何通过for循环添加对象到集合(防止数据覆盖)
- 关于java的一些小问题,list中添加对象,java基本数据类型对象
- 一个对象类型的数据如何转化为String类型
- 如何在ArrayList<Integer>中添加String类型数据
- spring3mvc如何把checkbox的值绑定到model对象的int数据类型
- PostgreSQL json jsonb 支持的value数据类型,如何构造一个jsonb
- 如何将数组对象合并,也就是给原来的数据添加值
- 如何在已经绑定数据的dataGridView对象中动态添加记录?
- JS 如何创建对象、数据类型
- 数据类型与NSMutableArray添加对象(insertObject)引起的问题
- 把对象生成为Parcel类型,以及如何利用Parcel来传递Enum类型数据
- postgresql图片等二进制数据的存储(copy命令,bytea类型)
- 基本数据类型对象包装类有什么作用?如何使用?
- 变量-数据类型-对象-如何编写python脚本
- spring3mvc如何把checkbox的值绑定到model对象的int数据类型