1. 模式操作
1.1. 创建数据库
CREATE DATABASE 数据库名;
1.2. 删除数据库
drop database 数据库名;
1.3. 创建用户
要创建一个角色,可以使用 CREATE ROLE
命令:
CREATE USER
和 CREATE 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日; |
1999-Jan-08; | 任何模式下的1月8日 |
99-Jan-08 | YMD 模式中的1月8日,否则错误 |
08-Jan-99 | 1月8日,除了在 YMD 模式中错误 |
19990108 | 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 TYPEhighgo=# CREATE TABLE person ( name text, current_mood mood );CREATE TABLEhighgo=# INSERT INTO person VALUES ('Moe', 'happy');INSERT 0 1highgo=# 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 TYPEhighgo=# CREATE TABLE holidays ( highgo(# num_weeks integer,highgo(# happiness happinesshighgo(# ); 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字节 | 圆 | (中心点和半径) |
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 |
2.2.9.6. XML类型
xml 数据类型可以被用来存储 XML 数据。它比直接在一个 text 域中存储 XML 数据的优势在于,它会检查输入值的结构是否良好,并且有支持函数用于在其上执行类型安全的操作。
创建xml值:
要从字符数据中生成一个 xml 类型的值,可以使用函数 xmlparse。
XMLPARSE({DOCUMENT|CONTENT}value)
例如:
XMLPARSE (DOCUMENT 'Manual ...') XMLPARSE (CONTENT 'abcbarfoo')
然而根据 SQL 标准这是唯一将字符串转换为 XML 值的方法,HGDB 还有特有的语法:
xml'bar''bar'::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. 高级查询
- 排序: order by 列 [asc|desc]
- 截取: limit 开始,几个
- 聚合函数: count(列)
- 分组: group by 列
- 过滤: having 过滤条件
- 普通条件: where
高级查询的顺序:
select 聚合函数() from 表 [where 条件] [group by 分组] [having 过滤] [order by 排序] [limit 截取]
4. 数据库约束
- 主键约束:
primary key
- 唯一约束:
unique
- 非空约束:
not null
- 默认值:
default(默认值)
- 外键约束:
[constraint 约束名: xxx_fk] foreign key (列名) references 主表(主键)
5. 多表查询
- 内连接:(inner) join
- 左外连接:left (outer) join
- 右外连接:right (outer) join
- 子查询