模型索引参考 — Django 文档

来自菜鸟教程
Django/docs/3.2.x/ref/models/indexes
跳转至:导航、​搜索

型号索引参考

索引类简化了创建数据库索引的过程。 可以使用 Meta.indexes 选项添加它们。 本文档解释了 Index 的 API 参考,其中包括 索引选项

引用内置索引

索引在 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

3.2 版中的新功能。


位置参数 *expressions 允许在表达式和数据库函数上创建函数索引。

例如:

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

按降序在 title 字段的小写值和按默认升序的 pub_date 字段的小写值上创建索引。

另一个例子:

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

在将字段 heightweight 以及舍入为最接近的整数的 weight 相乘的结果上创建索引。

使用 *expressions 时需要 Index.name

对 Oracle 的限制

Oracle 要求将索引中引用的函数标记为 DETERMINISTIC。 Django 不会验证这一点,但 Oracle 会出错。 这意味着不接受诸如 Random() 之类的函数。


对 PostgreSQL 的限制

PostgreSQL 要求将索引中引用的函数和运算符标记为 IMMUTABLE。 Django 不会验证这一点,但 PostgreSQL 会出错。 这意味着不接受诸如 Concat() 之类的函数。


MySQL 和 MariaDB

MySQL < 8.0.13 和 MariaDB 会忽略功能索引,因为它们都不支持。


fields

Index.fields

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

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

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


name

Index.name

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

抽象基类中的部分索引

您必须始终为索引指定唯一名称。 因此,您通常不能在抽象基类上指定部分索引,因为 Meta.indexes 选项由子类继承,属性值完全相同(包括 name)每一次。 为了解决名称冲突,部分名称可能包含 '%(app_label)s''%(class)s',分别由具体模型的小写应用程序标签和类名称替换。 例如Index(fields=['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_opsjsonfield 上创建一个 gin 索引。

opclasses 对于 PostgreSQL 以外的数据库将被忽略。

使用 opclasses 时需要 Index.name


condition

Index.condition

如果表非常大并且您的查询主要针对行的子集,则将索引限制为该子集可能很有用。 将条件指定为 Q。 例如,condition=Q(pages__gt=400) 索引超过 400 页的记录。

使用 condition 时需要 Index.name

对 PostgreSQL 的限制

PostgreSQL 要求将条件中引用的函数标记为 IMMUTABLE。 Django 不会验证这一点,但 PostgreSQL 会出错。 这意味着不接受诸如 Date 函数Concat 之类的函数。 如果您将日期存储在 DateTimeField 中,与 datetime 对象的比较可能需要提供 tzinfo 参数,否则比较可能会由于转换 Django 而导致可变函数用于 查找


SQLite 的限制

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


甲骨文

Oracle 不支持部分索引。 相反,可以通过将功能索引与 Case 表达式一起使用来模拟部分索引。


MySQL 和 MariaDB

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


include

Index.include

3.2 版中的新功能。


要作为非键列包含在覆盖索引中的字段名称的列表或元组。 这允许仅索引扫描用于仅选择包含字段 (include) 和仅按索引字段过滤 (fields) 的查询。

例如:

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

将允许过滤 headline,同时选择 pub_date,同时仅从索引中获取数据。

使用 include 将产生比使用多列索引更小的索引,但缺点是非键列不能用于排序或过滤。

include 对于 PostgreSQL 以外的数据库被忽略。

使用 include 时需要 Index.name

有关 覆盖索引 的更多详细信息,请参阅 PostgreSQL 文档。

对 PostgreSQL 的限制

PostgreSQL 11+ 只支持覆盖 B-Tree 索引,PostgreSQL 12+ 也支持覆盖 GiST 索引