# 建立一个复合类型person # 命令格式:create type xxx AS (); testdb=# create type person AS ( testdb(# name text, testdb(# age int4, testdb(# sex boolean testdb(# ); CREATE TYPE testdb=# \d person; 合成类型 "public.person" 栏位 | 类型 | Collation | Nullable | Default ------+---------+-----------+----------+--------- name | text | | | age | integer | | | sex | boolean | | | testdb=# \dt person; 没有找到任何名称为 "person" 的关联。 testdb=# \d person; 合成类型 "public.person" 栏位 | 类型 | Collation | Nullable | Default ------+---------+-----------+----------+--------- name | text | | | age | integer | | | sex | boolean | | | # 建立一个带复合类型的表author testdb=# create table author ( testdb(# id int4, testdb(# people person, testdb(# book text testdb(# ); CREATE TABLE testdb=# \d author; 数据表 "public.author" 栏位 | 类型 | Collation | Nullable | Default --------+---------+-----------+----------+--------- id | integer | | | people | person | | | book | text | | | # 插入数据 testdb=# insert into author values(1, ' ("qkl", 29, TRUE)', '张三的自传'); INSERT 0 1 # 缺省不填写就是NULL,逗号间不要有空格 testdb=# insert into author values(2, '("zgq", , TRUE)', '张三的自传2'); ERROR: invalid input syntax for integer: " " 第1行insert into author values(2, '("zgq", , TRUE)', '张三的自传2... ^ testdb=# insert into author values(2, '("zgq",,TRUE)', '张三的自传2'); INSERT 0 1 testdb=# insert into author values(2, '("zgq",, TRUE)', '张三的自传2'); INSERT 0 1 testdb=# insert into author values(3, '("",, TRUE)', '张三的自传3'); INSERT 0 1 # ROW行插入,注意ROW后面的字符请用单引号,不能带双引号 testdb=# insert into author values(4, ROW("",, TRUE), '张三的自传5'); ERROR: zero-length delimited identifier at or near """" 第1行insert into author values(4, ROW("",, TRUE), '张三的自传5'); ^ testdb=# insert into author values(4, ROW('PCB',, TRUE), '张三的自传5'); ERROR: syntax error at or near "," 第1行insert into author values(4, ROW('PCB',, TRUE), '张三的自传5... ^ # 省略ROW testdb=# insert into author values(4, ('hgr',30, TRUE), '张三的自传6'); INSERT 0 1 testdb=# select (people).name from author; name ------ qkl zgq zgq hgr (5 行记录) # 更新复合类型数据,复合类型名不带括号 testdb=# update author set people.name='qkl2' where id=1; UPDATE 1 testdb=# select people from author; people ------------- (zgq,,t) (zgq,,t) ("",,t) (hgr,30,t) (qkl2,29,t) (5 行记录) testdb=# update author set people.age = people.age +1 where id=1; ERROR: missing FROM-clause entry for table "people" 第1行update author set people.age = people.age +1 where id=1; ^ # 若是更新的字段右边也是复合类型必须携带括号 testdb=# update author set people.age = (people).age +1 where id=1; UPDATE 1 testdb=# select people from author; people ------------- (zgq,,t) (zgq,,t) ("",,t) (hgr,30,t) (qkl2,30,t) (5 行记录) # 单独插入复合类型的数据 testdb=# insert into author (id, people.name, people.age) values(7, 'ldh', 33); INSERT 0 1 testdb=# select * from author; id | people | book ----+-------------+------------- 2 | (zgq,,t) | 张三的自传2 2 | (zgq,,t) | 张三的自传2 3 | ("",,t) | 张三的自传3 4 | (hgr,30,t) | 张三的自传6 1 | (qkl2,30,t) | 张三的自传 7 | (ldh,33,) | (6 行记录)
xm丨类型能够用于存储XML数据。使用字符串类型(如text)也能够存储XML数据,但text类型不能保证其中存储的是合法XML数据,一般须要由应用程序来负责保证输人数据的正确性,这将增长应用程序开发的难度。而使用xml类型就不存在此问题。数据库会对输人的数据进行检查,让一些不符合XML标准的数据不能存放到数据库中,同时还提供了函数对其类型进行安全性检査。
注意,要使用xml数据类型,在编译PostgreSQL源码时必须使用如下参数:
configure --with-libxmlexpress
xml存储的XML数据杳两种:json
documents
。content
片断。content
片断能够有多个级元素或character
节点.但documents
只能有一个顶级元素。可使用xmlvalue is DOCUMENT
来判断一个特定的XML值是一个documents
还足content
片断。
PostgreSQL的xmlopiions参数用来指定输人的数据是documents
仍是content
片断,默认状况下此值为content
片断。因此输人的xml能够有多个顶级元素,但若是把此参数改为document
,将不能输人有多个顶级元素的内容。segmentfault
PostgreSQL数据库在客户端与服务器之间传递数据时,会自动进行字符集的转换。若是客户端的字符集与服务端不同,PostgreSQL会自动进行字符集转换。但也正是由于有这个特性,在传递XML数据时须要格外注意。咱们知道,对于XML文件来讲,能够经过相似“encoding="XXX"”的方式指定本身文件的字符集,但当这些数据在PostgreSQL之间传递时, PostgreSQL会把其原始内容的宇符集变成数据库服务端的字符集,而这就会致使问题,由于这意味着XML数据中的字符集编码声明在客户端和服务器之间传递时,可能变得无效。为了应对该问题,提交输人到xml类型的字符串中的编码声明将会被忽略掉.同时内容的字符集会被认为是当前数据库服务器的字符集。数组
正确处理XML字符集的方式是,先将XML数据的字符串在当前客户端中编码成当前客户端的字符集,而后再发送到服务端,这样就会被转换成服务端的字符集存储。当査询xml 类型的值时,此数据又会被转换成客户端的字符集,因此客户端收到的XML数据的字符集就是客户端的字符集。
因此一般来讲,若是XML数据的字符集编码、客户端字符集编码,以及服务器字符集编码彻底同样,那么用PostgreSQL处理XML数据将会大大减小字符集问题,而且处理的效率也会很高。一般XML数据都是用UTF-8编码格式处理的,所以把PostgreSQL数据库服务器端编码也设置成UTF-8将是一种较好的选择。安全
postgres=# select xml'<code>hello postgres</code>'; xml ----------------------------- <code>hello postgres</code> (1 行记录) postgres=# show xmloption; xmloption ----------- content (1 行记录) postgres=# set xmloption TO document; SET postgres=# show xmloption; xmloption ----------- document (1 行记录) # document类型,插入多顶级元素,出错 postgres=# select xml'<code>hello postgres</code><other>hello world</other>'; ERROR: invalid XML document 第1行select xml'<code>hello postgres</code><other>hello world</ot... ^ 描述: line 1: Extra content at the end of the document <code>hello postgres</code><other>hello world</other> ^ postgres=# set xmloption TO content; SET postgres=# select xml'<code>hello postgres</code><other>hello world</other>'; xml ------------------------------------------------------- <code>hello postgres</code><other>hello world</other> (1 行记录) # xmlparse函数 postgres=# select xmlparse(document'<?xml version="1.0"?><person><name>qkl</name></person>'); xmlparse ----------------------------------- <person><name>qkl</name></person> (1 行记录) postgres=# select xmlparse(content'<?xml version="1.0"?><person><name>qkl</name></person>'); xmlparse ----------------------------------- <person><name>qkl</name></person> (1 行记录)
JSON数据类型是从P〇StgreSQL9.3开始提供的一种类型,9.3版中只有一种类型:JSON
在PosIgreSQL 9.4中乂提供了一种更高效的类型JSONB这两种类型在使用上几乎彻底一致,主要的区別是,JSON类型是把输人的数据原封不动地存放到数据库中(固然在存放前会作JSON的语法检查),使用的时候须要®:新解析数据,而JSONB类型是在存放时就把JSON解折成二进制格式了,使用的时候就不须要再次解析,因此JSONB在使用时性能会更高。另外,JSONB支持在其上逑索引,iftHSON则不能,这是JSONB类型的很大一个优势。
由于JSON类型是把输人的整个字符串原封不改动地保存到数据库中的,所以JSON串中key之间多余的空格也会保留。并且,若是JSON串中有重复的key,这些重复的key也会保留(默认处理时以最后一个为准),同时也会保留输人时JSON串中各个key的顺序。而JSONB类塑则偏偏相反,+会保留多余的空格,不会保留key的顺序,也不会保留重复的key。
在PostgreSQL中只容许毎个数据库用一种服务器编码,若是数据库的编码不是UTF-8,PostgreSQL中的JSON类塑是没法严格符合JSON规范中对字符集的要求的。若是输人中包含不能在服务器编码中表示的字符数据,将没法导人到数据库中。可是,能在服务器编码中表示的
非UTF-8字符则是被容许的。可使用uXXXX形式的转义,从而忽视数据库的字符集编码。
当把一个JSON字符串转换成JSONB类塑吋,JSON字符串内的数据类型实际上被转换成rPostgreSQL数据库中的类塑,二者的映射关系见表5-30。耑要注意的是,若是是在JS0NB中,在PostgrcSQL 不能输人超出numeric数据类型范闹的值。服务器
基础操做架构
testdb=# select '9'::json, '"osdba"'::json, 'true'::json, 'null'::json; json | json | json | json ------+---------+------+------ 9 | "osdba" | true | null (1 行记录) testdb=# select '[9, true, "qkl", null]'::json, '[9, true, "qkl", null]'::jsonb; json | jsonb ------------------------+------------------------ [9, true, "qkl", null] | [9, true, "qkl", null] (1 行记录) testdb=# select json'{"name":"qkl", "age":18, "sex":true, "money":888.88}'; json ------------------------------------------------------ {"name":"qkl", "age":18, "sex":true, "money":888.88} (1 行记录) # json 存取的是浮点型,存在精度问题 testdb=# select json'{"p":1.684544545454e-27}'; json -------------------------- {"p":1.684544545454e-27} (1 行记录) # jsonb存取的是numeric testdb=# select jsonb'{"p":1.684544545454e-27}'; jsonb -------------------------------------------------- {"p": 0.000000000000000000000000001684544545454} (1 行记录)
更多和操做符app
testdb=# select json'[1,2,3]'->0; ?column? ---------- 1 (1 行记录) testdb=# select json'[1,2,3]'->3; ?column? ---------- (1 行记录) testdb=# select json'[1,2,3]'->2; ?column? ---------- 3 (1 行记录) testdb=# select json'[1,2,3]'->>2; ?column? ---------- 3 (1 行记录) testdb=# select json'[1,2,3]'->>'2'; ?column? ---------- (1 行记录) testdb=# select json'{"a":1,"b":22}'->>'a'; ?column? ---------- 1 (1 行记录) testdb=# select json'{"a":{"a1":{"a11":111}},"b":22}'#>'{a,a1}' testdb-# ; ?column? ------------- {"a11":111} (1 行记录) testdb=# select json'{"a":{"a1":{"a11":111}},"b":22}'#>'{a,a1,a11}' testdb-# ; ?column? ---------- 111 (1 行记录) testdb=# select json'{"a":{"a1":{"a11":111}},"b":22}'#>>'{a,a1,a11}'; ?column? ---------- 111 (1 行记录) testdb=# select json'{"a":{"a1":{"a11":111}},"b":22}'#>>'{a,a1}'; ?column? ------------- {"a11":111} (1 行记录)
testdb=# select '(0,6)'::int4range; int4range ----------- [1,6) (1 行记录) testdb=# select '[0,6)'::int4range; int4range ----------- [0,6) (1 行记录) testdb=# select '[0,6]'::int4range; int4range ----------- [0,7) (1 行记录) testdb=# select 'empty'::int4range; int4range ----------- empty (1 行记录) # 上面咱们看出,int4range总数会转换成`[)`格式 testdb=# select '[0,6]'::numrange; numrange ---------- [0,6] (1 行记录) testdb=# select '[0,6)'::numrange; numrange ---------- [0,6) (1 行记录) testdb=# select '(0,6)'::numrange; numrange ---------- (0,6) (1 行记录) testdb=# select '(0,)'::numrange; numrange ---------- (0,) (1 行记录) testdb=# select '[1,)'::numrange; numrange ---------- [1,) (1 行记录)
PostgreSQL支持表的字段使用定长或可变长度的一维或多维数组,数组的类型能够是任何数据库内建的类型、用户自定义的类型、枚举类型,以及组合类型。但目前还不支持domain类型。dom
create table test6 (id int, col1 int[], col2 int[10], col3 text[][]); create table test7 (id int, col1 int[10], col2 int[], col3 text[]);
在第一个语句中第二列的声明col2 int[10]
与第二个语句中第二列的声明col2 int[]
其意思相同;而在第一个语句中第三列的声明col3 text[][]
与第二个语句中第三列的声明col3 text[]
的意思也是相同的
咱们来查看下表结构
testdb=# create table test6 (id int, col1 int[], col2 int[10], col3 text[][]); CREATE TABLE testdb=# create table test7 (id int, col1 int[10], col2 int[], col3 text[]); CREATE TABLE testdb=# \d 关联列表 架构模式 | 名称 | 类型 | 拥有者 ----------+--------------+--------+---------- public | author | 数据表 | postgres public | test1 | 数据表 | postgres public | test2 | 数据表 | postgres public | test2_id_seq | 序列数 | postgres public | test3 | 数据表 | postgres public | test3_id_seq | 序列数 | postgres public | test6 | 数据表 | postgres public | test7 | 数据表 | postgres (8 行记录) testdb=# \d test6; 数据表 "public.test6" 栏位 | 类型 | Collation | Nullable | Default ------+-----------+-----------+----------+--------- id | integer | | | col1 | integer[] | | | col2 | integer[] | | | col3 | text[] | | | testdb=# \d test7; 数据表 "public.test7" 栏位 | 类型 | Collation | Nullable | Default ------+-----------+-----------+----------+--------- id | integer | | | col1 | integer[] | | | col2 | integer[] | | | col3 | text[] | | |
testdb=# create table test66(id int, col1 int[]); CREATE TABLE testdb=# insert into test66 values(1, '{1,2,3}'); INSERT 0 1 testdb=# insert into test66 values(2, '{4,5,6}'); INSERT 0 1 testdb=# select * from test66; id | col1 ----+--------- 1 | {1,2,3} 2 | {4,5,6} (2 行记录) testdb=# create table test77(id int, col1 text[]); CREATE TABLE testdb=# insert into test77 values(1, '{how, howe, howl}'); INSERT 0 1 testdb=# select * from test77; id | col1 ----+----------------- 1 | {how,howe,howl} (1 行记录) testdb=# insert into test77 values(1, '{"how", "howe", "howl"}'); INSERT 0 1 testdb=# select * from test77; id | col1 ----+----------------- 1 | {how,howe,howl} 1 | {how,howe,howl} (2 行记录) # 注意上面不一样的类型,可能分隔符会不同,下面可查询不一样类型的分隔符 testdb=# select typname,typdelim from pg_type where typname in ('int4', 'int8', 'bool', 'char', 'box'); typname | typdelim ---------+---------- bool | , char | , int8 | , int4 | , box | ; (5 行记录) testdb=# create table test778(id int ,col1 box[]); CREATE TABLE testdb=# insert into test778 values(1, '{((1,1), (2,2)); ((3,3),(4,4))}'); INSERT 0 1 testdb=# select * from test778; id | col1 ----+--------------------------- 1 | {(2,2),(1,1);(4,4),(3,3)} (1 行记录) # 上面输人的字符串内容是没有空格的,在有空格时,乂该如何输人呢?见下面的例子: testdb=# insert into test77 values(3,'{how many,how mach,how old}'); INSERT 0 1 能够看到有空格,也能够直接输人。 那么字符串中有逗号时怎么办呢?这时可使用双引号,以下: testdb=# insert into test77 values(4,'{"who, what", "CO.,LTD."}'); INSERT 0 1 若是字符串中有单引号怎么办呢?这时可使用两个链接的单引号表示一个单引号: testdb=# insert into test77 values(3,'{"who''s bread", "It''s ok"}'); INSERT 0 1 若是输人的字符串中有括号"{"和"}"怎么办呢?只需把它们放到双引号中便可: testdb=# insert into test77 values (5, '{"{os, dba}", "{dba, os}"}'); INSERT 0 1 若是输人的字符串中有双引号怎么办呢?这时须要在双引号前加反斜扛,以下所示: testdb=# insert into test77 values(6,'{os\"dba}'); testdb=# select * from test77; id | col1 ----+----------------------------------- 1 | {how,howe,howl} 1 | {how,howe,howl} 3 | {"how many","how mach","how old"} 4 | {"who, what","CO.,LTD."} 3 | {"who's bread","It's ok"} 5 | {"{os, dba}","{dba, os}"} 6 | {"os\"dba"} (7 行记录) # ARRAY关键词的使用,需带单引号 testdb=# insert into test77 values(9, array['os', 'dba']); INSERT 0 1 testdb=# insert into test77 values(9, array['os"win', 'dba']); INSERT 0 1 testdb=# insert into test77 values(9, array['os''win', 'dba']); INSERT 0 1 testdb=# select * from test77; id | col1 ----+----------------------------------- 1 | {how,howe,howl} 1 | {how,howe,howl} 3 | {"how many","how mach","how old"} 4 | {"who, what","CO.,LTD."} 3 | {"who's bread","It's ok"} 5 | {"{os, dba}","{dba, os}"} 6 | {"os\"dba"} 9 | {os,dba} 9 | {"os\"win",dba} 9 | {os'win,dba} (10 行记录)
# 多维数组 testdb=# create table test779 (id int , col1 test[][]); ERROR: type "test[]" does not exist 第1行create table test779 (id int , col1 test[][]); testdb=# create table test779 (id int , col1 text[][]); CREATE TABLE testdb=# \d test779; 数据表 "public.test779" 栏位 | 类型 | Collation | Nullable | Default ------+---------+-----------+----------+--------- id | integer | | | col1 | text[] | | | testdb=# insert into test779 values(1, array[['aa'], ['cc']]); INSERT 0 1 testdb=# insert into test779 values(1, array[['aa','bb'], ['cc','dd']]); INSERT 0 1 testdb=# select * from test779; id | col1 ----+------------------- 1 | {{aa},{cc}} 1 | {{aa,bb},{cc,dd}} (2 行记录) testdb=# insert into test779 values(1, array[['aa','bb'], ['cc','dd','dd']]); ERROR: multidimensional arrays must have array expressions with matching dimensions testdb=# insert into test779 values(3, '{{aa, bb}, {cc, dd}}'); INSERT 0 1 testdb=# select * from test779; id | col1 ----+------------------- 1 | {{aa},{cc}} 1 | {{aa,bb},{cc,dd}} 3 | {{aa,bb},{cc,dd}} (3 行记录) # 默认状况下数组的下标是从1开始的,postgres的数组是能够指定开始下标的 testdb=# create table test7799 (id int[]); CREATE TABLE testdb=# insert into test7799 values('[2:4]={1,2,3}'); INSERT 0 1 testdb=# select id[2], id[3], id[4] from test7799; id | id | id ----+----+---- 1 | 2 | 3 (1 行记录) testdb=# select id from test7799; id --------------- [2:4]={1,2,3} (1 行记录) testdb=# insert into test7799 values('{11,22,33}'); INSERT 0 1 testdb=# select id[2], id[3], id[4] from test7799; id | id | id ----+----+---- 1 | 2 | 3 22 | 33 | (2 行记录) testdb=# select id[1], id[2], id[3] from test7799; id | id | id ----+----+---- | 1 | 2 11 | 22 | 33 (2 行记录) # 从上面的例子能够看出,指定数组上下标的格式为: `[下标:上标] = [元素值1, 元素值2, 元素值3..]`
testdb=# create table test666 (id int, col1 int[][]); CREATE TABLE testdb=# \d test666; 数据表 "public.test666" 栏位 | 类型 | Collation | Nullable | Default ------+-----------+-----------+----------+--------- id | integer | | | col1 | integer[] | | | testdb=# insert into test666 values(1, '{{1,2,3}, {4,5,6}, {7,8,9}}'); INSERT 0 1 testdb=# select * from test666; id | col1 ----+--------------------------- 1 | {{1,2,3},{4,5,6},{7,8,9}} (1 行记录) # 多维数组读取 testdb=# select col1[1][1], col1[1][2], col1[2][1], col1[2][2] from test666; col1 | col1 | col1 | col1 ------+------+------+------ 1 | 2 | 4 | 5 (1 行记录) # 没法直接获取外层数组 testdb=# select id, col1[1] from test666; id | col1 ----+------ 1 | (1 行记录) # 数组切换可获取 testdb=# select id, col1[1:1] from test666; id | col1 ----+----------- 1 | {{1,2,3}} (1 行记录) testdb=# select id, col1[1:2] from test666; id | col1 ----+------------------- 1 | {{1,2,3},{4,5,6}} (1 行记录) # 注意这里的外层实际上是col1[3][1:2] == col1[1:3][1:2] testdb=# select id, col1[3][1:2] from test666; id | col1 ----+--------------------- 1 | {{1,2},{4,5},{7,8}} (1 行记录) testdb=# select id, col1[1:3][1:2] from test666; id | col1 ----+--------------------- 1 | {{1,2},{4,5},{7,8}} (1 行记录) # 注意这里的外层实际上是col1[1:2][2] == col1[1:2][1:2] testdb=# select id, col1[1:2][2] from test666; id | col1 ----+--------------- 1 | {{1,2},{4,5}} (1 行记录) testdb=# select id, col1[1:2][1:2] from test666; id | col1 ----+--------------- 1 | {{1,2},{4,5}} (1 行记录) # 修改 # 能够修改整个字段数组值,或修改某一维度的单元素的值 # 不过没法直接修改某一维数组的值 testdb=# select * from test666; id | col1 ----+--------------------------- 1 | {{1,2,3},{4,5,6},{7,8,9}} (1 行记录) testdb=# update test666 set col1[2][1] = 1000 where id=1; UPDATE 1 testdb=# select * from test666; id | col1 ----+------------------------------ 1 | {{1,2,3},{1000,5,6},{7,8,9}} (1 行记录) testdb=# update test666 set col1[2] = '{1,2,3}' where id=1; ERROR: invalid input syntax for integer: "{1,2,3}" 第1行update test666 set col1[2] = '{1,2,3}' where id=1;
伪类型(Pseudo-Types)是PostgreSQL中不能做为字段的数据类型,可是它能够用于声明
一个函数的参数或者结果类型。所包含的类型有:
□ any:用于指示函数的输人参数能够是任意数据类型的。
□ anyelement:表示一个函数接受任何数据类型。
□ anyarray:表示一个函数接受任何数组类型。
□ anynonarray:表示一个函数接受任何非数组类塑。
□ anyenum:表示一个函数接受任何枚举类型_。
□ anyrange:表示一个函数接受任何范类型。
□ cstring:表示一个函数接受或返回一个空字符(0)结尾的C语言字符串。
□ internal:表示一个函数接受或者返冋一种服务器内部的数据类型。
□ language_handler:声明一个函数返回类型是pi语言的一个handler闲数。
□ fdw_handler:声明一个函数的返冋类型楚foreign-data wrapper的handler函数。
□ record:标识一个函数返回一个未详细定义各列的row类型。
□ trigger: 一个触发器函数要声明为返回trigger类型。
□ void:表示一个函数没有返问值。
□ opaque:已通过时的类型,旧的PostgreSQL版本中用于上面这些用途。
用C编写的函数(不论是内H的仍是动态装载的)均可以卢明为接受或返冋上面任意一种伪数据类型。在把伪类型用做函数参数类型时,PostgreSQL数据库自己对类型检査就少了不少,保证类沏正确的任务就交给了写函数的幵发人员。
用过程语言编写的函数不必定都能使用上面列出的所有伪类型,具体能使用哪些须要丧看相关的过程语言文裆,或者查C•过程语言的实现。一般,过程语言都不支持使用“any”类型,但基本都能支持使用void和record做为结果类®,能支持多态闲数的过程语言还支持使
用“311)^〇^”、“311>^丨6咖111”、“3!1)^1111171”和‘‘311>010113〇'3>^’类型〇伪 类 型 “intemar用于声明那种只能在数据库系统内部调用的函数,它们不能直接在SQL査询里调用。若是函数至少有一个“internal”类型的参数,那么就不能从SQL里调用。
为了保留这个限制的类塑安全,必定要遵循这样的编码规则:对于没有任何一个"internal”参数的函数,不要把返回类型建立为“internal”。
UUID( Universally Unique Identifiers)用于存储一个 UUID; UUID 定义在RFC 4122
和 ISO/IEC 9834-8:2005
中。它是一个128bit的数字
PostgreSQL核心源代码中没提供产生UUID的函数,contrib下的uuid-ossp模块提供UUID的函数
pg_lsn类切是PostgrcSQL9.4版本以后提供的表示LSN ( Log Sequence Number)的一种数据类拟。LSN表示WALfi志的位酋。在一些记录WALti志信息的系统表中某些字段的类型就是pg_lsn类型