# Django 3.2.11.dev 文档

# 模型索引参考

索引类便于创建数据库索引。它们可以使用 `Meta.indexes` 选项来添加。本文档解释了 `Index` 的 API 引用，其中包括 index options 。

引用内置索引

索引是在 `django.db.models.indexes` 中定义的，但为了方便，它们被导入到 `django.db.models` 中。标准的惯例是使用 `from django.db import models` 并将索引称为 `models. <IndexClass>`。

## `Index` 选项

class `Index`(*expressions, fields=(), name=None, db_tablespace=None, opclasses=(), condition=None, include=None)

  在数据库中创建一个索引（B 树）。

### `expressions`

`Index.``expressions`

New in Django 3.2.

Positional argument `*expressions` allows creating functional indexes on expressions and database functions.

例子：

    Index(Lower('title').desc(), 'pub_date', name='lower_title_date_idx')

creates an index on the lowercased value of the `title` field in descending order and the `pub_date` field in the default ascending order.

Another example:

    Index(F('height') * F('weight'), Round('weight'), name='calc_idx')

creates an index on the result of multiplying fields `height` and `weight` and the `weight` rounded to the nearest integer.

`Index.name` is required when using `*expressions`.

Restrictions on Oracle

Oracle requires functions referenced in an index to be marked as `DETERMINISTIC`. Django doesn't validate this but Oracle will error. This means that functions such as `Random()` aren't accepted.

PostgreSQL 的限制

PostgreSQL requires functions and operators referenced in an index to be marked as `IMMUTABLE`. Django doesn't validate this but PostgreSQL will error. This means that functions such as `Concat()` aren't accepted.

MySQL 和 MariaDB

Functional indexes are ignored with MySQL < 8.0.13 and MariaDB as neither supports them.

### `fields`

`Index.``fields`

需要索引字段的名称列表或元组。

默认情况下，索引是以每列的升序创建的。要为列定义一个降序索引，请在字段名前添加一个连字符。

例如 `Index(fields=['headline', '-pub_date'])` 将创建 SQL 为 `(headline, pub_date DESC)`。MySQL 上不支持索引排序。在这种情况下，降序索引会像普通索引一样被创建。

### `name`

`Index.``name`

索引的名称。如果没有提供 `name`，Django 会自动生成一个名称。为了兼容不同的数据库，索引名不能超过 30 个字符，并且不应该以数字（0-9）或下划线（_）开头。

抽象基类中的部分索引

你必须始终为索引指定一个唯一的名称。因此，通常不能在抽象基类上指定部分索引，因为 `Meta.indexes` 选项是由子类继承的，每次的属性值（包括 `name` ）都完全相同。为了解决名称碰撞的问题，名称的一部分可以包含 `'%(app_label)s'` 和 `'%(class)s'`，它们分别被具体模型的小写应用标签和类名所代替。例如 `Index(field=['title'], name='%(app_label)s_%(class)s_title_index')`。

### `db_tablespace`

`Index.``db_tablespace`

该索引要使用的 数据库表空间 名称。对于单字段索引，如果没有提供 `db_tablespace`，则在字段的 `db_tablespace` 中创建索引。

如果没有指定 `Field.db_tablespace` （或者如果索引使用了多个字段），则在模型的 `class Meta` 里面的 `db_tablespace` 选项中指定的表空间创建索引。如果这两个表空间都没有设置，则在与表相同的表空间中创建索引。

参见

关于 PostgreSQL 特有的索引列表，请参见 `django.contrib.postgres.indexes`。

### `opclasses`

`Index.``opclasses`

要为这个索引使用的 PostgreSQL 运算符类 名称。如果你需要一个自定义的操作类，你必须为索引中的每个字段提供一个操作类。

例如，`GinIndex(name='json_index', fields=['jsonfield'], opclasses=['jsonb_path_ops'])` 使用 `jsonb_path_ops` 在 `jsonfield` 上创建一个 gin 索引。

`opclasses` 对于 PostgreSQL 以外的数据库来说是被忽略的。

`Index.name` 在使用 `opclasses` 时需要。

### `condition`

`Index.``condition`

如果表非常大，而且你的查询主要针对行的子集，那么将索引限制在该子集上可能会很有用。将条件指定为 `Q`。例如，`condition=Q(pages__gt=400)` 对超过 400 页的记录进行索引。

`Index.name` 在使用 `condition` 时需要。

PostgreSQL 的限制

PostgreSQL 要求条件中引用的函数必须标记为 IMMUTABLE。Django 不会验证这一点，但 PostgreSQL 会报错。这意味着诸如 日期函数 和 `Concat` 这样的函数不被接受。如果你把日期存储在 `DateTimeField` 中，与 `datetime` 对象进行比较时，可能需要提供 `tzinfo` 参数，否则比较的结果可能是一个可变的函数，因为 Django 对 lookups 进行了转换。

SQLite 的限制

SQLite 对如何构建部分索引 施加了限制 。

Oracle

Oracle does not support partial indexes. Instead, partial indexes can be emulated by using functional indexes together with `Case` expressions.

MySQL 和 MariaDB

在 MySQL 和 MariaDB 中，`condition` 参数被忽略，因为它们都不支持条件索引。

### `include`

`Index.``include`

New in Django 3.2.

A list or tuple of the names of the fields to be included in the covering index as non-key columns. This allows index-only scans to be used for queries that select only included fields (`include`) and filter only by indexed fields (`fields`).

例子：

    Index(name='covering_index', fields=['headline'], include=['pub_date'])

will allow filtering on `headline`, also selecting `pub_date`, while fetching data only from the index.

Using `include` will produce a smaller index than using a multiple column index but with the drawback that non-key columns can not be used for sorting or filtering.

`include` is ignored for databases besides PostgreSQL.

`Index.name` is required when using `include`.

See the PostgreSQL documentation for more details about covering indexes.

PostgreSQL 的限制

PostgreSQL 11+ only supports covering B-Tree indexes, and PostgreSQL 12+ also supports covering `GiST indexes`.