use*_*760 2 postgresql index database-design unique-constraint
Postgres 文档说:
使用索引来强制唯一约束可以被视为不应直接访问的实现细节。但是,应该注意没有必要在唯一的列上手动创建索引;这样做只会复制自动创建的索引。
基于此,如果我想要一个列上的表达式索引并且还希望该列是唯一的,那么case 2
下面会更好,因为它可以使用单个索引完成上述操作。而case 1
由于唯一约束而自动创建一个索引,而另一个因为我需要小写索引而自动创建?
正如@Colin'tHart 指出的那样,这两种情况不一样。我应该在不使用lower()
表达式的情况下发布这个问题。在那种情况下,我的理解是 aCREATE UNIQUE INDEX
比唯一约束和简单索引更好。
基于此,如果我想要text_pattern_ops
在列上使用运算符类(例如)的索引并且还希望该列是唯一的,那么case 2
下面会更好,因为它可以使用单个索引完成上述操作。而case 1
会因为唯一约束而自动创建一个索引,而另一个因为我需要不同的运算符类而自动创建?
情况1:
CREATE TABLE book (
id SERIAL PRIMARY KEY,
name text NOT NULL,
CONSTRAINT book_name_key UNIQUE (name)
);
CREATE INDEX book_name_like ON book (name text_pattern_ops);
Run Code Online (Sandbox Code Playgroud)
案例2:
CREATE TABLE book (
id SERIAL PRIMARY KEY,
name text NOT NULL
);
CREATE UNIQUE INDEX book_name_like ON book (name text_pattern_ops);
Run Code Online (Sandbox Code Playgroud)
有那么一刻我想一个可能能够使用预先存在的 text_pattern_ops
指数与USING INDEX
增加一个条款时UNIQUE CONSTRAINT
。但这失败了,因为:
Run Code Online (Sandbox Code Playgroud)ERROR: index "book2_name_like" does not have default sorting behavior
索引不能有表达式列,也不能是部分索引。此外,它必须是具有默认排序顺序的 b 树索引。这些限制确保索引等同于由常规
ADD PRIMARY KEY
或ADD UNIQUE
命令构建的索引。
例如,像这样的唯一索引将允许 FK 约束引用它,但性能很差,因为它不支持标准运算符。
手册:
请注意,你也应该,如果你想涉及普通查询创建的缺省操作符的索引
<
,<=
,>
,或>=
比较使用索引。
所以要回答这个问题:
如果您需要一个UNIQUE CONSTRAINT
(除其他原因外:用 FK 引用它),您的第一个带有约束和索引的变体是唯一的选择。此外,约束创建的索引的默认运算符类支持更多操作(如按默认排序顺序排序)。
如果您不需要任何这些,请使用您的第二个变体,因为很明显,只有一个索引的维护成本更低:只是一个UNIQUE text_pattern_ops
索引。
索引和约束的区别:
除了创建两个索引之外,还有另一种可能更可取的索引替代方法。手册:xxx
_pattern_ops
与默认操作符类的不同之处在于,这些值严格逐个字符地进行比较,而不是根据特定于语言环境的排序规则进行比较。
LIKE
当数据库不使用标准的“C”语言环境时,这使得这些运算符类适用于涉及模式匹配表达式(或 POSIX 正则表达式)的查询。
索引自动使用基础列的排序规则。
您可以创建没有排序规则的列(使用COLLATE "C"
)。然后默认运算符类的行为方式与text_pattern_ops
将相同- 加上索引可以与所有标准运算符一起使用。
CREATE TABLE book2 (
book_id serial PRIMARY KEY,
book text NOT NULL COLLATE "C" UNIQUE -- that's all!
);
Run Code Online (Sandbox Code Playgroud)
现在,LIKE
可以使用索引:
SELECT * FROM book2 WHERE book LIKE 'foo%';
Run Code Online (Sandbox Code Playgroud)
但ILIKE
仍然不能:
SELECT * FROM book2 WHERE book ILIKE 'foo%';
Run Code Online (Sandbox Code Playgroud)
考虑使用附加模块 pg_trgm 的三元索引以获得更通用的解决方案:
归档时间: |
|
查看次数: |
2813 次 |
最近记录: |