这是我参与8月更文挑战的第11天,活动详情查看:8月更文挑战html
对字符集的支持,能够容许你使用多种字符集(也称为编码
)存储文本,包括单字节字符集(如ISO 8859
)和多字节字符集(如 EUC
——Extended Unix Code
、UTF-8和Mule internal code
)sql
字符集在 initdb
命令初始化PostgreSQL数据库集群是设置;也能够在建立数据库建立时指定。数据库
LC_CTYPE
—— character classification locale settings
:本地设置的字符分类,即本地设置的字符类别,与字符集含义相似。markdown
LC_COLLATE
—— string sort order locale settings
:本地设置的字符串排序,即本地设置的排序规则。app
对于 C
或 POSIX
locale,任何字符集都是容许的。其余则不必定,好比Windows下,UTF-8编码能够在任何locale下使用。ide
locale 直接含义为本地,在此处也能够翻译为“语言环境”,或“本地语言环境”。函数
为PostgreSQL集群定义默认的字符集编码:oop
initdb -E EUC_JP
复制代码
上面设置的默认字符集为:EUC_JP
(Extended Unix Code for Japanese)。-E
是参数 --encoding
的缩写。post
EUC_JP, EUC_CN, EUC_KR, EUC_TW.ui
数据库指定LC_COLLATE和LC_CTYPE后没法修改。
为一个数据库指定另外一个编码(改编码须要与 初始化集群时的locale兼容)
createdb -E EUC_KR -T template0 --lc-collate=ko_KR.euckr --lc-ctype=ko_KR.euckr korean
复制代码
上面建立一个名为 korean 的数据库,该数据库使用字符集 EUC_KR
和语言环境(locale
) ko_KR
。
也可使用 SQL 命令实现:
CREATE DATABASE korean WITH ENCODING 'EUC_KR' LC_COLLATE='ko_KR.euckr' LC_CTYPE='ko_KR.euckr' TEMPLATE=template0;
复制代码
上述命令指定复制 template0 数据库。复制任何其余数据库时,没法更改来自源数据库的数据的编码和区域设置,由于这可能会致使数据损坏。
使用系统目录 pg_database
能够查看数据看编码;也可使用 psql -l
或 \l
命令查看
shop=# \l
数据库列表
名称 | 拥有者 | 字元编码(Encoding) | 校对规则(排序规则Collation) | Ctype | 存取权限
-----------+----------+----------+--------------------------------+--------------------------------+-----------------------
demo | postgres | UTF8 | Chinese (Simplified)_China.936 | Chinese (Simplified)_China.936 |
postgres | postgres | UTF8 | Chinese (Simplified)_China.936 | Chinese (Simplified)_China.936 |
shop | postgres | UTF8 | Chinese (Simplified)_China.936 | Chinese (Simplified)_China.936 |
template0 | postgres | UTF8 | Chinese (Simplified)_China.936 | Chinese (Simplified)_China.936 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | Chinese (Simplified)_China.936 | Chinese (Simplified)_China.936 | =c/postgres +
| | | | | postgres=CTc/postgres
(5 行记录)
复制代码
概念上,可排序数据类型的每一个表达式都有一个排序规则。
通常常见的内置的可排序数据类型(collatable data type
)有 text
, varchar
和 char
,用户定义的基类型也能够标记为可整理...
若是表达式是列引用,则表达式的排序规则是列上已定义的排序规则。
若是表达式是常量,则排序规则是常量数据类型的默认排序规则。
更复杂表达式的排序规则源自其输入的排序规则。
若是要进行排序操做或其余须要排序规则的操做,则必需要有肯定的表达式的排序规则,表达式排序规则不肯定,排序将失败。
好比Order By、或<
比较操做符,或函数,会使用输入表达式(输入列)的排序规则。
在全部平台中,default
、 C
和 POSIX
这三种排序规则都是可用的。
其余的排序规则取决于操做系统的支持。
SQL标准的排序规则ucs_basic
(用于UTF8
编码的collation)也是可用的。
要查看当前可用的排序能够可使用系统目录pg_collation
。(在初始化数据库系统时,initdb会使用在操做系统中找到的全部语言环境的排序规则填充系统目录 pg_collation)
SELECT * FROM pg_collation;
复制代码
或在 psql
中,执行 \dOS+
命令查看。
shop=# SELECT * FROM pg_collation WHERE COLLNAME LIKE '%CN%';
oid | collname | collnamespace | collowner | collprovider | collisdeterministic | collencoding | collcollate | collctype | collversion
-------+------------------+---------------+-----------+--------------+---------------------+--------------+-------------+------------+-------------
12391 | bo-CN-x-icu | 11 | 10 | i | t | -1 | bo_CN | bo_CN | 137.51.25
12665 | ii-CN-x-icu | 11 | 10 | i | t | -1 | ii_CN | ii_CN | 137.51.25
12930 | ug-Arab-CN-x-icu | 11 | 10 | i | t | -1 | ug_Arab_CN | ug_Arab_CN | 137.51.25
12963 | zh-Hans-CN-x-icu | 11 | 10 | i | t | -1 | zh_Hans_CN | zh_Hans_CN | 137.51.25
(4 行记录)
shop=# SELECT * FROM pg_collation;
oid | collname | collnamespace | collowner | collprovider | collisdeterministic | collencoding | collcollate | collctype | collversion
-------+------------------------+---------------+-----------+--------------+---------------------+--------------+-------------+-------------+-------------
100 | default | 11 | 10 | d | t | -1 | | |
950 | C | 11 | 10 | c | t | -1 | C | C |
951 | POSIX | 11 | 10 | c | t | -1 | POSIX | POSIX |
12326 | ucs_basic | 11 | 10 | c | t | 6 | C | C |
...
...
...
复制代码
CREATE COLLATION
语句能够建立自定义的排序规则。
建立一个存放ABab的数据表。后续操做基于此表演示。
CREATE TABLE OrderTest( letter char(1) NOT NULL ); INSERT INTO OrderTest values('B'),('b'),('A'),('a'); 复制代码
PostgreSQL的排序规则彷佛有些不一样,其默认的排序规则,在比较操做中是区分大小写的,可是在排序操做中,是不区分大小写的,至少默认不是按照字母编码的值排序。
具体查看下面的结果:
shop=# select * from OrderTest where letter ='A';
letter
--------
A
(1 行记录)
shop=# select * from OrderTest where letter ='a';
letter
--------
a
(1 行记录)
复制代码
letter ='A'
和letter ='a'
是两个不一样的结果。包括使用LIKE子句的比较,也是区分大小写的。
shop=# select * from OrderTest order by letter;
letter
--------
a
A
b
B
(4 行记录)
复制代码
如上所示,默认的排序结果中,a 和 A 被视为相同并放在了一块儿;b 和 B 被视为相同并放在了一块儿。
或者SQL标准的排序规则ucs_basic
(用于UTF8
编码的collation),与'C'的行为同样。或者其余严格区分码值的排序规则
shop=# select * from OrderTest order by letter collate "ucs_basic";
letter
--------
A
B
a
b
(4 行记录)
shop=# select * from OrderTest order by letter collate "C";
letter
--------
A
B
a
b
(4 行记录)
shop=# select * from OrderTest order by letter collate "C" desc;
letter
--------
b
a
B
A
(4 行记录)
复制代码
排序规则(collation
)特性容许指定每列甚至每一个操做的数据的排序顺序和字符分类行为。
同时也能够解除数据库的 LC_COLLATE
和 LC_CTYPE
设置在建立后没法修改的限制。
以下,在建立表时指定列的排序规则:
CREATE TABLE test1 (
a text COLLATE "zh-Hans-CN-x-icu",
b text COLLATE "zh-Hant-TW-x-icu"
);
insert into test1 values('A','a'),('b','B');
复制代码
此时,若是执行下面的比较查询查询将会发生错误:
shop=# SELECT a < b FROM test1;
错误: 没法肯定字符串比较中使用哪一种排序规则
提示: 使用COLLATE子句来显示设置排序规则.
复制代码
这是由于a和b有隐式的排序规则的冲突。
在查询中指定列或常量的排序规则
<column_name/constant_value> COLLATE "<collate_name>"
。
以下:
shop=# SELECT a < b COLLATE "zh-Hans-CN-x-icu" FROM test1;
?column?
----------
f
t
(2 行记录)
复制代码
在某些状况下,不一样的查询须要使用不一样的排序规则来查询同一列。
例如,一个查询可能须要对列执行区分大小写的比较,而另外一个查询可能须要对同一列执行不区分大小写的比较。这能够经过在查询内显式指定排序规则来完成:
在正常使用的SQL语句中的列名后面,指定COLLATE
关键字及排序规则名,其余部分和之前的SQL同样,保持不变。
注意,COLLATE后的排序规则必选用双引号包含,如COLLATE "ucs_basic"
、COLLATE "C"
,不然会报错。MySQL/MariaDB、SQLServer中不须要双引号包含。
<column_name/constant_value> COLLATE "<collate_name>"
复制代码
好比查询OrderTest表的按列排序。
-- 默认区分大小写
shop=# select * from OrderTest where letter='a';
letter
--------
a
(1 行记录)
复制代码
彷佛,==PostgreSQL的UTF-8编码下,未找到不区分大小写的排序规则【也多是本身不会】==。
-- 指定查询使用的排序规则
shop=# select * from OrderTest where letter COLLATE "C" ='a';
letter
--------
a
(1 行记录)
shop=# select * from OrderTest where letter COLLATE "ucs_basic" ='a';
letter
--------
a
(1 行记录)
复制代码
PostgreSQL中能够建立指定的排序规则的索引,即建立与列不一样的排序规则的索引,一个列上建立多个不一样索引。
详细可查看相关官方文档。
CREATE TABLE .. ( ..., field COLLATE <collation>, ... )
ALTER TABLE
CREATE INDEX .. ON ( field COLLATE <collation> )
CREATE INDEX .. ON ( (expr COLLATE <collation>) )
expr :: expr COLLATE <collation>
Possibly: CREATE COLLATE ..
复制代码