博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PG字符:使用collation设置排序规则
阅读量:6947 次
发布时间:2019-06-27

本文共 5015 字,大约阅读时间需要 16 分钟。

hot3.png

  相关文档:

  PG9.1 

  Collation支持 
  字符集的设置 
  PG9.2 
  Collation支持 
  字符集的设置 
  
  简介:PG9.1开始支持collationcollation允许指定每列数据的排序顺序和字符分类,甚至每个操作的。
  它缓解了数据库的LC_COLLATELC_CTYPE设置无法在数据库创建后更改的限制。
  
  使用示例:
  
  1.排序顺序的设置:
  a.初始化数据库是可以设置locale,如果不设置默认参照操作系统的locale
    bin]$   ./initdb -D ../data5 --encoding=UTF8 --locale=zh_CN.UTF8
  postgres=# \l
  List of databases
  Name | Owner | Encoding | Collate | Ctype | Access privileges 
  -----------+----------+----------+-------------+-------------+-----------------------
  postgres | postgres | UTF8 | zh_CN.utf8 | zh_CN.utf8 | 
  template0| postgres | UTF8 | zh_CN.utf8 | zh_CN.utf8 | =c/postgres 
  +
  | | | | | postgres=CTc/postgres
  template1| postgres | UTF8 | zh_CN.utf8 | zh_CN.utf8 | =c/postgres 
  +
  | | | | | postgres=CTc/postgres
  (5 rows)
  
  b.创建数据库时,locale参数的设置必须是数据库集群初始化时设置的locale(也就是templatelocale)兼容的:
  postgres=# create database testdb with ENCODING='utf8'   LC_COLLATE='zh_CN.utf8' LC_CTYPE='zh_CN.utf8'
  template=template0; 
  CREATE DATABASE
  c.创建表时,引用的collation必须是所在数据库的编码encoding兼容的。
  CREATE TABLE test1 (
  a text COLLATE "de_DE",
  b text COLLATE "es_ES"
  );
  
  2.定义新的collation
  语法:
  CREATE COLLATION name (
  [ LOCALE = locale, ]
  [ LC_COLLATE = lc_collate, ]
  [ LC_CTYPE = lc_ctype ]
  )
  CREATE COLLATION name FROM existing_collation
  注意:创建collation时:若设置参数LOCALE的值,则表示LC_COLLATELC_CTYPE都设置为LOCALE所设置的值,
  此时不能再设置LC_COLLATELC_CTYPE;不设置LOCALE值的时候才能设置LC_COLLATELC_CTYPE的值,
  一般二者设置为相同的值,也可以设置为不同,但一般在实践中是无意义的。
  例子:
  postgres=# create collation ddd (locale='de_DE.utf8');
  CREATE COLLATION
  postgres=# select a<b collate "ddd" from tt;
  ?column? 
  ----------
  f
  t
  f
  f
  f
  t
  f
  (7 rows)
  postgres=# create collation ddd2 from ddd;
  CREATE COLLATION
  
  3.排序顺序的使用:
  一个表达式的collation derivation可以是隐式的或者显式的。这个区别在多个不同collation出现在一个表达式中
  时影响collation的组合。显式的collation   derivation出现在使用COLLATE语句的时候;所有其他的collation   derivations
  都是隐式的。当需要组合多个collation时,例如在一个函数调用中,通常有以下规则:
  aIf any input expression has an explicit collation derivation, then   all explicitly derived collations among the 
  input expressions must be the same, otherwise an error is raised. If any   explicitly derived collation is present, 
  that is the result of the collation combination.
  b. Otherwise, all input expressions must have the same implicit collation   derivation or the default collation. 
  If any non-default collation is present, that is the result of the collation   combination. Otherwise, the result is
  the default collation.
  c. If there are conflicting non-default implicit collations among the input   expressions, then the combination is
  deemed to have indeterminate collation. This is not an error condition unless   the particular function being 
  invoked requires knowledge of the collation it should apply. If it does, an   error will be raised at run-time.
  
  以表test1的操作为例:
  postgres=# \d test1
  Table "public.test1"
  Column | Type | Modifiers 
  --------+------+---------------
  a | text | collate de_DE
  b | text | collate es_ES
  ab列有冲突的隐式collation。必须为任何一个输入表达式附加一个显式的collation说明。如下:
  postgres=# select a<b from test1;
  
  ERROR: could not determine which collation to use for string comparison
  HINT: Use the COLLATE clause to set the collation explicitly.
  STATEMENT: select a<b from test1;
  ERROR: could not determine which collation to use for string comparison
  HINT: Use the COLLATE clause to set the collation explicitly.
  
  解决:SELECT a < b COLLATE "de_DE" FROM test1; 
  或等效的 SELECT a COLLATE "de_DE" < b FROM test1;
  
  ab列组合时,隐式的collation不一致,则需要显式地为组合指定一个collation。如下:
  
  postgres=# select * from test1 order by a||b;
  
  ERROR: collation mismatch between implicit collations "de_DE" and   "es_ES" at character 30
  HINT: You can choose the collation by applying the COLLATE clause to one or   both expressions.
  STATEMENT: select * from test1 order by a||b;
  ERROR: collation mismatch between implicit collations "de_DE" and   "es_ES"
  LINE 1: select * from tt order by a||b;
  ^
  HINT: You can choose the collation by applying the COLLATE clause to one or   both expressions.
  
  解决:SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";
  
  PostgreSQL认为不同的collation对象是不兼容的,即使他们有相同的属性。所以,比如:
  postgres=# select a collate "C"<b COLLATE "POSIX" from   test1;
  
  ERROR: collation mismatch between explicit collations "C" and   "POSIX" at character 24
  STATEMENT: select a collate "C"<b COLLATE "POSIX" from   test1;
  ERROR: collation mismatch between explicit collations "C" and   "POSIX"
  LINE 1: select a collate "C"<b COLLATE "POSIX" from   test1;
  tip:默认情况下,不管数据库编码是什么都可以使用CPOSIXcollation
  ④当排序顺序不符合自身语言环境的习惯时,可以对排序字段排序顺序的转化来调整。以下是一个
  中文排序习惯的转化:
  以下排序不符合中文发音排序的习惯:
  postgres=# select * from t order by cont;
  id | name | cont 
  ----+------+--------------
  10 | kkk | 从此从此从此
  10 | kkk | 可可己
  10 | kkk | 可可己
  10 | kkk | 可可己
  10 | kkk | 并不并不
  10 | kkk | 阿阿阿阿阿阿
  (6 rows)
  
  解决:
  postgres=# select * from t order by convert_to(cont,'GBK');
  id | name | cont 
  ----+------+--------------
  10 | kkk | 阿阿阿阿阿阿
  10 | kkk | 并不并不
  10 | kkk | 从此从此从此
  10 | kkk | 可可己
  10 | kkk | 可可己
  10 | kkk | 可可己
  (6 rows)
  
  4.创建索引时也可以由COLLATE语句显式指定collation
  postgres=# create index tiindex on t1(b collate "de_DE" DESC); 
  CREATE INDEX
  
  更多详细信息,请查阅PG社区相关文档专区

 初次发表网址:    

转载于:https://my.oschina.net/liuyuanyuangogo/blog/213793

你可能感兴趣的文章
怎么清除火狐浏览器的cookie?
查看>>
连麦介绍
查看>>
MQTT 客户端源码分析
查看>>
IT思想类智力题
查看>>
php设计模式-单例模式
查看>>
php扩展php-redis安装与使用
查看>>
python一天一题(2)
查看>>
[HTML5] Semantics for accessibility
查看>>
Win10下安装Ubuntu16.04虚拟机并搭建TensorFlow1.3环境
查看>>
leetcode 108. Convert Sorted Array to Binary Search Tree
查看>>
【商城购物车】购物车逻辑
查看>>
PCIE协议解析 synopsys IP loopback 读书笔记(1)
查看>>
关于小程序你需要知道的事
查看>>
表服务器无法打开与报表服务器数据库的连接。所有请求和处理都要求与数据库建立连接...
查看>>
4月第4周业务风控关注 | 网络犯罪经济每年1.5万亿美元 GDP居全球第12位
查看>>
idea中gitlab新创建分支查找不到的原因
查看>>
php调试时echo,print_r(),var_dump()的区别
查看>>
vue 作用域插槽
查看>>
tfs 2013 利用 web deploy 完成asp.net站点自动发布
查看>>
dom对象常用的属性和方法有哪些?
查看>>