1. 模式操作

1.1. 创建数据库

CREATE DATABASE 数据库名;

1.2. 删除数据库

drop database 数据库名;

1.3. 创建用户

要创建一个角色,可以使用 CREATE ROLE 命令:

CREATE USERCREATE ROLE 等效,除了 CREATE USER 默认有 LOGIN,而 CREATE ROLE 没有。具有 LOGIN 属性的角色才能连接到数据库。用户密码要求长度至少为8位,必须含有大小写字母、数字以及 !@#$%^&*() 特殊字符,不能含有当前用户名字符串,不能含有瀚高数据库保留字和关键字,不能使用最近五个使用过的密码。

CREATE ROLE 用户名 LOGIN password '密码';

CREATE USER 用户名 password 'mima';

1.4. 创建模式

create schema [if not exists] 模式名 [AUTHORIZATION 用户名];

1.5. 删除模式

drop schema [if exists] 模式名;

2. 数据表操作

2.1. 创建数据表

-- 语法
create table [if not exists] [模式.]表名(    
  字段名1  字段类型1(字段长度),  -- 不是;号    
  字段名2  字段类型2(字段长度),	
  ....	
  字段名n  字段类型n(字段长度)  -- 最后一列后面是没有,的
);

-- 实例  
create table if not exists test.person(
  "id" INTEGER identity(1, 1),
  "username" VARCHAR(20),
  "password" VARCHAR(50),
  "gender" CHAR(10),
  "addr" VARCHAR(100),
  primary key("id")
);

2.2. 常见的数据类型

2.2.1. 数字类型

HGDB 有着丰富的本地数据类型可用,用户也可以使用 CREATE TYPE 命令为 HGDB 增加新的数据类型。

数字类型由 2、4 或 8 字节的整数以及 4 或 8 字节的浮点数和可选精度小数组成。下表列出了数字类型的所有可用类型。

名字

存储尺寸

描述

范围

smallint

2字节

小范围整数

-32768 to +32767

integer

4字节

整数的典型选择

-2147483648 to +2147483647

bigint

8字节

大范围整数

-9223372036854775808 to +9223372036854775807

decimal

可变

用户指定精度,精确

最高小数点前 131072 位,以及小数点后16383 位

numeric(precision,scale)

可变

用户指定精度,精确

最高小数点前 131072位,以及小数点后16383 位

real

4字节

可变精度,不精确

6 位十进制精度

double precision

8字节

可变精度,不精确

15 位十进制精度

smallserial

2字节

自动增加的小整数

1 到 32767

serial

4字节

自动增加的整数

1 到 2147483647

bigserial

8字节

自动增加的大整数

1 到9223372036854775807

2.2.1.1. 整数类型

smallint、integer、bigint。常用的类型是 integer,一般只有在磁盘空间紧张的时候才用 smallint 类型,只有在 integer 范围不够的时候才用 bigint 类型。

2.2.1.2. 任意精度数字

numeric(precision,scale)、decimal、real、double precision。numeric 的 precision 是数中有效位的位数,包括小数点两边的数字,scale 是小数部分的位数。numeric 建议用于货币金额和其他要求计算准确的数量。类型 decimal 和 numeric 是等效的,在圆整时,numeric 类型会圆整到远离零的整数,而大部分情况下 real 和 double precision 类型会圆整到最近的偶数。

2.2.1.3. 浮点类型

real、double precision 是不精确的、变精度的数字类型。

2.2.1.4. 序数类型

smallserial、serial、bigserial。可以用序数类型为表创建一个自增列。类型名 serial 和 serial4 是等效的,两个都创建 integer 列。类型名 bigserial 和 serial8 是等效的,它们创建一个 bigint 列。如果预计使用的标识符数目超过 2^31 个,那么建议使用 bigserial。类型名 smallserial 和 serial2 也以相同方式工作,它们创建一个 smallint 列。

2.2.2. 货币类型

money 类型存储固定小数精度的货币数字,小数的精度由数据库的 lc_monetary 设置决定,表中展示的范围假设有两个小数位。money 类型可以接受的输入格式很多,包括整数和浮点数文字,以及常用的货币格式,如’$1,000.00’。 输出通常是最后一种形式,但和区域相关。

名字

存储尺寸

描述

范围

money

8 bytes

货币额

92233720368547758.08 to +92233720368547758.07

由于这种数据类型的输出是区域敏感的,因此将 money 数据装入到另一个不同 lc_monetary 的数据库是不起作用的,在恢复一个转储到一个新数据库中之前,应确保新数据库的 lc_monetary 设置和被转储数据库的相同或者具有等效值。

2.2.3. 字符类型

名字

描述

character varying(n),varchar(n)

有限制的变长

character(n),char(n)

定长,空格填充

text

无限变长

n 是一个正整数,character varying(n) 、varchar(n) 、character(n)、char(n) 将存储长度不超过 n 位的的串。text 类型可以存储任何长度的串。这三种类型之间没有性能差别,只是 character(n) 由于可能需要额外的存储开销,因而在大多数情况下,text 或者 character varying 是更好的选择。

如果串的长度小于 n,character(n) 和 char(n) 将会用空白对剩余的长度进行填充,而 character varying(n) 和 varchar(n) 将直接存储串的内容,不会对剩余的长度进行填充。character 结尾的空白在进行两个值比较时不会进行考虑,character varying 和 text 结尾的空白语意上是有含义的,在模式匹配时会进行考虑。没有长度声明的 character 等效于 character(1),没有长度声明的 character varying 接受任何长度的串。varchar(n) 和 char(n) 的概念分别是 character varying(n) 和 character(n) 的别名。

2.2.4. 二进制数据类型

bytea 数据类型允许存储二进制串。

名字

存储尺寸

描述

bytea

1 或 4 字节外加真正的二进制串

变长二进制串

bytea 类型支持两种用于输入和输出的格式:“十六进制”格式和瀚高数据库的历史的“转义”格式。在输入时这两种格式总是会被接受,输出格式则取决于配置参数 bytea_output,其默认值为十六进制。“十六进制”格式将二进制数据编码为每个字节 2 个十六进制位,最高有效位在前,整个串以序列 \x 开头(用以和转义格式区分)。作为输入,十六进制位可以是大写也可以是小写,在位对之间可以有空白。

例如下面是一个十六进制格式。

SELECT '\xDEADBEEF';

“转义”格式是 bytea 类型的传统瀚高数据库格式,将二进制串表示成 ASCII 字符序列。通常,要转义一个字节,需要把它转换成它的三位八进制值,前导一个反斜线。反斜线本身可以双写来进行表示。

下表给出了必须被转义的字符及替代转义序列:

十进制字节值

描述

转义输入表示

例子

十六进制表示

0

0字节

‘\000’

SELECT ‘\000’::bytea;

\x00

39

单引号

‘’’’或’\047’

SELECT ‘’’’::bytea;

\x27

92

反斜线

‘\\‘或’\134’

SELECT ‘\\'::bytea;

\x5c

0到31和127到255

“不可打印”字节

‘\xxx’(八进制值)

SELET ‘\001’::bytea;

\x01

二进制串和字符串的区别有两个:

首先,二进制串明确允许存储零值的字节以及其它“不可打印的”字节(通常是位于十进制范围 32 到 126 之外的字节)。 字符串不允许零字节,并且也不允许那些对于数据库的选定字符集编码是非法的任何其它字节值或者字节值序列。

其次,对二进制串的操作会处理实际上的字节,而字符串的处理取决于区域设置。 简单说,二进制字串适用于存储那些程序员认为是“裸字节”的数据,而字符串适合存储文本。

2.2.5. 日期/时间类型

HGDB 支持 SQL 中所有的日期和时间类型,日期根据公历来计算,对于该历法被引入之前的年份也一样。

下表是 HGDB 中的日期/时间类型。

名字

存储尺寸

描述

最小值

最大值

解析度

timestamp [ (p) ] [ without time zone ]

8字节

包括日期和时间(无时区)

4713BC

294276AD

1微秒

timestamp [ (p) ] with time zone

8字节

包括日期和时间,有时区

4713BC

294276AD

1微秒

date

4字节

日期(没有一天中的时间)

4713BC

5874897AD

1日

time [ (p) ] [ without time zone ]

8字节

一天中的时间(无日期)

00:00:00

24:00:00

1微秒

time [ (p) ] with time zone

12字节

仅仅是一天中的时间(没有日期),带有时区

00:00:00+1459

24:00:00-1459

1微秒

interval [ fields ] [ (p) ]

16字节

时间间隔

-178000000年

178000000年

1微秒

HGDB 中,timestamp 等效于 timestamp without time zone,timestamptz 被接受为 timestamp with time zone 的一种简写。

time、timestamp 和 interval 接受一个可选的精度值 p,这个精度值声明在秒域中小数点之后保留的位数,p 允许的范围是从0到6,缺省情况下,在精度上没有明确的边界。

interval 类型有一个附加选项,可以通过写下面之一的短语来限制存储的 fields 的集合:

YEAR、MONTH、DAY、HOUR、MINUTE、SECOND、

YEAR TO MONTH、DAY TO HOUR、DAY TO MINUTE、DAY TO SECOND、

HOUR TO MINUTE、HOUR TO SECOND、MINUTE TO SECOND

注意如果 fields 和 p 被指定,fields 必须包括 SECOND,因为精度只应用于秒。

2.2.5.1. 日期/时间输入

所有日期或者时间在输入时都需要由单引号包围,就像一个文本字符串一样。

日期和时间的输入可以接受几乎任何合理的格式,包括 ISO 8601、SQL-兼容的、传统的和其他的形式。DateStyle 参数可以指定日期输入的格式,MDY 是“月-日-年”,DMY 是“日-月-年”,YMD 是“年-月-日”。

下表显示了 date 类型可能的输入方式。、

例子

描述

1999-01-08

ISO 8601;任何模式下的1月8日(推荐格式)

January 8,1999

在任何 DateStyle 输入模式下都无歧义

1/8/1999

MDY 模式中的1月8日;DMY 模式中的8月1日

1/18/1999

MDY 模式中的1月18日;在其他模式中被拒绝

01/02/03

MDY 模式中的2003年1月2日;
DMY 模式中的2003年2月1日;
YMD 模式中的2001年2月3日

1999-Jan-08;
Jan-08-1999;
08-Jan-1999

任何模式下的1月8日

99-Jan-08

YMD 模式中的1月8日,否则错误

08-Jan-99
Jan-08-99

1月8日,除了在 YMD 模式中错误

19990108
990108

ISO 8601;任何模式中的1999年1月8日

1999.008

年和一年中的日子

J2451187

儒略日期

January 8, 99 BC

公元前99年

时间:当日时间类型是 time [ (p) ] without time zone 和 time [ (p) ] with time zone,只写 time 等效于 time without time zone。这些类型的有效输入由当日时间后面跟着可选的时区组成,时间类型中指定的日期会被忽略,除非使用了一个涉及到夏令时规则的时区,例如 America/New_York。time without time zone 中指定的时区也会被无声地忽略。

例子

描述

04:05:06.789

ISO 8601

04:05:06

ISO 8601

04:05

ISO 8601

040506

ISO 8601

04:05 AM

和 04:05 一样,AM 并不影响值

04:05 PM

和 16:05 一样,输入的小时必须 <= 12

04:05:06.789-8

ISO 8601

04:05:06-08:99

ISO 8601

04:05-08:00

ISO 8601

040506-08

ISO 8601

04:05:06 PST

缩写指定的时区

2003-04-12 04:05:06 America/New_York

全名指定的时区

2.2.6. 布尔类型

HGDB 提供标准的 SQL 类型 boolean。boolean 可以有多个状态:“true(真)”、“false(假)” 和第三种状态 “ unknown(未知)”,未知状态由 SQL 空值表示。

名字

存储字节

描述

boolean

1字节

状态为真或假

在 SQL 查询中,布尔常量可以表示为 SQL 关键字 TRUE、FALSE、NULL。但是语法分析程序不会把 NULL 自动理解为 boolean 类型,因为它可以是任何类型的,必要时可以将它显示转换为 boolean 类型:NULL::boolean。

boolean 类型的数据类型输入函数接受这些字符串表示“真”状态:true、yes、on、1;接受这些表示为“假”状态:false、no、off、0。这些字符串的唯一前缀也可以接受,例如 t 或 n。字符串前端或尾部的空格将被忽略,并且大小写不敏感。

boolean 类型的数据类型输出函数总是发出 t 或 f。

2.2.7. 枚举类型

枚举(enum)类型是由一个静态、值的有序集合构成的数据类型。枚举类型的一个例子可以是一周中的日期,或者一个数据的状态值集合。枚举类型可以使用 CREATE TYPE 命令创建。

例如创建并应用一个枚举类型:

highgo=# CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');
CREATE TYPE

highgo=# CREATE TABLE person ( 
  name text, 
  current_mood mood 
);
CREATE TABLE

highgo=# INSERT INTO person VALUES ('Moe', 'happy');
INSERT 0 1
highgo=# SELECT* FROM person WHERE current_mood='happy';
 name | current_mood 
------+--------------
 Moe  | happy
(1 行记录)

在排序的时候,一个枚举类型的值的排序是该类型被创建时所列出的值的顺序,比如上面创建的 mood 类型的排序为 sad、ok、happy。

尽管枚举类型的主要目的是用于值的静态集合,但也有方法在现有枚举类型中增加新值和重命名值。不可以从枚举类型中去除现有的值,也不能更改这些值的排序顺序,如果要那样做可以删除并且重建枚举类型。

例如创建并应用新的枚举类型 happiness:

highgo=# CREATE TYPE happiness AS ENUM ('happy', 'very happy', 'ecstatic');
CREATE TYPE

highgo=# CREATE TABLE holidays ( 
  highgo(# num_weeks integer, 
       highgo(# happiness happiness 
       highgo(# );
       CREATE TABLE

       highgo=# INSERT INTO holidays VALUES (4,'happy'),(6,'very happy'),(8,'ecstatic');
       INSERT 0 3

       highgo=# INSERT INTO holidays VALUES (2,'sad');
       错误:  对于枚举happiness的输入值无效: "sad"

       highgo=# SELECT person.name,holidays.num_weeks FROM person,holidays WHERE person.current_mood = holidays.happiness;
       错误:  操作符不存在: mood = happiness

每一种枚举数据类型都是独立的并且不能和其他枚举类型相比较。不同的枚举类型中即便存在相同的类型,它们之间也不能进行比较。如果你确实需要做这样的事情,可以写一个自定义的操作符或者在查询中加上显式造型:

highgo=# SELECT person.name,holidays.num_weeks,person.current_mood,holidays.happiness FROM person,holidays WHERE person.current_mood::text = holidays.happiness::text;
 name | num_weeks | current_mood | happiness 
------+-----------+--------------+-----------
 Moe  |         4 | happy        | happy
(1 行记录)

2.2.8. 数组类型

2.2.8.1. 数组类型定义和插入

HGDB 允许一个表中的列定义为变长多维数组,可以创建任何内建或用户定义的基类、枚举类型、组合类型或者域类型的数组。

一个数组数据类型可以通过在数组元素的数据类型名称后面加上方括号([])来命名。CREATE TABLE 的语法允许指定数组的确切大小,如果不进行指定,那么数据的长度和维度都不受限制。实际上,CREATE TABLE 中声明数组的尺寸或维度仅仅只是文档而已,它并不影响运行时的行为。

例如在创建表 grape 时将 taste 定义为长度为1的数组,将 info 定义为长度不限制的数组:

CREATE TABLE grape (taste text[1],info int[][]);

INSERT INTO grape VALUES ('{sweet}','{1,2,3}'),('{sour}','{4,5,6}');
INSERT INTO grape VALUES ('{sweet,sour,sweet_and_sour}');
INSERT INTO grape VALUES('{sweet}','{{1},{2}}');
INSERT INTO grape VALUES('{bad}','{0,0,0}');

还可以用关键词 ARRAY 定义一维数组。同前面一样,数组可以不指定尺寸,并且 HGDB 在任何情况下都不会强制尺寸限制。

CREATE TABLE grape_(info int ARRAY[4]);

INSERT INTO grape_ VALUES(ARRAY[10,20]);
INSERT INTO grape_ VALUES('{12,6}');

注意,插入多条多维数组时,多维数组的每一维都必须有相匹配的长度,不匹配会造成错误。

2.2.8.2. 访问数组

访问数组中的元素时,可以将数组下标写在方括号内,HGDB 默认数组下标从1开始。

highgo=# SELECT taste FROM grape WHERE info[1]=1;
  taste  
---------
 {sweet}
(1 行记录)

如果数组本身为空或者任何一个下标表达式为空,访问数组下标表达式将会返回空值。如果下标超过了数组边界,下标表达式也会返回空值(这种情况不会抛出错误)。相似地,使用错误的下标号引用一个数组会得到空值而不是错误。

2.2.8.3. 修改数组

数组可以作为一个数组值被整个替换,也可以在某一个元素上被更新。

UPDATE grape SET taste='{sweet_and_sour}' where taste='{sweet,sour,sweet_and_sour}';
UPDATE grape SET info='{100,0,0}' WHERE taste='{sweet}';
UPDATE grape SET info=ARRAY[0,100,0] WHERE taste='{sour}';
UPDATE grape SET info[1]=50,info[2]=50 WHERE taste='{sweet_and_sour}';
2.2.8.4. 在数组中搜索

要搜索数组中值的”存在“情况,可以用关键字 ANY 来实现。例如搜索 info 数组里面所有出现元素100的数据:

highgo=# SELECT* FROM grape WHERE '100'= ANY(info);
  taste  |   info    
---------+-----------
 {sweet} | {100,0,0}
 {sweet} | {100,0,0}
 {sour}  | {0,100,0}
(3 行记录)

如果存在一个数组的所有元素值都相同,可以用关键字 ALL 来进行搜索。例如搜索info数组中所有元素的值都为0的数据:

highgo=# SELECT* FROM grape WHERE '0'= ALL(info);
 taste |  info   
-------+---------
 {bad} | {0,0,0}
(1 行记录)

2.2.9. 其他类型

2.2.9.1. 几何类型

几何数据类型表示二维的空间物体。

名字

存储尺寸

表示

描述

point

16字节

平面上的点

(x,y)

line

32字节

无限长的线

{A,B,C}(A、B都不为0)

lseg

32字节

有限线段

((x1,y1),(x2,y2))

box

32字节

矩形框

((x1,y1),(x2,y2))

path

16+16n 字节

封闭路径(类似于多边形)

((x1,y1),…)

path

16+16n 字节

开放路径

[(x1,y1),…]

polygon

40+16n 字节

多边形(类似于封闭路径)

((x1,y1),…)

circle

24字节

<(x,y),r>(中心点和半径)

2.2.9.2. 网络地址类型

HGDB 提供用于存储 IPv4、IPv6 和 MAC 地址的数据类型。 用这些数据类型存储网络地址比用纯文本类型好,因为这些类型提供输入错误检查以及特殊的操作符和函数。

名字

存储尺寸

描述

cidr

7或19字节

IPv4 和 IPv6 网络

inet

7或19字节

IPv4 和 IPv6 主机以及网络

macaddr

6字节

MAC 地址

macaddr8

8 byte

MAC 地址(EUI-64 格式)

在对 inet 或者 cidr 数据类型进行排序的时候, IPv4 地址将总是排在 IPv6 地址前面,包括那些封装或者是映射在 IPv6 地址里 的 IPv4 地址,例如 ::10.2.3.4 或者 ::ffff::10.4.3.2。

2.2.9.3. 位串类型

位串就是一串 1 和 0 的串,它们可以用于存储和可视化位掩码。

名字

描述

bit(n)

定长

bit varying(n)

变长

n 是一个正整数,bit 类型的数据必须准确匹配长度 n,更短或更长的位串都会被拒绝;bit varying 数据是最长位数为 n 的变长类型。写一个没有长度的 bit 等效于 bit(1),没有长度的 bit varying 意味着没有长度限制。位串类型在输入时也需要用单引号包围。

2.2.9.4. 文本搜索类型

HGDB 提供两种数据类型:tsvector 和 tsquery,它们被设计用来支持全文搜索,全文搜索是一种在自然语言的文档集合中搜索以定位那些最匹配一个查询的文档的活动。

名字

描述

tsvector

tsvector 类型表示一个为文本搜索优化的形式下的文档,tsvector 的值是一个排序的可区分词位的列表。

tsquery

tsquery 类型表示一个文本查询,一个 tsquery 值存储用于搜索的词位,并且使用布尔操作符 &(AND),|(OR) 和 !(NOT) 来组合它们。

2.2.9.5. UUID类型

数据类型 uuid 存储由 RFC 4122、ISO/IEC 9834-8:2005 以及相关标准定义的通用唯一标识符(UUID),这种标识符是一个 128 位的量。

一个 UUID 被写成一个小写十六进制位的序列,该序列被连字符分隔成多个组:首先是一个 8 位组,接下来是三个 4 位组,最后是一个 12 位组。总共的 32 位(十六进制位)表示了 128 个二进制位,这是 UUID 类型的标准形式。

瀚高数据库也接受另一种输入形式:使用大写位、标准格式被花括号包围、忽略某些或者全部连字符、在任意 4 位组后面增加一个连字符。

格式

示例

标准形式

a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11

非标准形式

A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11
{a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11}
a0eebc999c0b4ef8bb6d6bb9bd380a11
a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11
{a0eebc99-9c0b4ef8-bb6d6bb9-bd380a11}

2.2.9.6. XML类型

xml 数据类型可以被用来存储 XML 数据。它比直接在一个 text 域中存储 XML 数据的优势在于,它会检查输入值的结构是否良好,并且有支持函数用于在其上执行类型安全的操作。

创建xml值:

要从字符数据中生成一个 xml 类型的值,可以使用函数 xmlparse。

XMLPARSE({DOCUMENT|CONTENT}value)

例如:

XMLPARSE (DOCUMENT '<?xml version="1.0"?><book><title>Manual</ 
          title><chapter>...</chapter></book>') 
XMLPARSE (CONTENT 'abc<foo>bar</foo><bar>foo</bar>')

然而根据 SQL 标准这是唯一将字符串转换为 XML 值的方法,HGDB 还有特有的语法:

xml'<foo>bar</foo>'
'<foo>bar</foo>'::xml

从 xml 产生一个字符串的逆操作可以使用函数 xmlserialize:

XMLSERIALIZE ( { DUCUMENT | CONTENT } value AS type )

type 可以是 character、character varying 或 text(或者其中之一的一个别名)。

2.2.9.7. JSON类型

JSON 数据类型是用来存储 JSON(JavaScript Object Notation)数据的。这种数据也可以被存储为 text,但是 JSON 数据类型的优势在于能强制要求每个被存储的值符合 JSON 规则,也有很多 JSON 相关的函数和操作符可以用于存储在这些数据类型中的数据。

HGDB 提供存储 JSON 数据的两种类型:json 和 jsonb。json 和 jsonb 数据类型接受几乎完全相同的值集合作为输入,主要的实际区别之一是效率。json 数据类型存储输入文本的精准拷贝,执行时需重新解析数据。jsonb 数据被存储在一种分解好的二进制格式中,输入慢,处理快,因为输入时需要做附加的转换,而在处理时不需要解析,jsonb 也支持索引,这也是一个令人瞩目的优势。除非特别需要,大多数应用应该更愿意把 JSON 数据存储为 jsonb。

JSON 输出简单标量和数组如下所示:

SELECT '5'::json;
SELECT '[1,2,"foo",null]'::json;
2.2.9.8. 组合类型

一个组合类型表示一行或一个记录的结构,它本质上就是一个域名和它们数据类型的列表。HGDB 允许把组合类型用在很多能用简单类型的地方。例如,一个表的一列可以被声明为一种组合类型。

2.2.9.8.1. 组合类型的定义

创建一个组合类型通过 CREATE TYPE 来完成,例如创建一个 complex 组合类型。

CREATE TYPE complex AS ( 
  r double precision, 
  i double precision 
);

该语法堪比 CREATE TABLE ,不过只能指定域名和类型,不能包括约束,注意 AS 关键字这里不能省略。

下面用创建的组合类型来创建表:

CREATE TABLE complex_(co complex);
INSERT INTO complex_ VALUES ('(3.1415926,2.71828)');
2.2.9.8.2. 组合类型的输入

要把一个组合值写作一个文字常量,将该域值封闭在圆括号中并且用逗号分隔他们。可以在任何域值周围放上双引号,并且如果该值域包含逗号或圆括号则必须这样做。

一个组合常量的一般格式如下:

'(val1,val2,...)'

例如 inventory_item 复合类型的一个合法值是这样的:

CREATE TYPE inventory_item AS ( 
  name text, 
  supplier_id integer, 
  price numeric 
);

'("fuzzy dice",42,1.99)'
2.2.9.8.3. 访问组合类型

要访问一个组合列的一个域,可以写成一个点和域的名称,为避免被认为是从一个表中选择一个域,因此需要用圆括号将组合列括起来。

假设用上面创建的 iventory_item 复合类型在表 on_hand 中创建了一个名为 item 的属性,可以写一个这样的查询语句:

SELECT (item).name FROM on_hand WHERE (item).price>9.99;

也可以将表名也表示到圆括号里面:

SELECT (on_hand.item).name FROM on_hand WHERE (on_hand.item).price>9.99;
2.2.9.9. 范围类型

范围类型是表达某种元素类型(称为范围的 subtype)的一个值的范围的数据类型。例如,timestamp 的范围可以被用来表达一个会议室被保留的时间范围,在这种情况下,数据类型是 tsrange(“timestamp range”的简写)而 timestamp 是 subtype。

HGDB 中带有以下内建范围类型:

• int4range — integer 的范围

• int8range — bigint 的范围

• numrange — numeric 的范围

• tsrange — 不带时区的 timestamp 的范围

• tstzrange — 带时区的 timestamp 的范围

• daterange — date 的范围

也可以通过 CREATE TYPE 来定义自己的范围类型。

范围类型的使用可以通过下面的例子来实现:

CREATE TABLE reservation (room int, during tsrange);
INSERT INTO reservation VALUES (1108,'[2010-01-01 14:30,2010-01-01 15:30]');

--包含
SELECT int4range(10,20)@>3;
--重叠
SELECT numrange(11.1,22.2)&&numrange(20.0,30.0);
--抽取上届
SELECT upper(int8range(15,25));
--计算交集
SELECT int4range(10,20)*int4range(15,25);
--范围为空吗?
SELECT isempty(numrange(1,5));

一个范围值的输入必须遵循下列模式之一:

  • (lower-bound,upper-bound)
  • (lower-bound,upper-bound]
  • [lower-bound,upper-bound)
  • [lower-bound,upper-bound]
  • empty

圆括号或方括号指示上下界是否为排除的或者包含的,圆括号 ’()‘ 为不包含,方括号 ‘[]’ 为包含。注意最后一个模式是 empty,它表示一个空范围(一个不包含点的范围)。

lower-bound 可以是作为 subtype 的合法输入的一个字符串,或者是空表示没有下界。同样,upper-bound 可以是作为 subtype 的合法输入的一个字符串,或者是空表示没有上界。一个范围的下界被忽略意味着所有小于上界的值都被包括在范围中,例如(,3]。 同样,如果范围的上界被忽略,那么所有比上界大的值都被包括在范围中。如果上下界都被忽略,该元素类型的所有值都被认为在该范围中。

2.2.9.10. 域类型

域是一种用户定义的数据类型,它基于另一种底层类型。根据需要,它可以有约束来限制其有效值为底层类型所允许值的一个子集。如果没有约束,它的行为就和底层类型一样——例如,任何适用于底层类型的操作符或函数都对该域类型有效。底层类型可以是任何内建或者用户定义的基础类型、枚举类型、数组类型、组合类型、范围类型或者另一个域。

例如,我们可以在整数之上创建一个域,它只接受正整数:

CREATE DOMAIN posint AS integer CHECK(VALUE>0);
CREATE TABLE mytable(id posint);
INSERT INTO mytable VALUES(1);
INSERT INTO mytable VALUES(-1);

如此第一条数据插入成功,第二条数据插入失败。

当底层类型的一个操作符或函数适用于一个域值时,域会被自动向下造型为底层类型。因此,mytable.id - 1 的结果会被认为是类型 integer 而不是 posint。

2.2.9.11. 对象标识符类型

对象标识符(OID)被 HGDB 用来在内部作为多个系统表的主键。 类型 oid 表示一个对象标识符。 也有多个 oid 的别名类型:regproc,regprocedure,regoper,regoperator,regclass,regtype,regrole,regnamespace,regconfig 和 regdictionary。

名字

引用

描述

值示例

oid

任意

数字形式的对象标识符

564182

regproc

pg_proc

函数名字

sum

regprocedure

pg_proc

带参数类型的函数

sum(int4)

regoper

pg_operator

操作符名字

+

regoperator

pg_operator

带参数类型的操作符

*(integer,integer) or -(NONE,integer)

regclass

pg_class

关系名字

pg_type

regtype

pg_type

数据类型名字

integer

regrole

pg_authid

角色名

smithee

regnamespace

pg_namespace

名字空间名称

pg_catalog

regconfig

pg_ts_config

文本搜索配置

english

regdictionary

pg_ts_dict

文本搜索字典

simple

2.2.9.12. pg_lsn类型

pg_lsn 数据类型可以被用来存储 LSN(日志序列号)数据,LSN 是一个指向 WAL 中的位置的指针。这个类型是 XLogRecPtr 的一种表达并且是 HGDB 的一种内部系统类型。

在内部,一个 LSN 是一个 64 位整数,表示在预写式日志流中的一个字节位置。它被打印成两个最高 8 位的十六进制数,中间用斜线分隔,例如 16/B374D848。pg_lsn 类型支持标准的比较操作符,如 = 和 >。两个 LSN 可以用 - 操作符做减法, 结果将是分隔两个预写式日志位置的字节数。

2.2.9.13. 伪类型

HGDB 类型系统包含了一些特殊目的的项,它们被统称为伪类型。一个伪类型不能被用作一个列的数据类型,但是它可以被用来定义一个函数的参数或者结果类型。每一种可用的伪类型都有其可以发挥作用的情况,这些情况的特点是一个函数的行为并不能符合于简单使用或者返回一种特定 SQL 数据类型的值。下表列出了现有的伪类型。

名字

描述

any

表示一个函数可以接受任意输入数据类型

anyelement

表示一个函数可以接受任意数据类型

anyarray

表示一个函数可以接受任意数组数据类型

anynonarray

表示一个函数可以接受任意非数组数据类型

anyenum

表示一个函数可以接受任意枚举数据类型

anyrange

表示一个函数可以接受任意范围数据类型

cstring

表示一个函数接受或者返回一个非空结尾的C字符

internal

表示一个函数接受或返回一个服务器内部数据类型

language_handler

一个被声明为返回 language_handler 的过程语言调用处理器

fdw_handler

一个被声明为返回 fdw_handler 的外部数据包装器处理器

index_am_handler

一个被声明为返回 index_am_handler 索引访问方法处理器

tsm_handler

一个被声明为返回 tsm_handler 的表采样方法处理器

record

表示一个接受或者返回一个为未指定的行类型的函数

trigger

一个被声明为返回 trigger 的触发器函数

event_trigger

一个被声明为返回 event_trigger 的事件触发器函数

pg_ddl_command

表示一种对事件触发器可用的 DDL 命令的表达

void

表示一个函数不返回值

unknown

表示一种还未被解析的类型,例如一个未修饰的字符文本

opaque

一种已被废弃的类型名称,以前它用于实现以上的很多种目的

2.3. 修改数据表

2.3.1. 添加一列

ALTER TABLE 模式名.表名 ADD 字段名 列类型;

2.3.2. 修改类型

只有当列中的每一个项都能通过一个隐式造型转换为新的类型时该操作才能成功。

HGDB 将尝试把列的默认值转换为新类型,其他涉及到该列的任何约束也是一样。但是这些转换可能失败或者产生奇特的结果,因此最好在修改类型之前先删除该列上所有的约束,修改完类型后再重新加上相应修改过的约束。

ALTER TABLE 模式名.表名 ALTER COLUMN 列名 TYPE 列类型;

2.3.3. 修改列名

ALTER TABLE 模式名.表名 RENAME COLUMN 旧列名 TO 新列名;

2.3.4. 删除指定列

ALTER TABLE 模式名.表名 DROP COLUMN 列名;

2.3.5. 修改表名

ALTER TABLE 模式名.表名 RENAME TO 新表名;

2.4. 删除数据表

DROP TABLE [if exists] 模式名.表名;

3. 数据操作

3.1. 插入数据

3.1.1. 基本方式

INSERT INTO 模式名.表名(字段1,字段2,.....字段n) VALUES(值1,值2,.....值n);

例:

insert into test.student("id","name","birthday") values(5,'小兰','1990-01-01');

3.1.2. 批量插入

INSERT INTO 模式名.表名(字段1,字段2,.....字段n) VALUES(值1,值2,.....值n),(值1,值2,.....值n),(值1,值2,.....值n);

3.1.3. 省略列名

INSERT INTO 模式名.表名 VALUES(值1,值2,.....值n),(值1,值2,.....值n),(值1,值2,.....值n);

3.2. 修改数据

UPDATE 模式名.表名 SET 字段1=值1,字段2=值2 [WHERE 条件字段 = 值];

3.3. 删除数据

DELETE FROM 模式名.表名 [WHERE 字段=值2];

3.4. 查询数据

3.4.1. 简单查询

3.4.1.1. 查询所有列

SELECT * FROM 模式名.表名;

3.4.1.2. 查询部分列

select 列1名,列2名,...列n名 from 模式名.表名;

3.4.1.3. 去重

SELECT DISTINCT 列名 FROM 模式名.表名;

3.4.1.4. 四则运算

SELECT 列(四则) FROM 模式名.表名;

3.4.1.5. 空值处理

ifnull(列,默认值)

3.4.1.6. 别名

select 列 [as] 别名 from 模式名.表名;

3.4.2. 条件查询

3.4.2.1. 关系运算符

= >= <= != <>

3.4.2.2. 逻辑运算符

and or

3.4.2.3. 范围关键字
  • 字段 in (值1,值2,....值n) 表示字段=集合中的任何一个都可以
  • 字段 not in (值1,值2,....值n) 表示字段不在集合中才可以
  • 字段 between 开始值 and 结束值 查询的字段的值要在 [开始 , 结束]
  • 字段 not between 开始值 and 结束值 查询的字段的不值要在 [开始 , 结束]
3.4.2.4. null关键字
  • is null 为空
  • is not null 不为null
3.4.2.5. 模糊匹配

like

3.4.3. 高级查询

  1. 排序: order by 列 [asc|desc]
  2. 截取: limit 开始,几个
  3. 聚合函数: count(列)
  4. 分组: group by 列
  5. 过滤: having 过滤条件
  6. 普通条件: where

高级查询的顺序:

select 聚合函数() from 表 [where 条件] [group by 分组] [having 过滤] [order by 排序] [limit 截取]

4. 数据库约束

  1. 主键约束:primary key
  2. 唯一约束:unique
  3. 非空约束:not null
  4. 默认值:default(默认值)
  1. 外键约束:[constraint 约束名: xxx_fk] foreign key (列名) references 主表(主键)

5. 多表查询

  1. 内连接:(inner) join
  2. 左外连接:left (outer) join
  3. 右外连接:right (outer) join
  4. 子查询
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐