模型索引參考¶
索引類別方便建立資料庫索引。它們可以使用 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")
在 height
和 weight
欄位相乘的結果以及四捨五入到最接近整數的 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 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 索引。
除了 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 索引
。