设为首页 收藏本站
查看: 801|回复: 0

[经验分享] PostgreSQL中copy命令以二进制形式传输数据的二进制格式

[复制链接]

尚未签到

发表于 2016-11-21 07:00:31 | 显示全部楼层 |阅读模式
有用户想知道pg中copy命令使用二进制文件时二进制文件的格式,这个格式pg的使用文档里其实已经有了,这儿结合例子说明的更具体一些,现解析如下:
先看一下copy命令的语法,然后做个例子,根据例子解析一下二进制文件的格式。

COPY命令用于在外部文件(客户端)和表之间传送数据,语法如下:
COPY tablename [ ( column [, ...] ) ]
    FROM { 'filename' | STDIN }
    [ [ WITH ]
          [ BINARY ]
          [ OIDS ]
          [ DELIMITER [ AS ] 'delimiter' ]
          [ NULL [ AS ] 'null string' ]
          [ CSV [ HEADER ]
                [ QUOTE [ AS ] 'quote' ]
                [ ESCAPE [ AS ] 'escape' ]
                [ FORCE NOT NULL column [, ...] ]
 
COPY { tablename [ ( column [, ...] ) ] | ( query ) }
    TO { 'filename' | STDOUT }
    [ [ WITH ]
          [ BINARY ]
          [ OIDS ]
          [ DELIMITER [ AS ] 'delimiter' ]
          [ NULL [ AS ] 'null string' ]
          [ CSV [ HEADER ]
                [ QUOTE [ AS ] 'quote' ]
                [ ESCAPE [ AS ] 'escape' ]
                [ FORCE QUOTE column [, ...] ]
 
下面是pg7.3版本以前的语法,后续的版本仍然支持
COPY [ BINARY ] table_name [ WITH OIDS ]
    FROM { 'filename' | STDIN }
    [ [USING] DELIMITERS 'delimiter' ]
    [ WITH NULL AS 'null string' ]
 
COPY [ BINARY ] table_name [ WITH OIDS ]
    TO { 'filename' | STDOUT }
    [ [USING] DELIMITERS 'delimiter' ]
    [ WITH NULL AS 'null string' ]
   

使用copy命令的例子:
1
命令copy to 涉及的表copybinarytest的定义
beigang=# \d+ copybinarytest
                        资料表 "enterprisedb.copybinarytest"
  栏位   |         型别          | 修饰词 |   存储   | Stats target | 描述
---------+-----------------------+--------+----------+--------------+------
 id      | numeric(10,0)         |        | main     |              |
 content | character varying(30) |        | extended |              |
有 OIDs: 否
 
2
表copybinarytest的记录
beigang=# select * from copybinarytest;
 id |   content
----+-------------
  1 | beigang
  2 | copy binary
  3 | abc
(3 行记录)
 
3
创建命令copy from 涉及的表copybinarytest2
beigang=# create table copybinarytest2 as select * from copybinarytest where 1=8;
SELECT 0
 
4
命令copy from 涉及的表copybinarytest2的定义
beigang=# \d+ copybinarytest2;
                        资料表 "enterprisedb.copybinarytest2"
  栏位   |         型别          | 修饰词 |   存储   | Stats target | 描述
---------+-----------------------+--------+----------+--------------+------
 id      | numeric(10,0)         |        | main     |              |
 content | character varying(30) |        | extended |              |
有 OIDs: 否
 
5
用copy to命令以二进制形式把copybinarytest表的内容拷贝到binary文件中
beigang=# copy binary copybinarytest to 'binary';
COPY 3
beigang=#
 
6
Binary文件的内容如下图:
 

DSC0000.png
 
 
Copy命令二进制文件的格式如下:
二进制格式
    二进制格式的文件由一个文件头、数据(零个或多个元组)和文件尾构成。文件头和数据按网络字节顺序表示。
 
文件头
    文件头由15个字节的固定区域和一个变长的扩展区域组成。固定区域包括:
       签名
              11个字节的序列PGCOPY\nFF\r\n\0。
       标志位
              32位的整数。位的编号从0(最低位)到31(最高位)。当前只有一个标志位被使用,它是第16位,如果它的值是1,表示含有OID,如果它的值是0,表示不含OID。其它的标志位永远是0。
       扩展区域
              首先是一个32位的整数,表示扩展区域的长度,不包括这个32位的整数自身。当前,它的值是0。第一个元组紧跟在它的后面。
 
元组
    每个元组以一个16位的整数开始,表示元组中域的个数。然后是元组中的每个域。每个域由一个32位的整数开始,它表示域的长度,后面跟着域的数据,-1表示域的值为空值。如果文件中包含OID,则它的值跟在元组的第一个16位整数的后面,而且就算组的域的个数时,OID不被计算在内,它也由一个32位的整数开始,表示OID的长度,当前,OID的长度固定是4字节,以后可能扩展到8字节。
文件尾
    文件尾包含一个16位的整数,它的值是-1。
7
确认copybinarytest2表中没有记录
beigang=# select * from copybinarytest2;
 id | content
----+---------
(0 行记录)
 
8
用copy from命令把binary文件中的数据拷贝到表从opybinarytest中
beigang=# copy binary copybinarytest2 from 'binary';
COPY 3
 
9
确认表copybinarytest2的内容和copybinarytest相同。
beigang=# select * from copybinarytest2;
 id |   content
----+-------------
  1 | beigang
  2 | copy binary
  3 | abc
(3 行记录)
 

以上面的例子为例解析Copy命令二进制文件格式

DSC0001.png  
上图是copy命令导出的二进制数据文件,图中用红色竖线做分隔符,把二进制文件分成不同的段。蓝色数字表示各段的编号,
其中文件头包括第1段到第3段。
       第1段是11个字节的序列PGCOPY\nFF\r\n\0;第2段是标志位,占4个字节;第3段是扩展区域,至少4个字节,根据情况可能更多。
元祖包括第4段到第18段
              第4、5、6、7、8段是第一条记录:第4段表示该元祖的列数,占2个字节;第5段表示第一列的长度,占4个字节;第6段是第一列的值;第7段是第二列的长度,占4个字节;第8段是第二列的值。
              第9、10、11、12、13段是第二条记录,同上。
              第14、15、16、17、18段是第三条记录,同上。
文件尾是第19段,占2个字节。
 
参考:
http://www.postgresql.org/docs/9.2/static/sql-copy.html
src/backend/commands/copy.c
 

  -----------------

  转载请著明出处:
blog.csdn.net/beiigang
beigang.iyunv.com

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-303088-1-1.html 上篇帖子: PostgreSQL启动过程中的那些事四:初始化全局时区global_timezone 下篇帖子: 安装postgreSQL出现configure:error:readline library not found解决方法及pg安装全过程
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表