我如何知道我的PostgreSQL服务器是否使用“C”语言环境?

k10s72fa  于 2023-06-22  发布在  PostgreSQL
关注(0)|答案(5)|浏览(213)

我正试图尽我所能优化我的PostgreSQL 8.3 DB表,我不确定是否需要对某些列使用varchar_pattern_ops,我正在对字符串的前N个字符执行LIKE。根据this documentationxxx_pattern_ops的使用只有在“……当服务器不使用标准的‘C’语言环境时”才是必要的。
有人能解释一下这是什么意思吗?如何检查我的数据库使用的区域设置?

uplii1fm

uplii1fm1#

目前一些区域设置[docs]只能在initdb时设置,但我认为与_pattern_ops相关的区域设置可以在运行时通过SET修改,LC_COLLATE。要查看设置值,可以使用SHOW命令。
例如:

SHOW LC_COLLATE

_pattern_ops索引在使用模式匹配构造(如LIKE或regexp)的列中非常有用。您仍然需要创建一个常规索引(没有_pattern_ops)来对索引进行相等搜索。因此,您必须考虑所有这些因素,以确定是否需要在表上使用这样的索引。
关于locale是什么,它是一组关于字符顺序,格式和类似事情的规则,这些规则因语言/国家而异。例如,区域设置fr_CA(加拿大的法语)可能与en_CA(加拿大的英语)有一些不同的排序规则(或显示数字的方式等)。标准的“C”语言环境是POSIX标准兼容的默认语言环境。只有严格的ASCII字符才有效,排序和格式规则主要是en_US(美国英语)的规则
在计算机中,locale是一组参数,用于定义用户的语言,国家和用户希望在其用户界面中看到的任何特殊变体偏好。通常,区域设置标识符至少由语言标识符和区域标识符组成。

du7egjpx

du7egjpx2#

从命令行:psql -l
或从psql接口:\l
示例输出:

List of databases
    Name     | Owner  | Encoding |   Collate   |    Ctype    | Access privileges
-------------+--------+----------+-------------+-------------+-------------------
 packrd      | packrd | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
 postgres    | packrd | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
 template0   | packrd | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/packrd        +
             |        |          |             |             | packrd=CTc/packrd
 template1   | packrd | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/packrd        +
             |        |          |             |             | packrd=CTc/packrd
(5 rows)
pexxcrt2

pexxcrt23#

好的,从我的观察来看,这个初始设置
initdb --locale=xxx

--locale=locale
       Specifies the locale to be used in this database. This is equivalent to specifying both --lc-collate and --lc-ctype.

基本上为之后创建的所有数据库指定“默认”区域设置(即它指定了默认模板template1的设置)。您可以使用不同的语言环境创建新数据库,如下所示:
区域设置不同于编码,您可以手动指定区域设置和/或编码:

CREATE DATABASE korean WITH ENCODING 'EUC_KR' LC_COLLATE='ko_KR.euckr' LC_CTYPE='ko_KR.euckr' TEMPLATE=template0;

如果你想手动调用它。
基本上,如果您不指定它,它将使用系统默认值,几乎从不使用“C”。
所以如果你的show LC_COLLATE返回除了"C"或"POSIX"以外的任何东西,那么你就没有使用standard C locale,你需要为你的索引指定xxx_pattern_ops。还要注意caveat,如果你想使用<、<=、>或>=操作符,你需要创建第二个没有xxx_pattern_ops标志的索引(除非你在数据库中使用标准C语言环境,这很少见)。对于==和LIKE(等等),你不需要第二个索引。如果你不需要LIKE,那么你可能也不需要带有xxx_pattern_ops的索引。
即使您的索引被定义为与“默认”(如

CREATE INDEX my_index_name
  ON table_name
  USING btree
  (identifier COLLATE pg_catalog."default");

这是不够的,除非默认的是“C”(或POSIX,相同的东西)排序规则,否则它不能用于像LIKE 'ABC%'这样的模式。你需要这样的东西:

CREATE INDEX my_index_name
  ON table_name
  USING btree
  (identifier COLLATE pg_catalog."default" varchar_pattern_ops);
webghufk

webghufk4#

如果你有选择的余地...
您可以使用C语言环境重新创建数据库集群。
initializing您的Postgres示例时,您需要将区域设置传递给initdb
无论服务器的默认区域设置或用户的区域设置是什么,都可以执行此操作。
不过,这是一个服务器管理命令,而不是数据库模式设计器的任务。集群包含服务器上的所有数据库,而不仅仅是您正在优化的数据库。
它会创建一个全新的集群,并且不会迁移任何现有的数据库或数据。这将是额外的工作。
此外,如果您可以考虑创建一个新的集群作为一种选择,那么您真的应该考虑使用PostgreSQL 8.4,它可以在CREATE DATABASE statement中指定per-database locales

tktrz96b

tktrz96b5#

还有另一种方法(假设你想检查它们,而不是修改它们):
检查文件/var/lib/postgres/data/postgresql.conf,应该可以找到以下行:

# These settings are initialized by initdb, but they can be changed.
lc_messages = 'en_US.UTF-8'                     # locale for system error message strings
lc_monetary = 'en_US.UTF-8'                     # locale for monetary formatting
lc_numeric = 'en_US.UTF-8'                      # locale for number formatting
lc_time = 'en_US.UTF-8'                         # locale for time formatting

相关问题