sql – 为什么Django显式地在唯一字段上创建索引

前端之家收集整理的这篇文章主要介绍了sql – 为什么Django显式地在唯一字段上创建索引前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
更新:进一步简化实验psql的Q:

对于以下Django模型:

class Book(models.Model):
    name = models.TextField(unique=True)

pg_dump(Postgresql 9.3)显示下表&限制:

CREATE TABLE book (
    id integer NOT NULL,name text NOT NULL,);

ALTER TABLE ONLY book ADD CONSTRAINT book_name_key UNIQUE (name);

CREATE INDEX book_name_like ON book USING btree (name text_pattern_ops);

但是Postgresql documentation说:

Postgresql automatically creates a unique index when a unique
constraint […] is defined for a table.

[…] there’s
no need to manually create indexes on unique columns; doing so would
just duplicate the automatically-created index.

问题:为什么Django会在一个唯一的列上创建索引呢?也许理由是它使用运算符类text_pattern_ops,因此Django需要添加另一个索引.如果是这种情况,更好的方法是将Django解释为unique = True约束,如下所示:

CREATE UNIQUE INDEX book_name_like ON book USING btree (name text_pattern_ops);

根本没有列中的UNIQUE约束.因此,带有text_pattern_ops的单个UNIQUE INDEX将导致DB不为UNIQUE约束创建隐式索引.

解决方法

问题的核心是 Django documentation中的这种保证:

Note that when unique is True you don’t need to specify db_index,because unique implies the creation of an index.

因此,通过Django的契约,unique = True意味着db_index = True,而db_index = True意味着Django必须创建text_pattern_ops索引以支持所有查找类型(参见ticket 12234).

至于仅使用一个唯一索引,PostgreSQL documentation表示不会涵盖所有查找类型:

Note that you should also create an index with the default operator class if you want queries involving ordinary <,<=,>,or >= comparisons to use an index. Such queries cannot use the xxx_pattern_ops operator classes.

您可以尝试添加unique = True和db_index = False.

猜你在找的MsSQL相关文章