模型索引参考

    引用内置索引

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

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

    在数据库中创建一个索引(B 树)。

    Index.expressions

    New in Django 3.2.

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

    例子:

    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:

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

    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 aren’t accepted.

    MySQL 和 MariaDB

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

    fields

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

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

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

    Index.name

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

    抽象基类中的部分索引

    你必须始终为索引指定一个唯一的名称。因此,通常不能在抽象基类上指定部分索引,因为 选项是由子类继承的,每次的属性值(包括 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 里面的 选项中指定的表空间创建索引。如果这两个表空间都没有设置,则在与表相同的表空间中创建索引。

    参见

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

    Index.opclasses

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

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

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

    Index.name 在使用 opclasses 时需要。

    condition

    Index.condition

    Index.name 在使用 condition 时需要。

    PostgreSQL 的限制

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

    SQLite 的限制

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

    Oracle

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

    MySQL 和 MariaDB

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

    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 ().

    例子:

    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 .

    See the PostgreSQL documentation for more details about .

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