Ⅱ-数据类型-Ⅰ

以使用CREATE TYPE命令为 PostgreSQL增加新的数据类型


表1
表2

数字类型

1. 整数类型——smallint、integer、bigint

2.任意精度数字——numeric(precision,scale)

scale是到小数部分的位数,precision是整个数字里全部位的数目

numeric类型允许特殊值NaN, 表示“不是一个数字”。任何在 NaN上面的操作都生成另外一个NaN。 如果在 SQL 命令里把这些值当作一个常量写,你必须在其周围放上单引号,例如UPDATE table SET x = 'NaN'。在输入时,字串NaN被识别为大小写无关

3.浮点类型——real ,double precision

Infinity——正无穷大

-Infinity——负无穷大

NaN ——不是一个数字

如果在 SQL 命令里把这些数值当作常量写,必须在它们周围放上单引号,如UPDATE table SET x = '-Infinity'。 在输入时,这些串是以大小写无关的方式识别的。


4.序数类型——创建自动增量列的PostgreSQL特定方法

smallserial、serial和bigserial类型不是真正的类型,它们只是为了创建唯一标识符列而存在的方便符号

CREATE TABLEtablename(colnameSERIAL);

<=>

CREATE SEQUENCE tablename_colname_seq;

CREATE TABLE tablename (

colnameinteger NOT NULL DEFAULT nextval('tablename_colname_seq'));

ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;


货币类型

money类型存储固定小数精度的货币数字

可接受的输入格式——整数和浮点数文字,以及常用的货币格式,如'$1,000.00'。

 输出通常是最后一种形式,但和区域相关。

执行整数值对money值的除法时,将小数部分截断为零。为了得到一个四舍五入的结果,除以一个浮点值,或者在除法计算之前将 money值转换为numeric,然后返回到money。 (倾向于后者,可以避免精确度损失的风险。) 当一个money值被另一个money值除时,结果是double precision(即一个纯数字,而不是金额),在除法中货币单位被约掉了。


字符类型

character(n), char(n)——定长,空格填充
character varying(n), varchar(n)——有限制的变长

text——无限变长

"char"——单字节内部类型,只用了一个字节的存储空间。它在系统内部用于系统目录当做简化的枚举类型用

name——用于对象名的内部类型,用于在内部系统目录中存储标识符并且不是给一般用户使用


二进制数据类型

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


日期/时间类型

日期根据公历来计算


日期/时间 类型

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

1. 输入

DateStyle参数设置为MDY,就是选择“月-日-年”的解释,设置为DMY就是 “日-月-年”,而YMD是 “年-月-日”

任何日期或者时间的文字输入需要由单引号包围


日期输入方式


时间输入方式


时区输入

时间戳类型的有效输入由一个日期和时间的串接组成,后面跟着一个可选的时区,一个可选的AD或者BC

1999-01-08 04:05:06


特殊日期/时间输入

SQL-兼容的函数可以被用来为相应的数据类型获得当前时间值: CURRENT_DATE、CURRENT_TIME、 CURRENT_TIMESTAMP、LOCALTIME、 LOCALTIMESTAMP

2. 输出


输出风格


日期顺序习惯

日期/时间风格可以由用户使用SET datestyle命令选取,在postgresql.conf配置文件里的参数DateStyle设置或者在服务器或客户端的PGDATESTYLE环境变量里设置。

格式化函数to_char(见第 9.8 节)也可以作为一个更灵活的方式来格式化日期/时间输出。

3. 时区

4.间隔输入——interval

[@]quantityunit[quantityunit...] [direction]

quantity是一个数字(很可能是有符号的); unit是毫秒、 millisecond、second、 minute、hour、day、 week、month、year、 decade、century、millennium 或者缩写或者这些单位的复数; direction可以是ago或者为空。At符号(@)是一个可选的噪声

ago对所有域求反。如果IntervalStyle被设置为postgres_verbose,该语法也被用于间隔输出。

也可以被写成 ISO 8601 时间间隔:

quantityunit [quantityunit...] [T [quantityunit...]]

必须以一个P开始,并且可以包括一个引入当日时间单位的T。可用的单位缩写在表 ISO 8601 间隔单位缩写中给出。单位可以被忽略,并且可以以任何顺序指定,但是小于一天的单位必须出现在T之后。特别地,M的含义取决于它出现在T之前还是之后。


ISO 8601 间隔单位缩写

如果使用替代格式:

P [years-months-days] [Thours:minutes:seconds]

必须以P开始,并且一个T分隔间隔的日期和时间部分。其值按照类似于 ISO 8601日期的数字给出


间隔输入

5. 间隔输出

间隔类型的输出格式可以被设置为四种风格之一:sql_standard、postgres、postgres_verbose或iso_8601,设置方法使用SET intervalstyle命令。默认值为postgres格式。


 间隔输出风格例子

布尔类型——boolean

boolean可以有多个状态:“true(真)”、“false(假)”和第三种状态“unknown(未知)”,未知状态由SQL空值表示

“真”状态的有效文字值是:

TRUE

't'

'true'

'y'

'yes'

'on'

'1'

“假状态”:

FALSE

'f'

'false'

'n'

'no'

'off'

'0'


枚举类型——enum

是由一个静态、值的有序集合构成的数据类型

1. 声明

使用CREATE TYPE命令创建

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

在表和函数定义中使用

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

CREATE TABLE person (

    name text,

    current_mood mood

);

INSERT INTO person VALUES ('Moe', 'happy');

SELECT * FROM person WHERE current_mood = 'happy';

2.排序 

一个枚举类型的值的排序是该类型被创建时所列出的值的顺序。枚举类型的所有标准的比较操作符以及相关聚集函数都被支持

3.类型安全性

每一种枚举数据类型都是独立的并且不能和其他枚举类型相比较。

可以写一个自定义的操作符或者在查询中加上显式类型

SELECT person.name, holidays.num_weeks FROM person, holidays

  WHERE person.current_mood::text = holidays.happiness::text;

4. 实现细节

枚举标签是大小写敏感的,因此'happy'是不同于'HAPPY'的。标签内的空白也是有效的


几何类型

表示二维的空间物体


几何类型

1. 点

2. 线

由线性方程Ax + By + C = 0 表示,其中AB都不为零

{A,B,C}

还可以用下列任一形式输入

[ (x1,y1) , (x2,y2) ]

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

 (x1,y1) , (x2,y2)

x1,y1,x2,y2

3.线段

线段用一对线段的端点来表示,lseg类型的值用下面的语法声明

[ (x1,y1) , (x2,y2) ]

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

 (x1,y1) , (x2,y2)

x1,y1,x2,y2

其中(x1,y1) 和 (x2,y2) 是线段的端点。

线段使用第一种语法输出。

4.方框

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

 (x1,y1) , (x2,y2)

x1,y1,x2,y2

其中(x1,y1) 和 (x2,y2) 是方框的对角点。

方框使用第二种语法输出。

在输入时可以提供任意两个对角,但是值将根据需要被按顺序记录为右上角和左下角。

5.路径

径可能是开放的,也就是认为列表中第一个点和最后一个点没有被连接起来;也可能是封闭的,这时认为第一个和最后一个点被连接起来

[ (x1,y1) , ... , (xn,yn) ]

( (x1,y1) , ... , (xn,yn) ) 

 (x1,y1) , ... , (xn,yn)

 (x1,y1, ... ,xn,yn)

x1,y1, ... ,xn,yn

其中的点是组成路径的线段的端点。方括弧([])表示一个开放的路径,圆括弧(())表示一个封闭的路径。如第三种到第五种语法所示,当最外面的圆括号被忽略时,路径将被假定为封闭。

路径的输出使用第一种或第二种语法。

6.多边形

( (x1,y1) , ... , (xn,yn) ) 

 (x1,y1) , ... , (xn,yn

 (x1,y1, ... ,xn,yn)

x1,y1, ... ,xn,yn

点是组成多边形边界的线段的端点。

多边形的输出使用第一种语法。

7.圆

< (x,y) ,r>( (x,y) ,r

 (x,y) ,r

x,y,r

圆的输出用第一种语法


网络地址类型


网络地址类型

位串类型

位串就是一串 1 和 0 的串。它们可以用于存储和可视化位掩码。我们有两种类型的 SQL 位类型:bit(n)和bit varying(n),其中 n是一个正整数

CREATE TABLE test (a BIT(3), b BIT VARYING(5));

INSERT INTO test VALUES (B'101', B'00');

INSERT INTO test VALUES (B'10', B'101');

ERROR: bit string length 2 does not match type bit(3)

INSERT INTO test VALUES (B'10'::bit(3), B'101');

SELECT * FROM test; 

 a | b

-----+-----

101 | 00

100 | 101


文本搜索类型

全文搜索是一种在自然语言的文档集合中搜索以定位那些最匹配一个查询的文档的活动。tsvector类型表示一个为文本搜索优化的形式下的文档,tsquery类型表示一个文本查询

1. tsvector

2.tsquery


UUID类型

由RFC 4122、ISO/IEC 9834-8:2005以及相关标准定义的通用唯一标识符(UUID)


XML类型

1.创建xml值

函数xmlparse——从字符数据中生成一个xml类型的值

XMLPARSE ( { DOCUMENT | CONTENT }value)

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

xml '<foo>bar</foo>'

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

//PostgreSQL特有的语法

函数xmlserialize——从xml产生一个字符串

XMLSERIALIZE ( { DOCUMENT | CONTENT }value AS type)

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

2.编码处理

XML数据在内部是以UTF-8处理的

3.访问XML值


JSON类型

两种 JSON 数据类型:json 和 jsonb。它们 几乎接受完全相同的值集合作为输入

json数据类型存储输入文本的精准拷贝,处理函数必须在每 次执行时必须重新解析该数据。jsonb数据被存储在一种分解好的 二进制格式中,它在输入时要稍慢一些,因为需要做附加的转换。但在处理时要快很多,因为不需要解析。jsonb也支持索引


JSON 基本类型和相应的PostgreSQL类型

-- 简单标量/基本值

-- 基本值可以是数字、带引号的字符串、true、false或者null

SELECT '5'::json;

-- 有零个或者更多元素的数组(元素不需要为同一类型)

SELECT '[1, 2, "foo", null]'::json;

-- 包含键值对的对象

-- 注意对象键必须总是带引号的字符串

SELECT '{"bar": "baz", "balance": 7.77, "active": false}'::json;

-- 数组和对象可以被任意嵌套

SELECT '{"foo": [true, "bar"], "tags": {"a": 1, "b": null}}'::json;

理想情况下,JSON 文档应该每个表示 一个原子数据,业务规则命令不会进一步把它们划分成更小的可独立修 改的数据

1. jsonb测试包含

SELECT '["foo", "bar"]'::jsonb @> '"bar"'::jsonb;


数组

1.数组类型的定义

CREATE TABLE sal_emp (

    name            text,

    pay_by_quarter  integer[],

    schedule        text[][]

);

使用关键词ARRAY,可以用来定义一维数组

pay_by_quarter integer ARRAY

2.数组值输入

一个数组常量的一般格式如下

'{val1 delim val2 delim ... }'

delim是类型的定界符,在PostgreSQL发行提供的标准数据类型中,所有的都使用一个逗号(,),除了类型box使用一个分号(;)

val可以是数组元素类型的一个常量,也可以是一个子数组

3.访问数组

PostgreSQL为数组使用了一种从1开始的编号习惯

访问一个元素——pay_by_quarter[1]

任意矩形切片或者子数组——schedule[1:2][1:1] ,schedule[1:2][2],schedule[:][2:]

其中任何只有一个数字(无冒号)的维度被视作是从1到指定的数字

缺失的 边界会被数组下标的上下限所替代

array_dims(schedule)——获得当前数组维度

array_upper(schedule, 1)——数组的上界

array_lower(schedule, 1)——数组的下界

array_length(schedule, 1)——数组维度的长度

cardinality(schedule)——数组在所有维度上的元素总数

4.修改数组

update——被替换/更新

新的数组值可以通过串接操作符||构建

SELECT ARRAY[5,6] || ARRAY[[1,2],[3,4]];

      ?column?

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

{{5,6},{1,2},{3,4}}

(1 row)

把一个单独的元素加入到一个一维数组的开头或末尾;一个N维数组被放在另一个N+1维数组的前面或者后面则相似

1 || '[0:1]={2,3}'::int[]

ARRAY[1,2] || 3

使用函数array_prepend、array_append或array_cat构建。前两个函数仅支持一维数组,但array_cat支持多维数组

SELECT array_prepend(1, ARRAY[2,3]);

array_prepend

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

{1,2,3}

(1 row)

SELECT array_append(ARRAY[1,2], 3);

array_append

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

{1,2,3}

(1 row)

SELECT array_cat(ARRAY[1,2], ARRAY[3,4]);

array_cat

-----------

{1,2,3,4}

(1 row)

SELECT array_cat(ARRAY[[1,2],[3,4]], ARRAY[5,6]);

      array_cat

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

{{1,2},{3,4},{5,6}}

(1 row)

5.在数组中搜索

SELECT * FROM sal_emp WHERE 10000 = ANY (pay_by_quarter);

查找所有元素值都为10000的数组所在的行:

SELECT * FROM sal_emp WHERE 10000 = ALL (pay_by_quarter);

generate_subscripts函数也可以用来完成类似的查找

SELECT * FROM

  (SELECT pay_by_quarter,

          generate_subscripts(pay_by_quarter, 1) AS s

      FROM sal_emp) AS foo

WHERE pay_by_quarter[s] = 10000;

使用&&操作符来搜索一个数组,它会检查左操作数是否与右操作数重叠

SELECT * FROM sal_emp WHERE pay_by_quarter && ARRAY[10000];

array_position和array_positions在一个 数组中搜索特定值。前者返回值在数组中第一次出现的位置的下标。后者返回一个数组, 其中有该值在数组中的所有出现位置的下标

SELECT array_position(ARRAY['sun','mon','tue','wed','thu','fri','sat'], 'mon');

array_positions

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

2

SELECT array_positions(ARRAY[1, 4, 3, 1, 3, 4, 2, 1], 1);

array_positions

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

{1,4,8}


6.数组输入和输出语法



©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,104评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,816评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,697评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,836评论 1 298
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,851评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,441评论 1 310
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,992评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,899评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,457评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,529评论 3 341
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,664评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,346评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,025评论 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,511评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,611评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,081评论 3 377
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,675评论 2 359

推荐阅读更多精彩内容