模型索引參考

索引類別方便建立資料庫索引。它們可以使用 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

位置引數 *expressions 允許在運算式和資料庫函式上建立功能索引。

例如

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

title 欄位的 lowercase 值上以遞減順序建立索引,並在 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。

MariaDB

MariaDB < 10.8 不支援索引排序。在這種情況下,會將遞減索引建立為一般索引。

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 Metadb_tablespace 選項中指定的表格空間中建立索引。如果未設定這些表格空間,則會在與表格相同的表格空間中建立索引。

另請參閱

如需 PostgreSQL 特定索引的清單,請參閱 django.contrib.postgres.indexes

opclasses

Index.opclasses

要用於此索引的 PostgreSQL 運算子類別的名稱。如果您需要自訂運算子類別,則必須為索引中的每個欄位提供一個。

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

除了 PostgreSQL 之外,其他資料庫會忽略 opclasses

使用 opclasses 時,需要 Index.name

condition

Index.condition

如果表格非常大,而您的查詢主要針對一組列,則將索引限制為該子集可能會很有用。將條件指定為 Q。例如,condition=Q(pages__gt=400) 會將超過 400 頁的記錄編入索引。

使用 condition 時,需要 Index.name

PostgreSQL 上的限制

PostgreSQL 要求條件中引用的函式必須標記為 IMMUTABLE。 Django 不會驗證這一點,但 PostgreSQL 會產生錯誤。這表示像是日期函式Concat這類的函式將不被接受。如果您將日期儲存在DateTimeField中,與datetime物件比較時,可能需要提供 tzinfo 引數,因為否則比較可能會因 Django 為查找所做的類型轉換而產生可變函式。

SQLite 的限制

SQLite 對於如何建立部分索引施加了限制

Oracle

Oracle 不支援部分索引。相反地,可以使用函式索引以及Case 運算式來模擬部分索引。

MySQL 和 MariaDB

由於 MySQL 和 MariaDB 皆不支援條件索引,因此 condition 引數將被忽略。

include

Index.include

要包含在覆蓋索引中作為非鍵值欄位的欄位名稱清單或元組。這允許索引掃描僅用於僅選擇包含欄位(include),並僅按索引欄位(fields)篩選的查詢。

例如

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

將允許對 headline 進行篩選,同時選取 pub_date,並僅從索引中擷取資料。

使用 include 會產生比使用多欄索引更小的索引,但缺點是,非鍵值欄位不能用於排序或篩選。

除了 PostgreSQL 之外,其他資料庫會忽略 include

使用 include 時,需要 Index.name

有關覆蓋索引的詳細資訊,請參閱 PostgreSQL 文件。

PostgreSQL 上的限制

PostgreSQL 支援覆蓋 B 樹和GiST 索引。 PostgreSQL 14+ 也支援覆蓋SP-GiST 索引

回到頂端