数值类型由两个字节,4字节和8字节的整数,4字节和8字节的浮点数和可选精度的小数。下表列出了可用的类型。 www.yiibai.com
Name | Storage Size | Description | Range |
---|---|---|---|
int2 | 2 bytes | small-range integer | -32768 to +32767 |
int4 | 4 bytes | typical choice for integer | -2147483648 to +2147483647 |
int8 | 8 bytes | large-range integer | -9223372036854775808 to 9223372036854775807 |
decimal | variable | user-specified precision,exact | up to 131072 digits before the decimal point; up to 16383 digits after the decimal point |
float4 | 4 bytes | variable-precision,inexact | 6 decimal digits precision |
float8 | 8 bytes | variable-precision,inexact | 15 decimal digits precision |
serial2 | 2 bytes | small autoincrementing integer | 1 to 32767 |
serial4 | 4 bytes | autoincrementing integer | 1 to 2147483647 |
serial8 | 8 bytes | large autoincrementing integer | 1 to 9223372036854775807 |
名字 | 存储空间 | 描述 | 取值区间 |
---|---|---|---|
smallint |
2 字节 | 小整数 | -32768 到 +32767 |
integer |
4 字节 | 常用的整数 | -2147483648 到 +2147483647 |
bigint |
8 字节 | 大整数 | -9223372036854775808 到 9223372036854775807 |
decimal |
变长 | 用户定义精度,可以精确地表示小数 | 无限制 |
numeric |
变长 | 用户定义精度,可以精确地表示小数 | 无限制 |
real |
4 字节 | 精度可变,不能精确地表示小数 | 精度是6个十进制位 |
double precision |
8 字节 | 精度可变,不能精确地表示小数 | 精度是15个十进制位 |
serial |
4 字节 | 小范围的自增整数 | 大范围的自增整数 |
bigserial |
8 字节 | 大范围的自增整数 | 1 到 9223372036854775807 |
类型 smallint
、integer
和 bigint
只能保存整数,也就是没有小数部分的数字。如果试图在一个整数类型中保存一个超过它能够表示的值范围的整数,数据库将会报错。
常用的类型是integer
,因为它提供了在表示范围、存储空间和性能之间的最佳平衡。只有在磁盘空间紧张的情况下才使用 smallint
。只有在 integer
太小的时候才使用 bigint
,因为在进行数学运算时,interger类型的数据bigint类型的数据要快。
SQL标准只定义了整数类型 integer
(或int
)、smallint``和``bigint
。
numeric
类型最多能存储有1000个数字位的数字并且能进行准确的数值计算。它主要用于需要准确地表示数字的场合,如货币金额。不过,对numeric
类型进行算术运算比整数类型和浮点类型要慢很多。
numeric
类型有两个术语,分别是标度和精度。numeric``类型的
标度(scale)是到小数点右边所有小数位的个数, numeric
的精度(precision)是所有数字位的个数,因例如, 23.5141 的精度是6而标度为4。可以认为整数的标度是零。
numeric
类型的最大精度和最大标度都是可以配置的。可以用下面的语法定义一个numeric类型:
(1)NUMERIC(*precision*
, *scale*
)
(2)NUMERIC(*precision*
)
(3)NUMERIC
精度必须为正数,标度可以为零或者正数。在上面的第二种语法中没有指定标度,则系统会将标度设为0,所以NUMERIC(precision,0)``和
NUMERIC(`precision)是等价的。第三种类型的语法没有指定精度和标度,则这种类型的列可以接受任意精度和标度的
numeric数据(在系统能表示的最大精度范围内),而不会对输入的数据进行精度或标度的变换。如果一个列被定义成
numeric类型而且指定了标度,那么输入的数据将被强制转换成这个标度(如果它的标度比定义列的
numeric``的标度大),进行标度转换时的规则是四舍五入。如果输入的数据进行标度转换后得到的数据在小数点左边的数据位的个数超过了列的类型的精度减去标度的差,系统将会报告类似下面的错误:```
`错误: numeric
类型数据溢出。```
`细节: precision
为3, scale
为3
的数必须被四舍五入成小于1
的数。```
` ``下面是一个实例:```
create table test ( col1 numeric(3,3));
insert into test values(0.5678);
insert into test values(0.5671);
insert into test values ( 1.4);
`错误: numeric
类型数据溢出。```
`细节: precision
为3, scale
为3
的数必须被四舍五入成小于1
的数。```
=>select * from test;
col1
-------
0.568
0.567
`(2 rows)```
numeric
类型接受一个特殊的值 “NaN``”
,它的意思是“不是一个数字"。任何在 NaN
上面的操作都生成另外一个 NaN
。 如果在 SQL 命令里把这些值当作一个常量写,必须把它用单引号引起来,比如 UPDATE table SET x = 'NaN'
。在输入时,”NaN”的大小写无关紧要。
**注意:**在其它的数据库中,NaN和任何的数值数据都不相等,两个NaN也是不相等的,在postgresSQL中,为了索引实现的方便,NaN被看成大于或等于所有非NaN的数值。
类型 decimal
和numeric
是等价的,两种类型都是SQL标准定义的,SQL标准要求numeric的默认精度应该是0,PostgreSQL没有执行这个规则,为了增强程序的移植性,最好同时指定numeric的精度和标度。
数据类型 real
和 double precision
表示不准确的变精度的数字。这些类型实现了IEEE 标准754二进制浮点数算术(分别对应单精度和双精度)。
不准确的意思是一些数值不能准确地用real和double precision``表示,
存储在数据库里的只是它们的近似值。如果要求准确地保存某些数值(比如计算货币金额),应使用 numeric
类型。另外,比较两个浮点数是否相等时,可能会得到意想不到的结果。
通常,real
类型的表示的数值范围是至少-1E+37到+1E+37,精度至少是6位小数。double precision
类型表示的范围通常是-1E+308到+1E+308 ,精度是至少15位小数。太大或者太小的数值都会导致错误。如果输入数据的精度太高,会被约成可以被接受的精度。太接近零的数字,如果和0的内部表示形式一样,会产生下溢(underflow)的错误。
浮点类型还有几个特殊值:
Infinity`
`-Infinity`
`NaN
这些值分别表示 IEEE 754标准中的特殊值"正无穷大",“负无穷大”, 以及"不是一个数字"。如果在 SQL 命令里把这些数值当作常量写,必须在它们用单引号引起来,例如UPDATE table SET x = 'Infinity'
。 输入时,这些值的大小写无关紧要。
**注意:**IEEE 754标准要求NaN和任何的数值数据都不相等,两个NaN也是不相等的,在postgresSQL中,为了索引实现的方便,NaN被看成大于或等于所有非NaN的数值。
PostgreSQL 还支持 SQL 标准中定义的类型float
和float(*p*)
。*p*
定义以二进制位表示的最低可以接受的精度,p的取值在1到53之间。实际上,如果p的取值在1到24之间,float(*p*)
被看成是real类型,如果p的取值在25到53之间,float(*p*)
被看成是double precision``类型。不带精度的
float被看成是`double precision``类型。```
serial
和 bigserial
并不是真正的数据类型,只是为了可以给表中的数据行设置一个唯一的标识。它类似其它一些数据库中的 AUTO_INCREMENT
属性。使用它们的方法如下:
CREATE TABLE *tablename*
(
*colname*
SERIAL
);
上面的命令实际上上等价于下面的两条命令:
CREATE SEQUENCE *tablename*
_*colname*
_seq;
CREATE TABLE *tablename*
(
*colname*
integer DEFAULT nextval(’*tablename*
_*colname*
_seq’) NOT NULL
);
上面的命令在表中创建了一个类型为无符号整数的列,该列与一个序列对象相关联,这个序列对象的初始值是1, 表中每插入一条新的记录,该序列的值会自动加一,在向表中插入数据时,INSERT命令不要为该列指定数据,或者指定它的值为DEFAULT。
下面是一个实例:
create table test3 ( product_id serial, name char(5));
insert into test3(name) values(‘pen’);
insert into test3(name) values(‘car’);
insert into test3 values(DEFAULT, ‘bike’);
=>select * from test3;
product_id | name
------------±------
1 | pen
2 | car
3 | bike
(3 rows)
**注意:**insert命令中一定不要为serial或bigserial类型的列指定一个不是DEFAULT的值,因为对于这样的命令系统是不会报错的,会导致serial或bigserial类型的列上的数值出现混乱。
货币类型存储的货币金额与一个固定的分数精度。可以转换为金钱的数字,int和bigint数据类型的值。不推荐使用浮点数来处理金钱的潜力,由于舍入误差。
Name | Storage Size | Description | Range |
---|---|---|---|
money | 8 bytes | currency amount | -92233720368547758.08 to +92233720368547758.07 |
下表列出了可在PostgreSQL通用字符类型。
名称 | 描述 |
---|---|
varchar(n) | variable-length with limit |
char(n) | fixed-length, blank padded |
text | variable unlimited length |
名字 | 描述 |
---|---|
character varying(*n*) , varchar(*n*) |
变长,最大长度有限制 |
character(*n*) , char(*n*) |
定长, 不足补空白 |
text |
变长,最大长度没有限制 |
如果明确将把一个数值转换成character(*n*)
或者 character varying(*n*)``类型
,如果转换以后的字符串的长度超过n,那么它将被自动截断成长度为n的字符串,系统不会报错(这也是SQL标准要求的)。
char(*n*)
和 varchar(*n*)
分别是 character(*n*)
和character varying(*n*)
的别名。没有定义长度的character
等同于 character(1)
。没有定义长度的character varying
类型接受任意长度的字符串,这是PostgreSQL的扩展特性。
bytea数据类型允许存储二进制字符串,如下面的表格中说明。
Name | Storage Size | Description |
---|---|---|
bytea | 1 or 4 bytes plus the actual binary string | variable-length binary string |
二进制字符串是一个字节数值的序列。SQL 标准定义了一种不同的二进制字符串类型,叫做 BLOB
或者 BINARY LARGE OBJECT``,
其输入格式和 bytea
不同,但是提供的函数和操作符大多一样。``bytea``类型数据的具体含义由应用程序自己决定,数据库也提供了和普通文本字符串的处理方式类似的方法来对``bytea``类型数据进行输入和输出。
PostgreSQL支持全套的SQL日期和时间类型,列于下表。根据公历日期计算。在这里,所有的类型有日期类型以外,其分辨率为day1微秒/14位的解析度。
Name | Storage Size | Description | Low Value | High Value |
---|---|---|---|---|
timestamp [§] [without time zone ] | 8 bytes | both date and time (no time zone) | 4713 BC | 294276 AD |
timestamp [§ ] with time zone | 8 bytes | both date and time, with time zone | 4713 BC | 294276 AD |
date | 4 bytes | date (no time of day) | 4713 BC | 5874897 AD |
time [ §] [ without time zone ] | 8 bytes | time of day (no date) | 00:00:00 | 24:00:00 |
time [ §] with time zone | 12 bytes | times of day only, with time zone | 00:00:00+1459 | 24:00:00-1459 |
interval [fields ] [§ ] | 12 bytes | time interval | -178000000 years | 178000000 years |
time`、`timestamp` 和`interval`可以定义精度值`*p*`,这个精度值定义用来表示秒的小数位的个数,默认的情况下,没有精度限制。对于`timestamp`和`interval``,``p``的取值范围是``0``到``6``(实际的精度可能小于``6``)。`对于`time``,``p``的取值范围是``0``到``10``。
类型time with time zone
是SQL标准定义的,这个类型有些多余。在大多数情况下,date
、time
、timestamp without time zone
和 timestamp with time zone
的组合就能满足任何应用需求。
类型 abstime
和reltime
是低分辨率时间类型,它们是数据库内部使用的类型,在应用程序里面不应该使用这两个类型。
时间输入
例子 | 描述 |
---|---|
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:00 | 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 |
带全称的时区 |
可以在 文件postgresql.conf
里设置配置参数 timezone,还可以用下面的方法来设置时区:
如果文件postgresql.conf 里没有设置timezone
,服务器试图使用服务器主机上的操作系统环境变量TZ的值作为服务器的默认时区。 如果没有定义TZ,或者TZ的值是 PostgreSQL 无法识别的时区, 那么服务器将通过检查C 库函数 localtime()
的行为确定来操作系统的默认时区(如果postgresql.conf 里没有设置参数log_timezone``,
这些规则也用来确定参数log_timezone的值)。
SQL 命令 SET TIME ZONE 为会话设置时区,它等价与命令SET TIMEZONE TO。
PostgreSQL提供了标准的SQL类型布尔值。布尔类型可以有几种状态:true,false,和第三状态null,这是SQL空值表示。
Name | Storage Size | Description |
---|---|---|
boolean | 1 byte | state of true or false |
枚举(枚举)类型的数据类型,包括静态,有序设置的值。在许多编程语言支持枚举类型,它们是相等。
Unlike other types, Enumerated Types need to be created using CREATE TYPE command. This type is used to store a static, ordered set of values, for example compass directions, i.e. NORTH, SOUTH, EAST, and WEST or days of the week as below:
CREATE TYPE week AS ENUM ('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun');
枚举一旦产生,它们可以像任何其他类型。
几何数据类型表示二维空间对象。最根本的不同点是形成的所有其他类型的基础。
Name | Storage Size | Representation | Description |
---|---|---|---|
point | 16 bytes | Point on a plane | (x,y) |
line | 32 bytes | Infinite line (not fully implemented) | ((x1,y1),(x2,y2)) |
lseg | 32 bytes | Finite line segment | ((x1,y1),(x2,y2)) |
box | 32 bytes | Rectangular box | ((x1,y1),(x2,y2)) |
path | 16+16n bytes | Closed path (similar to polygon) | ((x1,y1),…) |
path | 16+16n bytes | Open path | [(x1,y1),…] |
polygon | 40+16n | Polygon (similar to closed path) | ((x1,y1),…) |
circle | 24 bytes | Circle | <(x,y),r> (center point and radius) |
PostgreSQL提供的数据类型来存储的IPv4,IPv6的地址和MAC地址。这是更好地使用这些类型,而不是纯文本类型存储网络地址,因为这些类型提供输入错误检查和特殊的操作和函数。
Name | Storage Size | Description |
---|---|---|
cidr | 7 or 19 bytes | IPv4 and IPv6 networks |
inet | 7 or 19 bytes | IPv4 and IPv6 hosts and networks |
macaddr | 6 bytes | MAC addresses |
在对inet
或者cidr
类型的数据进行排序的时候,IPv4 地址总是排在 IPv6 地址前面,包括那些封装在IPv6地址里面或映射成 IPv6 地址的 IPv4 地址,例如::10.2.3.4 或者::ffff::10.4.3.2。
位串类型用于存储位掩码。他们要么是0或1。 SQL位类型有两种:(n)的位而变位(n)的,其中n是一个正整数 www.yiibai.com
这个类型支持全文检索,这是通过自然语言文档的集合的搜索,找到那些最符合查询活动。这有两种数据类型:
名称 | 描述 |
---|---|
tsvector | This is a sorted list of distinct words that have been normalized to merge different variants of the same word, called as “lexemes”. |
tsquery | This stores lexemes that are to be searched for, and combines them honoring the Boolean operators & (AND), | (OR), and ! (NOT). Parentheses can be used to enforce grouping of the operators. |
一个UUID(通用唯一标识符)写成小写的十六进制数字序列,由连字号,特别是一组8位数字,然后由三组4位数字,然后由一组12位数字分开几组,总32位,128位代表。
uuid类型用于存储RFC 4122和ISO/IEC 9834-8:2005中定义的通用唯一标识符(stores Universally Unique Identifiers,UUID),有一些数据库中把这个类型称为GUID(globally unique identifier)。UUID由一个128位的数字构成,它的标准的输入格式由32个小写的十六进制位组成,这32个十六进制位被分成4个组,第一个组有包含8个十六进制位,接下来的三个组个包含4个十六进制位,最后一个组包含12个十六进制位。不同的组横杠分开(-),例如:a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11。
一个UUID的例子是: 550e8400-e29b-41d4-a716-446655440000
xml数据类型可以用来存储XML数据。对于存储XML数据,首先创建XML值函数XMLPARSE如下:
xml类型可以存储xml文档(document),也可以存储由XMLDecl? content定义的xml内容片段(content)。xml内容片段可以有多个顶级元素。可以用表达式xmlvalue IS DOCUMENT来判断一个xml值是xml文档还是xml内容片段。
XMLPARSE (DOCUMENT '
PostgreSQL Tutorial
...
')
XMLPARSE (CONTENT 'xyzbar foo ')
JSON数据类型可以用来存储JSON(JavaScript对象符号)数据。这样的数据也可以被存储为文本,但json数据类型具有的优点是检查每个存储的值是否为有效的JSON值。也有相关的支持功能可以直接用来处理JSON数据类型,如下所示:
Example | Example Result |
---|---|
array_to_json(’{{1,5},{99,100}}’::int[]) | [[1,5],[99,100]] |
row_to_json(row(1,‘foo’)) | {“f1”:1,“f2”:“foo”} |
PostgreSQL的机会定义为可变长度的多维数组的列一个表。任何内置或用户定义的基本类型数组,枚举类型,或者可以创建复合型。
数组类型可以声明为:
CREATE TABLE monthly_savings (
name text,
saving_per_quarter integer[],
scheme text[][]
);
或通过使用关键字“ARRAY”:
CREATE TABLE monthly_savings (
name text,
saving_per_quarter integer ARRAY[4],
scheme text[][]
); www.yiibai.com
数组的值可以插入一个文本常量,内附大括号内的元素值,并用逗号将它们隔开。例子如下:
INSERT INTO monthly_savings
VALUES ('Manisha',
'{20000, 14600, 23500, 13250}',
'{{"FD", "MF"}, {"FD", "Property"}}');
用于访问阵列的一个例子如下所示。下面的命令将选择人员,他们存储在第二,第四个。 yiibai.com
SELECT name FROM monhly_savings WHERE saving_per_quarter[2] > saving_per_quarter[4];
修改数组的一个例子如下所示。
UPDATE monthly_savings SET saving_per_quarter = '{25000,25000,27000,27000}'
WHERE name = 'Manisha';
或数组表达式语法:
UPDATE monthly_savings SET saving_per_quarter = ARRAY[25000,25000,27000,27000]
WHERE name = 'Manisha'; www.yiibai.com
搜索数组的一个例子如下所示。
SELECT * FROM monthly_savings WHERE saving_per_quarter[1] = 10000 OR
saving_per_quarter[2] = 10000 OR
saving_per_quarter[3] = 10000 OR
saving_per_quarter[4] = 10000;
如果数组的大小是已知的上述搜索方法都可以使用。否则,下面的例子说明如何时要搜索的大小是不知道的。
SELECT * FROM monthly_savings WHERE 10000 = ANY (saving_per_quarter);
此类型代表一个字段名和数据类型,即结构的一个表中的行或记录列表。
下面的例子演示如何声明一个复合类型:
CREATE TYPE inventory_item AS (
name text,
supplier_id integer,
price numeric
); www.yiibai.com
此数据类型可用于在创建表如下所示: yiibai.com
CREATE TABLE on_hand (
item inventory_item,
count integer
);
复合值可以插入文字常量,封装领域括号内的值,并用逗号将它们隔开。一个例子是如下:
INSERT INTO on_hand VALUES (ROW('fuzzy dice', 42, 1.99), 1000); yiibai.com
此有效的定义同上的inventory_item的。行关键字实际上是可选的表达式中,只要有一个以上的字段。
要访问一个复合列的字段,字段名,使用点很像选择字段从一个表名。例如,要选择一些子字段,on_hand示例表的查询将如下所示:
SELECT (item).name FROM on_hand WHERE (item).price > 9.99;
甚至可以使用表名(例如,在一个多表查询),像这样: yiibai.com
SELECT (on_hand.item).name FROM on_hand WHERE (on_hand.item).price > 9.99;
范围类型的数据类型,采用了一系列数据。范围类型可以是离散的范围(例如,所有的整数值1到10)或连续范围(例如任何时间点的上午10:00到上午11:00)。
内置的范围类型范围包括:
int4range - Range of integer
int8range - Range of bigint
numrange - Range of numeric
tsrange - Range of timestamp without time zone
tstzrange - Range of timestamp with time zone yiibai.com
daterange - Range of date
可以创建自定义的范围类型,做出新的类型的适用范围,如使用int类型为基础的IP地址范围,或者使用浮点数据类型为基础的浮动范围。
范围类型支持包容性和排他性的范围边界分别使用[]和()个字符,例如: [4,9]'代表所有从包括4但不包括9的整数。
对象标识符(OID)内部使用PostgreSQL作为各种系统表的主键。 OIDS IfWITH指定或default_with_oids配置变量,只有在这样的情况下启用的OID被添加到用户创建的表。下表列出了几个别名类型。 OID别名类型有没有自己的操作,除了专门的输入和输出过程。
Name | References | Description | Value Example |
---|---|---|---|
oid | any | numeric object identifier | 564182 |
regproc | pg_proc | function name | sum |
regprocedure | pg_proc | function with argument types | sum(int4) |
regoper | pg_operator | operator name | + |
regoperator | pg_operator | operator with argument types | *(integer,integer) or -(NONE,integer) |
regclass | pg_class | relation name | pg_type |
regtype | pg_type | data type name | integer |
regconfig | pg_ts_config | text search configuration | english |
regdictionary | pg_ts_dict | text search dictionary | simple |
PostgreSQL类型系统包含了一些特殊用途的统称为伪类型的项。一个伪类型不能被用作列的数据类型,但它可以用来声明一个函数的参数或结果类型。下表列出了现有的伪类型。
名称 | 描述 |
---|---|
any | Indicates that a function accepts any input data type. |
anyelement | Indicates that a function accepts any data type. |
anyarray | Indicates that a function accepts any array data type. |
anynonarray | Indicates that a function accepts any non-array data type. |
anyenum | Indicates that a function accepts any enum data type. |
anyrange | Indicates that a function accepts any range data type. |
cstring | Indicates that a function accepts or returns a null-terminated C string. |
internal | Indicates that a function accepts or returns a server-internal data type. |
language_handler | A procedural language call handler is declared to return language_handler. |
fdw_handler | A foreign-data wrapper handler is declared to return fdw_handler. |
record | Identifies a function returning an unspecified row type. |
trigger | A trigger function is declared to return trigger. |
void | Indicates that a function returns no value. |