PostgreSQL 数据类型
PostgreSQL?有着丰富的数据类型可用。 用户可以使用?CREATE TYPE?命令为?PostgreSQL?增加新的数据类型。 Table 8-1?显示了所有内置的普通数据类型。 在"别名"列里列出的大多数可选名字都是因历史原因?PostgreSQL?在内部使用的名字。 另外,还有一些内部使用的或者废弃的类型也可以用,但没有在这里列出。 Table 8-1. 数据类型
每种数据类型都有一个由其输入和输出函数决定的外部表现形式。 许多内建的类型有明显的格式。不过,许多类型要么是?PostgreSQL?所特有的,比如几何路径,要么可能是有几种不同的格式,比如日期和时间类型。 有些输入和输出函数是不可逆的。也就是说,输出函数的输出结果和原始的输入比较的时候可能丢失精度。 8.1. 数值类型数值类型由2、4或8字节的整数以及4或8字节的浮点数和可选精度小数组成。?Table 8-2?列出了所有可用类型。 Table 8-2. 数值类型
数值类型常量的语法在?Section 4.1.2?里描述。 数值类型对应有一套完整的数学操作符和函数。相关信息请参考?Chapter 9。 下面的几节详细描述这些类型。 8.1.1. 整数类型类型?smallint,integer,和?bigint?存储各种范围的全部是数字的数,也就是没有小数部分的数字。 试图存储超出范围以外的数值将导致一个错误。 常用的类型是?integer,因为它提供了在范围,存储空间, 和性能之间的最佳平衡。一般只有在磁盘空间紧张的时候才使用?smallint。而只有在?integer?的范围不够的时候才使用?bigint,因为前者绝对快得多。 bigint?类型可能不是在所有平台上都运转正确, 因为它依赖编译器对八字节整数的支持。在那些没有这样支持的机器上,?bigint?的作用和?integer?一样(但是仍然占据八字节存储)。不过,我们还不知道任何有这样的情况的平台。 SQL只声明了整数类型?integer(或int)和?smallint。类型?bigint,和类型名?int2,int4,和?int8?都是扩展, 也在许多其它?SQL?数据库系统中使用。 8.1.2. 任意精度数值类型?numeric?可以存储最多1000位精度的数字并且准确地进行计算。 我们特别建议将它用于货币金额和其它要求计算准确的数量。不过,numeric?类型上的算术运算比整数类型或者我们下一节描述的浮点数类型要慢很多。 在随后的内容里,我们使用了下述术语: 一个?numeric?的比例是到小数点右边为止小数部分的位数,?numeric?的精度是整个数字里全部数据位的数目,也就是小数点两边的数据数目。 因此数字 23.5141 的精度为6而比例为4。你可以认为整数的比例为零。 numeric?字段的最大精度和最大比例都是可以配置的。要声明一个类型为?numeric?的字段,你可以用下面的语法 NUMERIC(precision,scale) 精度必须为正数,比例可以为零或者正数。 另外, NUMERIC(precision) 选择了 0 为比例。不带任何精度或者比例声明 NUMERIC 则创建一个可以存储一个直到实现精度上限的任意精度和比例的数值, 一个这样类型的字段将不会把输入数值转化成任何特定的比例, 而带有比例声明的?numeric?字段将把输入值转化为该比例。 (SQL标准要求缺省的比例是 0。也就是转化成整数精度。 我们觉得这样做有点没用。如果你关心移植性,那你最好总是明确声明精度和比例。) 如果一个要存储的数值的比例比字段声明的比例高, 那么系统将尝试圆整(四舍五入)该数值到指定的小数位。 然后,如果小数点左边的数据位数超过了声明的精度减去声明的比例, 那么抛出一个错误。 数值数据值物理上是不带任何前导或者后缀零的形式存储的。 因此,字段上声明的精度和比例都是最大值,而不是固定分配的。 (在这个方面,numeric?类型更类似于?varchar(n), 而不像?char(n)。) 实际存储是每四个十进制位两个字节,然后在整个数据上加上八个字节的额外开销。 除了普通的数字值之外,numeric?类型允许特殊值?NaN, 表示"不是一个数字"。任何在?NaN?上面的操作都生成另外一个?NaN。 如果在 SQL 命令里把这些值当作一个常量写,你必须在其周围放上单引号,比如?UPDATE table SET x = ‘NaN‘。在输入时,字串?NaN当作大小写无关看待。 类型?decimal?和?numeric?是等效的。 两种类型都是SQL标准。 8.1.3. 浮点数类型数据类型?real?和?double precision?是不准确的,变精度的数字类型。 实际上,这些类型是?IEEE?标准 754 二进制浮点数算术(分别对应单和双精度)的一般实现, 外加下层处理器,操作系统和编译器对它的支持。 不准确意味着一些数值不能准确地转换成内部格式并且是以近似的形式存储的,因此存储然后把数据再打印出来可能显示一些缺失。 处理这些错误以及这些错误是如何在计算中传播的属于数学和计算机科学的一个完整的分支, 我们不会在这里进一步讨论它,这里的讨论仅限于如下几点: ? ?
? 通常,real?类型的范围是至少 -1E+37 到 +1E+37, 精度至少是 6 位小数。double precision?类型通常有 -1E+308 到 +1E+308 的范围,精度是至少 15 位数字。太大或者太小的数值都会导致错误。 如果输入数据太高,那么可能发生园整。太接近零的数字,如果无法与零值的表现形式相区分就会产生下溢错。 除了普通的数字值之外,浮点类型还有几个特殊值: Infinity ? PostgreSQL?还支持 SQL 标准表示法?float?和?float(p)?用于声明非精确的数值类型。 在这里,p?声明以二进制位表示的最低可接受精度。 在选取?real?类型的时候,PostgreSQL?接受?float(1)?到?float(24),在选取?double precision?的时候,接受?float(25)?到?float(53)。在允许范围之外的?p?值将导致一个错误。 没有声明精度的?float?将被当作是?double precision。
8.1.4. Serial(序号)类型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 ); 因此,我们就创建了一个整数字段并且把它的缺省数值安排为从一个序列发生器取值。 应用了一个?NOT NULL?约束以确保空值不会被明确地插入。 在大多数情况下你可能还希望附加一个?UNIQUE?或者?PRIMARY KEY?约束避免意外地插入重复的数值,但这个不是自动发生的。
要使用?serial?字段插入序列的下一个数值到表中, 主要是要注意?serial?应该赋予缺省值。 我们可以通过在?INSERT?语句中把该字段排除在字段列表之外来实现, 也可以通过使用?DEFAULT?关键字来实现。 类型名?serial?和?serial4?是等效的: 两个都创建?integer?字段。类型名?bigserial?和?serial8?也一样,只不过它创建一个?bigint?字段。 如果你预计在表的生存期中使用的标识数目超过 231?个,那么你应该使用?bigserial。 一个?serial?类型创建的序列在所属的字段被删除的时候自动删除,其它情况下是不会被删除的。 (这一点在?PostgreSQL?版本 7.3 之前可不是真的。请注意,这种自动删除的关联在通过重载 7.3 以前的数据库转储的时候可不会自动发生; 那样的转储文件不包含需要建立这种关联关系的信息。) 另外,这样的序列和字段之间的依赖性只在?serial?字段本身上有; 如果任何其它字段引用了序列(可能是手工调用?nextval?函数), 那么,如果这个序列被删除了,它们就会被破坏。我们认为这样使用?serial?字段是一种不好的形式;如果你想用同一个序列发生器给几个字段喂数据,那么还是把序列发生器作为独立对象创建。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |