您的位置:首页 > 其它

postgres关键字、常量和数据类型

2015-12-08 22:40 190 查看
一 标识符和关键字

         1. SQL 标识符和关键字必须以一个字母 (a-z 以及带变音符的字母和非拉丁字母 )或下划线(_) 开头, 随后的字符可以是字母、下划线、数字 (0-9)、 美元符号 ($)。

         2. 根据 SQL 标准,美元符号不允许出现在标识符中, 因此使用美元符号将不易移植。

         3. SQL 标准不会定义包含数字或者以下划线开头或结尾的关键字, 因此按照这种格式定义的标识符是安全的,不会和将来标准的扩展特性冲突。

         4. 系统使用不超过 NAMEDATALEN-1 个字符作为标识符; 你可以在命令中写更长的名字,但它们会被截断。

                   (1)NAMEDATALEN 的缺省值是 64 , 因此标识符最大长度是 63 字节。

                   (2) 如果觉得这个限制有问题,那么你可以在 src/include/pg_config_manual.h里修改NAMEDATALEN 来改变它。

         5. 关键字和未被引号包围的标识符都是大小写无关的,但是建议:把关键字写成大写,而名字等用小写。

                   UPDATE MY_TABLE SET A = 5; 和 uPDaTE
my_TabLE SeT a = 5; 是等效的。

         6. 把一个标识符用引号包围起来同时也令它大小写相关,而没有引号包围起来的名字总是转成小写。

                   (1) 标识符FOO, foo和"foo" 是等价的 PostgreSQL名字

                   (2) 但"Foo"和 "FOO" 与上面三个以及它们之间都是不同的。 PostgreSQL里对未加引号的名子总是转换成小写

                   (3) 这和 SQL 标准是不兼容的, SQL 标准要求未用引号包围起来的名字总是转成大写。因此根据标准, foo等于"FOO" 但不等于 "foo"

                   (4) 如果你想编写可移植的程序,那么我们建议你要么就总是用引号包围某个名字,要么就从来不引

二 常量

         1. 两个只是通过至少一个换行符的空白分隔的字符串常量会被连接在一起, 并当做它们是写成一个常量处理。

                   (1)SELECT 'foo'

                            'bar'; 和 SELECT
'foobar'; 是等价的。

         2. 转义字符串常量,这是一个 PostgreSQL对SQL 标准的扩展。转义字符串语法是通过在字符串前写字母 E
(大写或者小写)的方法声明的。

                   (1)C 风格的转义字符串常量。 =>
select e'this is \n a string!';

                                                 ?column? 

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

                                                this is   +

                                                 a string!

                                               (1 row)

                      主意:最好是不使用反斜杠转义。如果你需要使用反斜杠转义来表示特殊的字符, 那么请在字符串常量前加上 E。

                             要在字符串常量里包含反斜杠, 则写两个反斜杠(\\)。另外, PostgreSQL 允许用一个反斜杠来转义单引号 \', 不过,将来版本 的 PostgreSQL 将不允许这么用。所以最好坚持使用符合标准的 ''。

                   (2)Unicode 转义字符串常量。一个转义 Unicode字符常量以 U& 或者u&开始,在引号中, 通过写一个后面跟有4位 16进制代码点或跟有“+”号和 6位16 进制代码点的反斜杠, Unicode字符可以写成转义格式。

                             例如:U&'d\0061t\+000061'; 和 U&'d!0061t!+000061'
UESCAPE '!'; 和 u&'d!0061t!0061'
UESCAPE '!'; 都是代表“ data”

                            cd03=> select U&'d!0061t!+000061' UESCAPE '!';

                             ?column?

                            ----------

                             data

                            (1 row)

                   (3) 美元符引用字符串常量。如果一个字符串里面包含了很多特殊字符,如: [\t\r\n\v\\],那么用$q$[\t\r\n\v\\]$q$ 这种方式表示会很方便( $q$,是一个字符串开始和结束标签,两个标签大小写一致)。

                    但是这并非 sql标准。

                            => select $q$[\t\r\n\v\\]$q$;

                               ?column?  

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

                             [\t\r\n\v\\]

                            (1 row)

                    在定义函数是经常用到,如:

                            $function$

                            BEGIN

                                RETURN ($1 ~ $q$[\t\r\n\v\\]$q$);END;

                            $function$

                   (4) 位串常量 ,位串常量里可以用的字符只有 0 和1 。

                            2 进制:

                            => SELECT B'1001';

                             ?column?

                            ----------

                             1001

                            (1 row)

                            16 进制:

                            => SELECT X'1FF';

                               ?column?  

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

                             000111111111

                            (1 row)

三 数据类型

          常用的数据类型:

名字别名描述
bigintint8有符号8字节整数
bigserialserial8自增8字节整数
bit [ (n) ] 定长位串
bit varying [ (n) ]varbit变长位串
booleanbool逻辑布尔值(真/假)
box 平面上的矩形
bytea 二进制数据("字节数组")
character varying [ (n) ]varchar [ (n) ]变长字符串
character [ (n) ]char [ (n) ]定长字符串
cidr IPv4 或 IPv6 网络地址
circle 平面上的圆
date 日历日期(年, 月, 日)
double precisionfloat8双精度浮点数字(8字节)
inet IPv4 或 IPv6 主机地址
integerint, int4有符号 4 字节整数
interval [ fields ] [ (p)
]
 时间间隔
line 平面上的无限长直线
lseg 平面上的线段
macaddr MAC (Media Access Control)地址
money 货币金额
numeric [ (p, s)
]
decimal [ (p, s)
]
可选精度的准确数字
path 平面上的几何路径
point 平面上的点
polygon 平面上的封闭几何路径
realfloat4单精度浮点数(4 字节)
smallintint2有符号 2 字节整数
smallserialserial2自增 2 字节整数
serialserial4自增 4 字节整数
text 变长字符串
time [ (p) ] [ without time zone ] 一天中的时间(无时区)
time [ (p) ] with time zonetimetz一天里的时间,包括时区
timestamp [ (p) ] [ without time zone ] 日期和时间(无时区)
timestamp [ (p) ] with time zonetimestamptz日期和时间,包括时区
tsquery 文本检索查询
tsvector 文本检索文档
txid_snapshot 用户级别的事务ID快照
uuid 通用唯一标识符
xml XML 数据
json JSON 数据
     1.  负数在计算机中以其正值的补码形式表达,能够表示多一个数字,而且避免了减法运算
smallint2 字节小范围整数-32768 到 +32767
          => insert into jay_test values(32768);

          ERROR:  smallint out of range

    数值类型
名字存储空间描述范围
smallint2 字节小范围整数-32768 到 +32767
integer4 字节常用的整数-2147483648 到 +2147483647
bigint8 字节大范围整数-9223372036854775808 到 +9223372036854775807
decimal变长用户声明精度,精确小数点前 131072 位;小数点后 16383 位
numeric变长用户声明精度,精确小数点前 131072 位;小数点后 16383 位
real4 字节变精度,不精确6 位十进制数字精度
double precision8 字节变精度,不精确15 位十进制数字精度
smallserial2 字节小范围自增整数1 到 32767
serial4 字节自增整数1 到 2147483647
bigserial8 字节大范围自增整数1 到 9223372036854775807
     2.如果要表示精确的小数,用decimal和numeric,两者都是一样的。

     3.real和double precision都不能表示准确的小数。

          (1)real只能保存6位数字,科学计数法也是一样(指数部分不算)

          (2)如果整数位已经大于六位,则采用科学计数法:5.24961e+12

          (3)如果小数位+整数位(整数位小于六位)大于六位,会四舍五入

          (4)所以real结果是很难预料的,而且值采用科学计数法之后误差会变大

          (5)如果使用real类型,应该确保值不会超过999999。

          (6)但是效率会比decimal和numeric高!因为他的位数是固定的。

          (7)取值范围:最大值的二进制表示为0/1(符合位) 11111111(指数位)  111 111 111 111 111 111 111 11(尾数位),即x=+/-(2-2^(-23)) * 2^127=+/-3.40282e+38

          (8)特殊值Infinity:正无穷  -Infinity:负无穷 NaN:不是一个数值

          例如:

          => create table jay_test(id real);

          CREATE TABLE

          cd03=> insert into jay_test values(123.342453457345);

INSERT 0 1

cd03=> select * from jay_test ;

   id

---------

123.342

(1 row)

     4. numeric 类型

          存储非常大的数字并且准确地进行计算, 用于货币金额和其它要求精确计算的场合, numeric类型上的算术运算比整数类型或者浮点数类型要慢很多。

          NUMERIC(precision, scale)

     precision:精度 最大值为1000

     scale:标度 如果传入的小数标度大于声明的标度,则四舍五入。

     例如:2.234的精度为4,标度为3

     numeric 类型的数据值在物理上是不带任何前导或者后缀零的形式存储的。 因此,字段上声明的精度和标度都是最大值,而不是固定分配的。在这个方面, numeric类型更类似于varchar(n)而不是 char(n)。实际存储是每四个十进制位两个字节,
然后在整个数据上加上三到八个字节的额外开销。

          numeric类型允许用特殊值NaN 表示"不是一个数字"。任何在NaN上面的操作都生成另外一个 NaN。PostgreSQL认为NaN相等,
并且大于所有非NaN值。

     5.序列号类型

          smallserial,serial和bigserial类型不是真正的类型,
只是为在表中创建唯一标识做的概念上的便利。声明的时候会创建一个属于该字段的序列。

          一个serial类型创建的序列在所属的字段被删除的时候自动删除。

          注意:不管 smallserial,serial还是bigserial,生成的序列最大值总是9223372036854775807(bigint),但是实际字段可接受的值可能没有这么大,如:smallserial可接受的最大值为:32767,但是序列生成的值可能大于这个值,那么在插入的时候报错。


     5.字符类型

          这三种类型之间没有性能差别,除了当使用填充空白类型时的增加存储空间, 和当存储长度约束的列时一些检查存入时长度的额外的CPU周期。 虽然在某些其它的数据库系统里,character(n) 有一定的性能优势,但在PostgreSQL里没有。
事实上,character(n)通常是这三个中最慢的,
因为额外存储成本。在大多数情况下,应该使用text 或character varying。

          但是实际测试结果如下:



结论:1.插入1百万条记录,varchar稍快。

          2.更新70万条记录,char明显更快。

          3.在存储空间上,varchar明显比char更节约空间。

          4.另外由于postgres才用mvcc(多版本并发控制),无论更新或者删除数据都会使表内容变大。

          
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: