简答:大多数数据库都制作索引以提高唯一性约束的检查。
构造它的查询将在数据库端创建一个索引。事实上,如果你创建一个UniqueConstraint [GitHub],那么它会调用使用create_sql method [GitHub] 来生成SQL 查询来创建这个约束:
def create_sql(self, model, schema_editor):
fields = [model._meta.get_field(field_name).column for field_name in self.fields]
condition = self._get_condition_sql(model, schema_editor)
return schema_editor._create_unique_sql(
model, fields, self.name, condition=condition,
deferrable=self.deferrable,
)
如果数据库支持supports_partial_indexes 功能,则此_create_unique_sql function [GitHub] 将检查它是否必须建立索引:
def _create_unique_sql(self, model, columns, name=None, condition=None, deferrable=None):
if (
deferrable and
not self.connection.features.supports_deferrable_unique_constraints
):
return None
def create_unique_name(*args, **kwargs):
return self.quote_name(self._create_index_name(*args, **kwargs))
table = Table(model._meta.db_table, self.quote_name)
if name is None:
name = IndexName(model._meta.db_table, columns, '_uniq', create_unique_name)
else:
name = self.quote_name(name)
columns = Columns(table, columns, self.quote_name)
if condition:
if not self.connection.features.supports_partial_indexes:
return None
sql = self.sql_create_unique_index
else:
sql = self.sql_create_unique
return Statement(
sql,
table=table,
name=name,
columns=columns,
condition=self._index_condition_sql(condition),
deferrable=self._deferrable_constraint_sql(deferrable),
)
这个sql_create_unique_index [GitHub] 的值为:
sql_create_unique_index = "CREATE UNIQUE INDEX %(name)s ON %(table)s (%(columns)s)%(condition)s"
因此,这将创建一个索引,并加快查找速度。
然而,并非所有数据库都需要明确创建索引。例如,对于 MySQL,它将创建一个如下所示的查询:
--
-- Create constraint ij_unique on model foo
--
ALTER TABLE `app_name_foo` ADD CONSTRAINT `ij_unique` UNIQUE (`i`, `j`);
但是正如我们在MySQL documentation on Creating table indexes keys 中看到的,这也会创建一个数据库索引。例如,如果我们检查索引,我们会看到:
mysql> show index from app_name_foo;
+--------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| app_name_foo | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE | | |
| app_name_foo | 0 | ij_unique | 1 | i | A | 0 | NULL | NULL | | BTREE | | |
| app_name_foo | 0 | ij_unique | 2 | j | A | 0 | NULL | NULL | | BTREE | | |
+--------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+