资讯专栏INFORMATION COLUMN

PostgreSQL的实践一:数据类型(二)

Mr_houzi / 3224人阅读

摘要:的实践一数据类型一数据类型复合类型创建一个复合类型命令格式合成类型栏位类型没有找到任何名称为的关联。数据库会对输人的数据进行检查,让一些不符合标准的数据不能存放到数据库中,同时还提供了函数对其类型进行安全性检査。

PostgreSQL的实践一:数据类型(一)

数据类型 复合类型

</>复制代码

  1. # 创建一个复合类型person
  2. # 命令格式:create type xxx AS ();
  3. testdb=# create type person AS (
  4. testdb(# name text,
  5. testdb(# age int4,
  6. testdb(# sex boolean
  7. testdb(# );
  8. CREATE TYPE
  9. testdb=# d person;
  10. 合成类型 "public.person"
  11. 栏位 | 类型 | Collation | Nullable | Default
  12. ------+---------+-----------+----------+---------
  13. name | text | | |
  14. age | integer | | |
  15. sex | boolean | | |
  16. testdb=# dt person;
  17. 没有找到任何名称为 "person" 的关联。
  18. testdb=# d person;
  19. 合成类型 "public.person"
  20. 栏位 | 类型 | Collation | Nullable | Default
  21. ------+---------+-----------+----------+---------
  22. name | text | | |
  23. age | integer | | |
  24. sex | boolean | | |
  25. # 创建一个带复合类型的表author
  26. testdb=# create table author (
  27. testdb(# id int4,
  28. testdb(# people person,
  29. testdb(# book text
  30. testdb(# );
  31. CREATE TABLE
  32. testdb=# d author;
  33. 数据表 "public.author"
  34. 栏位 | 类型 | Collation | Nullable | Default
  35. --------+---------+-----------+----------+---------
  36. id | integer | | |
  37. people | person | | |
  38. book | text | | |
  39. # 插入数据
  40. testdb=# insert into author values(1, " ("qkl", 29, TRUE)", "张三的自传");
  41. INSERT 0 1
  42. # 缺省不填写就是NULL,逗号间不要有空格
  43. testdb=# insert into author values(2, "("zgq", , TRUE)", "张三的自传2");
  44. ERROR: invalid input syntax for integer: " "
  45. 第1行insert into author values(2, "("zgq", , TRUE)", "张三的自传2...
  46. ^
  47. testdb=# insert into author values(2, "("zgq",,TRUE)", "张三的自传2");
  48. INSERT 0 1
  49. testdb=# insert into author values(2, "("zgq",, TRUE)", "张三的自传2");
  50. INSERT 0 1
  51. testdb=# insert into author values(3, "("",, TRUE)", "张三的自传3");
  52. INSERT 0 1
  53. # ROW行插入,注意ROW后面的字符请用单引号,不能带双引号
  54. testdb=# insert into author values(4, ROW("",, TRUE), "张三的自传5");
  55. ERROR: zero-length delimited identifier at or near """"
  56. 第1行insert into author values(4, ROW("",, TRUE), "张三的自传5");
  57. ^
  58. testdb=# insert into author values(4, ROW("PCB",, TRUE), "张三的自传5");
  59. ERROR: syntax error at or near ","
  60. 第1行insert into author values(4, ROW("PCB",, TRUE), "张三的自传5...
  61. ^
  62. # 省略ROW
  63. testdb=# insert into author values(4, ("hgr",30, TRUE), "张三的自传6");
  64. INSERT 0 1
  65. testdb=# select (people).name from author;
  66. name
  67. ------
  68. qkl
  69. zgq
  70. zgq
  71. hgr
  72. (5 行记录)
  73. # 更新复合类型数据,复合类型名不带括号
  74. testdb=# update author set people.name="qkl2" where id=1;
  75. UPDATE 1
  76. testdb=# select people from author;
  77. people
  78. -------------
  79. (zgq,,t)
  80. (zgq,,t)
  81. ("",,t)
  82. (hgr,30,t)
  83. (qkl2,29,t)
  84. (5 行记录)
  85. testdb=# update author set people.age = people.age +1 where id=1;
  86. ERROR: missing FROM-clause entry for table "people"
  87. 第1行update author set people.age = people.age +1 where id=1;
  88. ^
  89. # 如果更新的字段右边也是复合类型必须携带括号
  90. testdb=# update author set people.age = (people).age +1 where id=1;
  91. UPDATE 1
  92. testdb=# select people from author;
  93. people
  94. -------------
  95. (zgq,,t)
  96. (zgq,,t)
  97. ("",,t)
  98. (hgr,30,t)
  99. (qkl2,30,t)
  100. (5 行记录)
  101. # 多带带插入复合类型的数据
  102. testdb=# insert into author (id, people.name, people.age) values(7, "ldh", 33);
  103. INSERT 0 1
  104. testdb=# select * from author;
  105. id | people | book
  106. ----+-------------+-------------
  107. 2 | (zgq,,t) | 张三的自传2
  108. 2 | (zgq,,t) | 张三的自传2
  109. 3 | ("",,t) | 张三的自传3
  110. 4 | (hgr,30,t) | 张三的自传6
  111. 1 | (qkl2,30,t) | 张三的自传
  112. 7 | (ldh,33,) |
  113. (6 行记录)
XML类型

xm丨类型可以用于存储XML数据。使用字符串类型(如text)也可以存储XML数据,但text类型不能保证其中存储的是合法XML数据,通常需要由应用程序来负责保证输人数据的正确性,这将增加应用程序开发的难度。而使用xml类型就不存在此问题。数据库会对输人的数据进行检查,让一些不符合XML标准的数据不能存放到数据库中,同时还提供了函数对其类型进行安全性检査。
注意,要使用xml数据类型,在编译PostgreSQL源码时必须使用以下参数:
configure --with-libxml

xml存储的XML数据杳两种:

由 XML 标准走义的documents

由XML标准定义的content片段。

content片段可以有多个级元素或character节点.但documents只能有一个顶级元素。可以使用xmlvalue is DOCUMENT来判断一个特定的XML值是一个documents还足content片段。
PostgreSQL的xmlopiions参数用来指定输人的数据是documents还是content片段,默认情况下此值为content片段。所以输人的xml可以有多个顶级元素,但如果把此参数改成document,将不能输人有多个顶级元素的内容。

PostgreSQL数据库在客户端与服务器之间传递数据时,会自动进行字符集的转换。如果客户端的字符集与服务端不一样,PostgreSQL会自动进行字符集转换。但也正是因为有这个特性,在传递XML数据时需要格外注意。我们知道,对于XML文件来说,可以通过类似“encoding="XXX"”的方式指定自己文件的字符集,但当这些数据在PostgreSQL之间传递时, PostgreSQL会把其原始内容的宇符集变成数据库服务端的字符集,而这就会导致问题,因为这意味着XML数据中的字符集编码声明在客户端和服务器之间传递时,可能变得无效。为了应对该问题,提交输人到xml类型的字符串中的编码声明将会被忽略掉.同时内容的字符集会被认为是当前数据库服务器的字符集。

正确处理XML字符集的方式是,先将XML数据的字符串在当前客户端中编码成当前客户端的字符集,然后再发送到服务端,这样就会被转换成服务端的字符集存储。当査询xml 类型的值时,此数据又会被转换成客户端的字符集,所以客户端收到的XML数据的字符集就是客户端的字符集。
所以通常来说,如果XML数据的字符集编码、客户端字符集编码,以及服务器字符集编码完全一样,那么用PostgreSQL处理XML数据将会大大减少字符集问题,并且处理的效率也会很高。通常XML数据都是用UTF-8编码格式处理的,因此把PostgreSQL数据库服务器端编码也设置成UTF-8将是一种较好的选择。

</>复制代码

  1. postgres=# select xml"hello postgres";
  2. xml
  3. -----------------------------
  4. hello postgres
  5. (1 行记录)
  6. postgres=# show xmloption;
  7. xmloption
  8. -----------
  9. content
  10. (1 行记录)
  11. postgres=# set xmloption TO document;
  12. SET
  13. postgres=# show xmloption;
  14. xmloption
  15. -----------
  16. document
  17. (1 行记录)
  18. # document类型,插入多顶级元素,出错
  19. postgres=# select xml"hello postgreshello world";
  20. ERROR: invalid XML document
  21. 第1行select xml"hello postgreshello worldhello postgreshello world
  22. ^
  23. postgres=# set xmloption TO content;
  24. SET
  25. postgres=# select xml"hello postgreshello world";
  26. xml
  27. -------------------------------------------------------
  28. hello postgreshello world
  29. (1 行记录)
  30. # xmlparse函数
  31. postgres=# select xmlparse(document"qkl");
  32. xmlparse
  33. -----------------------------------
  34. qkl
  35. (1 行记录)
  36. postgres=# select xmlparse(content"qkl");
  37. xmlparse
  38. -----------------------------------
  39. qkl
  40. (1 行记录)
json类型

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数据类型范闹的值。

基础操作

</>复制代码

  1. testdb=# select "9"::json, ""osdba""::json, "true"::json, "null"::json;
  2. json | json | json | json
  3. ------+---------+------+------
  4. 9 | "osdba" | true | null
  5. (1 行记录)
  6. testdb=# select "[9, true, "qkl", null]"::json, "[9, true, "qkl", null]"::jsonb;
  7. json | jsonb
  8. ------------------------+------------------------
  9. [9, true, "qkl", null] | [9, true, "qkl", null]
  10. (1 行记录)
  11. testdb=# select json"{"name":"qkl", "age":18, "sex":true, "money":888.88}";
  12. json
  13. ------------------------------------------------------
  14. {"name":"qkl", "age":18, "sex":true, "money":888.88}
  15. (1 行记录)
  16. # json 存取的是浮点型,存在精度问题
  17. testdb=# select json"{"p":1.684544545454e-27}";
  18. json
  19. --------------------------
  20. {"p":1.684544545454e-27}
  21. (1 行记录)
  22. # jsonb存取的是numeric
  23. testdb=# select jsonb"{"p":1.684544545454e-27}";
  24. jsonb
  25. --------------------------------------------------
  26. {"p": 0.000000000000000000000000001684544545454}
  27. (1 行记录)

更多和操作符

</>复制代码

  1. testdb=# select json"[1,2,3]"->0;
  2. ?column?
  3. ----------
  4. 1
  5. (1 行记录)
  6. testdb=# select json"[1,2,3]"->3;
  7. ?column?
  8. ----------
  9. (1 行记录)
  10. testdb=# select json"[1,2,3]"->2;
  11. ?column?
  12. ----------
  13. 3
  14. (1 行记录)
  15. testdb=# select json"[1,2,3]"->>2;
  16. ?column?
  17. ----------
  18. 3
  19. (1 行记录)
  20. testdb=# select json"[1,2,3]"->>"2";
  21. ?column?
  22. ----------
  23. (1 行记录)
  24. testdb=# select json"{"a":1,"b":22}"->>"a";
  25. ?column?
  26. ----------
  27. 1
  28. (1 行记录)
  29. testdb=# select json"{"a":{"a1":{"a11":111}},"b":22}"#>"{a,a1}"
  30. testdb-# ;
  31. ?column?
  32. -------------
  33. {"a11":111}
  34. (1 行记录)
  35. testdb=# select json"{"a":{"a1":{"a11":111}},"b":22}"#>"{a,a1,a11}"
  36. testdb-# ;
  37. ?column?
  38. ----------
  39. 111
  40. (1 行记录)
  41. testdb=# select json"{"a":{"a1":{"a11":111}},"b":22}"#>>"{a,a1,a11}";
  42. ?column?
  43. ----------
  44. 111
  45. (1 行记录)
  46. testdb=# select json"{"a":{"a1":{"a11":111}},"b":22}"#>>"{a,a1}";
  47. ?column?
  48. -------------
  49. {"a11":111}
  50. (1 行记录)

Range类型

</>复制代码

  1. testdb=# select "(0,6)"::int4range;
  2. int4range
  3. -----------
  4. [1,6)
  5. (1 行记录)
  6. testdb=# select "[0,6)"::int4range;
  7. int4range
  8. -----------
  9. [0,6)
  10. (1 行记录)
  11. testdb=# select "[0,6]"::int4range;
  12. int4range
  13. -----------
  14. [0,7)
  15. (1 行记录)
  16. testdb=# select "empty"::int4range;
  17. int4range
  18. -----------
  19. empty
  20. (1 行记录)
  21. # 上面我们看出,int4range总数会转换成`[)`格式
  22. testdb=# select "[0,6]"::numrange;
  23. numrange
  24. ----------
  25. [0,6]
  26. (1 行记录)
  27. testdb=# select "[0,6)"::numrange;
  28. numrange
  29. ----------
  30. [0,6)
  31. (1 行记录)
  32. testdb=# select "(0,6)"::numrange;
  33. numrange
  34. ----------
  35. (0,6)
  36. (1 行记录)
  37. testdb=# select "(0,)"::numrange;
  38. numrange
  39. ----------
  40. (0,)
  41. (1 行记录)
  42. testdb=# select "[1,)"::numrange;
  43. numrange
  44. ----------
  45. [1,)
  46. (1 行记录)

数组类型

PostgreSQL支持表的字段使用定长或可变长度的一维或多维数组,数组的类型可以是任何数据库内建的类型、用户自定义的类型、枚举类型,以及组合类型。但目前还不支持domain类型。

</>复制代码

  1. create table test6 (id int, col1 int[], col2 int[10], col3 text[][]);
  2. create table test7 (id int, col1 int[10], col2 int[], col3 text[]);

在第一个语句中第二列的声明col2 int[10]与第二个语句中第二列的声明col2 int[]其意思相同;而在第一个语句中第三列的声明col3 text[][]与第二个语句中第三列的声明col3 text[]的意思也是相同的

我们来查看下表结构

</>复制代码

  1. testdb=# create table test6 (id int, col1 int[], col2 int[10], col3 text[][]);
  2. CREATE TABLE
  3. testdb=# create table test7 (id int, col1 int[10], col2 int[], col3 text[]);
  4. CREATE TABLE
  5. testdb=# d
  6. 关联列表
  7. 架构模式 | 名称 | 类型 | 拥有者
  8. ----------+--------------+--------+----------
  9. public | author | 数据表 | postgres
  10. public | test1 | 数据表 | postgres
  11. public | test2 | 数据表 | postgres
  12. public | test2_id_seq | 序列数 | postgres
  13. public | test3 | 数据表 | postgres
  14. public | test3_id_seq | 序列数 | postgres
  15. public | test6 | 数据表 | postgres
  16. public | test7 | 数据表 | postgres
  17. (8 行记录)
  18. testdb=# d test6;
  19. 数据表 "public.test6"
  20. 栏位 | 类型 | Collation | Nullable | Default
  21. ------+-----------+-----------+----------+---------
  22. id | integer | | |
  23. col1 | integer[] | | |
  24. col2 | integer[] | | |
  25. col3 | text[] | | |
  26. testdb=# d test7;
  27. 数据表 "public.test7"
  28. 栏位 | 类型 | Collation | Nullable | Default
  29. ------+-----------+-----------+----------+---------
  30. id | integer | | |
  31. col1 | integer[] | | |
  32. col2 | integer[] | | |
  33. col3 | text[] | | |

</>复制代码

  1. testdb=# create table test66(id int, col1 int[]);
  2. CREATE TABLE
  3. testdb=# insert into test66 values(1, "{1,2,3}");
  4. INSERT 0 1
  5. testdb=# insert into test66 values(2, "{4,5,6}");
  6. INSERT 0 1
  7. testdb=# select * from test66;
  8. id | col1
  9. ----+---------
  10. 1 | {1,2,3}
  11. 2 | {4,5,6}
  12. (2 行记录)
  13. testdb=# create table test77(id int, col1 text[]);
  14. CREATE TABLE
  15. testdb=# insert into test77 values(1, "{how, howe, howl}");
  16. INSERT 0 1
  17. testdb=# select * from test77;
  18. id | col1
  19. ----+-----------------
  20. 1 | {how,howe,howl}
  21. (1 行记录)
  22. testdb=# insert into test77 values(1, "{"how", "howe", "howl"}");
  23. INSERT 0 1
  24. testdb=# select * from test77;
  25. id | col1
  26. ----+-----------------
  27. 1 | {how,howe,howl}
  28. 1 | {how,howe,howl}
  29. (2 行记录)
  30. # 注意上面不同的类型,可能分隔符会不一样,下面可查询不同类型的分隔符
  31. testdb=# select typname,typdelim from pg_type where typname in ("int4", "int8", "bool", "char", "box");
  32. typname | typdelim
  33. ---------+----------
  34. bool | ,
  35. char | ,
  36. int8 | ,
  37. int4 | ,
  38. box | ;
  39. (5 行记录)
  40. testdb=# create table test778(id int ,col1 box[]);
  41. CREATE TABLE
  42. testdb=# insert into test778 values(1, "{((1,1), (2,2)); ((3,3),(4,4))}");
  43. INSERT 0 1
  44. testdb=# select * from test778;
  45. id | col1
  46. ----+---------------------------
  47. 1 | {(2,2),(1,1);(4,4),(3,3)}
  48. (1 行记录)
  49. # 上面输人的字符串内容是没有空格的,在有空格时,乂该如何输人呢?见下面的例子:
  50. testdb=# insert into test77 values(3,"{how many,how mach,how old}");
  51. INSERT 0 1
  52. 可以看到有空格,也可以直接输人。
  53. 那么字符串中有逗号时怎么办呢?这时可以使用双引号,如下:
  54. testdb=# insert into test77 values(4,"{"who, what", "CO.,LTD."}");
  55. INSERT 0 1
  56. 如果字符串中有单引号怎么办呢?这时可以使用两个连接的单引号表示一个单引号:
  57. testdb=# insert into test77 values(3,"{"who""s bread", "It""s ok"}");
  58. INSERT 0 1
  59. 如果输人的字符串中有括号"{""}"怎么办呢?只需把它们放到双引号中即可:
  60. testdb=# insert into test77 values (5, "{"{os, dba}", "{dba, os}"}");
  61. INSERT 0 1
  62. 如果输人的字符串中有双引号怎么办呢?这时需要在双引号前加反斜扛,如下所示:
  63. testdb=# insert into test77 values(6,"{os"dba}");
  64. testdb=# select * from test77;
  65. id | col1
  66. ----+-----------------------------------
  67. 1 | {how,howe,howl}
  68. 1 | {how,howe,howl}
  69. 3 | {"how many","how mach","how old"}
  70. 4 | {"who, what","CO.,LTD."}
  71. 3 | {"who"s bread","It"s ok"}
  72. 5 | {"{os, dba}","{dba, os}"}
  73. 6 | {"os"dba"}
  74. (7 行记录)
  75. # ARRAY关键词的使用,需带单引号
  76. testdb=# insert into test77 values(9, array["os", "dba"]);
  77. INSERT 0 1
  78. testdb=# insert into test77 values(9, array["os"win", "dba"]);
  79. INSERT 0 1
  80. testdb=# insert into test77 values(9, array["os""win", "dba"]);
  81. INSERT 0 1
  82. testdb=# select * from test77;
  83. id | col1
  84. ----+-----------------------------------
  85. 1 | {how,howe,howl}
  86. 1 | {how,howe,howl}
  87. 3 | {"how many","how mach","how old"}
  88. 4 | {"who, what","CO.,LTD."}
  89. 3 | {"who"s bread","It"s ok"}
  90. 5 | {"{os, dba}","{dba, os}"}
  91. 6 | {"os"dba"}
  92. 9 | {os,dba}
  93. 9 | {"os"win",dba}
  94. 9 | {os"win,dba}
  95. (10 行记录)

</>复制代码

  1. # 多维数组
  2. testdb=# create table test779 (id int , col1 test[][]);
  3. ERROR: type "test[]" does not exist
  4. 第1行create table test779 (id int , col1 test[][]);
  5. testdb=# create table test779 (id int , col1 text[][]);
  6. CREATE TABLE
  7. testdb=# d test779;
  8. 数据表 "public.test779"
  9. 栏位 | 类型 | Collation | Nullable | Default
  10. ------+---------+-----------+----------+---------
  11. id | integer | | |
  12. col1 | text[] | | |
  13. testdb=# insert into test779 values(1, array[["aa"], ["cc"]]);
  14. INSERT 0 1
  15. testdb=# insert into test779 values(1, array[["aa","bb"], ["cc","dd"]]);
  16. INSERT 0 1
  17. testdb=# select * from test779;
  18. id | col1
  19. ----+-------------------
  20. 1 | {{aa},{cc}}
  21. 1 | {{aa,bb},{cc,dd}}
  22. (2 行记录)
  23. testdb=# insert into test779 values(1, array[["aa","bb"], ["cc","dd","dd"]]);
  24. ERROR: multidimensional arrays must have array expressions with matching dimensions
  25. testdb=# insert into test779 values(3, "{{aa, bb}, {cc, dd}}");
  26. INSERT 0 1
  27. testdb=# select * from test779;
  28. id | col1
  29. ----+-------------------
  30. 1 | {{aa},{cc}}
  31. 1 | {{aa,bb},{cc,dd}}
  32. 3 | {{aa,bb},{cc,dd}}
  33. (3 行记录)
  34. # 默认情况下数组的下标是从1开始的,postgres的数组是可以指定开始下标的
  35. testdb=# create table test7799 (id int[]);
  36. CREATE TABLE
  37. testdb=# insert into test7799 values("[2:4]={1,2,3}");
  38. INSERT 0 1
  39. testdb=# select id[2], id[3], id[4] from test7799;
  40. id | id | id
  41. ----+----+----
  42. 1 | 2 | 3
  43. (1 行记录)
  44. testdb=# select id from test7799;
  45. id
  46. ---------------
  47. [2:4]={1,2,3}
  48. (1 行记录)
  49. testdb=# insert into test7799 values("{11,22,33}");
  50. INSERT 0 1
  51. testdb=# select id[2], id[3], id[4] from test7799;
  52. id | id | id
  53. ----+----+----
  54. 1 | 2 | 3
  55. 22 | 33 |
  56. (2 行记录)
  57. testdb=# select id[1], id[2], id[3] from test7799;
  58. id | id | id
  59. ----+----+----
  60. | 1 | 2
  61. 11 | 22 | 33
  62. (2 行记录)
  63. # 从上面的例子可以看出,指定数组上下标的格式为:
  64. `[下标:上标] = [元素值1, 元素值2, 元素值3..]`

</>复制代码

  1. testdb=# create table test666 (id int, col1 int[][]);
  2. CREATE TABLE
  3. testdb=# d test666;
  4. 数据表 "public.test666"
  5. 栏位 | 类型 | Collation | Nullable | Default
  6. ------+-----------+-----------+----------+---------
  7. id | integer | | |
  8. col1 | integer[] | | |
  9. testdb=# insert into test666 values(1, "{{1,2,3}, {4,5,6}, {7,8,9}}");
  10. INSERT 0 1
  11. testdb=# select * from test666;
  12. id | col1
  13. ----+---------------------------
  14. 1 | {{1,2,3},{4,5,6},{7,8,9}}
  15. (1 行记录)
  16. # 多维数组读取
  17. testdb=# select col1[1][1], col1[1][2], col1[2][1], col1[2][2] from test666;
  18. col1 | col1 | col1 | col1
  19. ------+------+------+------
  20. 1 | 2 | 4 | 5
  21. (1 行记录)
  22. # 无法直接获取外层数组
  23. testdb=# select id, col1[1] from test666;
  24. id | col1
  25. ----+------
  26. 1 |
  27. (1 行记录)
  28. # 数组切换可获取
  29. testdb=# select id, col1[1:1] from test666;
  30. id | col1
  31. ----+-----------
  32. 1 | {{1,2,3}}
  33. (1 行记录)
  34. testdb=# select id, col1[1:2] from test666;
  35. id | col1
  36. ----+-------------------
  37. 1 | {{1,2,3},{4,5,6}}
  38. (1 行记录)
  39. # 注意这里的外层其实是col1[3][1:2] == col1[1:3][1:2]
  40. testdb=# select id, col1[3][1:2] from test666;
  41. id | col1
  42. ----+---------------------
  43. 1 | {{1,2},{4,5},{7,8}}
  44. (1 行记录)
  45. testdb=# select id, col1[1:3][1:2] from test666;
  46. id | col1
  47. ----+---------------------
  48. 1 | {{1,2},{4,5},{7,8}}
  49. (1 行记录)
  50. # 注意这里的外层其实是col1[1:2][2] == col1[1:2][1:2]
  51. testdb=# select id, col1[1:2][2] from test666;
  52. id | col1
  53. ----+---------------
  54. 1 | {{1,2},{4,5}}
  55. (1 行记录)
  56. testdb=# select id, col1[1:2][1:2] from test666;
  57. id | col1
  58. ----+---------------
  59. 1 | {{1,2},{4,5}}
  60. (1 行记录)
  61. # 修改
  62. # 可以修改整个字段数组值,或修改某一维度的单元素的值
  63. # 不过无法直接修改某一维数组的值
  64. testdb=# select * from test666;
  65. id | col1
  66. ----+---------------------------
  67. 1 | {{1,2,3},{4,5,6},{7,8,9}}
  68. (1 行记录)
  69. testdb=# update test666 set col1[2][1] = 1000 where id=1;
  70. UPDATE 1
  71. testdb=# select * from test666;
  72. id | col1
  73. ----+------------------------------
  74. 1 | {{1,2,3},{1000,5,6},{7,8,9}}
  75. (1 行记录)
  76. testdb=# update test666 set col1[2] = "{1,2,3}" where id=1;
  77. ERROR: invalid input syntax for integer: "{1,2,3}"
  78. 第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

UUID( Universally Unique Identifiers)用于存储一个 UUID; UUID 定义在RFC 4122ISO/IEC 9834-8:2005中。它是一个128bit的数字
PostgreSQL核心源代码中没提供产生UUID的函数,contrib下的uuid-ossp模块提供UUID的函数

PG_LSN

pg_lsn类切是PostgrcSQL9.4版本之后提供的表示LSN ( Log Sequence Number)的一种数据类拟。LSN表示WALfi志的位酋。在一些记录WALti志信息的系统表中某些字段的类型就是pg_lsn类型

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/39017.html

相关文章

  • PostgreSQL实践数据类型

    摘要:数据类型类型转换数值类型数值类型序列类型不同于的自增长,和都是序列的方式创建使用创建序列关联列表架构模式名称类型拥有者数据表数据表序列数行记录数据 数据类型 showImg(https://segmentfault.com/img/bVbi9mw?w=750&h=379);showImg(https://segmentfault.com/img/bVbi9mz?w=729&h=626)...

    高璐 评论0 收藏0
  • 新书推荐 |《PostgreSQL实战》出版(提供样章下载)

    摘要:作者谭峰张文升出版日期年月页数页定价元本书特色中国开源软件推进联盟分会特聘专家撰写,国内多位开源数据库专家鼎力推荐。张文升中国开源软件推进联盟分会核心成员之一。 很高兴《PostgreSQL实战》一书终于出版,本书大体上系统总结了笔者 PostgreSQL DBA 职业生涯的经验总结,本书的另一位作者张文升拥有丰富的PostgreSQL运维经验,目前就职于探探科技任首席PostgreS...

    Martin91 评论0 收藏0
  • 想熟悉PostgreSQL?这篇就够了

    摘要:它在其他开放源代码数据库系统和专有系统之外,为用户又提供了一种选择。将插入空间以填补任何额外的空间。始终被视为唯一值上述两个约束的组合。表范围的约束可以是,,或。如何在中创建表我们将创建一个名为的表,它定义了各种游乐场设备。 欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由angel_郁 发表于云+社区专栏 什么是PostgreSQL? PostgreSQL是自由...

    DTeam 评论0 收藏0
  • PostgreSQL实践:初识

    摘要:每个服务由多个进程组成,为首的进程名为。服务使用字节长的内部事务标识符,即时发生重叠后仍然继续使用,这会导致问题,所以需要定期进行操作。操作被认为是紧跟操作后的操作。在涉及高比例插入删除的表中,会造成索引膨胀,这时候可以重建索引。 简介和认知 发音 post-gres-q-l 服务(server) 一个操作系统中可以启动多个postgres服务。每个服务由多个进程组成,为首的进程名为p...

    yibinnn 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<