Краткий ответ : большинство баз данных создают индексы, чтобы сделать проверку ограничений уникальности эффективной.
Запрос для его создания создаст индекс на стороне базы данных. Действительно, если вы создадите UniqueConstraint
[GitHub] , тогда он вызовет метод create_sql
[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.<b>_create_unique_sql(</b>
model, fields, self.name, condition=condition,
deferrable=self.deferrable,
<b>)</b>
Эта _create_unique_sql
функция [GitHub] будет, тогда также проверьте, нужно ли создавать индекс, учитывая, что база данных поддерживает функцию supports_partial_indexes
:
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.<b>features.supports_partial_indexes</b>:
return None
<b>sql = self.sql_create_unique_index</b>
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` <b>UNIQUE</b> (`i`, `j`);
Но, как мы видим в документации MySQL по Создание ключей индексов таблиц , это также создаст индекс базы данных. Если мы, например, проверим индексы, мы увидим:
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 | | |
+--------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+