对于以下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 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约束创建隐式索引.
解决方法
Note that when
unique
isTrue
you don’t need to specifydb_index
,becauseunique
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.