モデルインデックスリファレンス
インデックスクラスは、データベースインデックスの作成を容易にします。 Meta.indexes オプションを使用して追加できます。 このドキュメントでは、インデックスオプションを含むインデックスの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')
フィールド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を作成します。 インデックスの順序付けは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 オプションで指定されたテーブルスペースに作成されます。 。 これらのテーブルスペースのどちらも設定されていない場合、インデックスはテーブルと同じテーブルスペースに作成されます。
opclasses
- Index.opclasses
このインデックスに使用する PostgreSQLオペレータークラスの名前。 カスタム演算子クラスが必要な場合は、インデックスの各フィールドに1つずつ指定する必要があります。
たとえば、GinIndex(name='json_index', fields=['jsonfield'], opclasses=['jsonb_path_ops'])は、jsonb_path_opsを使用してjsonfieldにジンインデックスを作成します。
opclassesは、PostgreSQL以外のデータベースでは無視されます。
opclassesを使用する場合は、 Index.name が必要です。
condition
- Index.condition
テーブルが非常に大きく、クエリのほとんどが行のサブセットを対象としている場合は、インデックスをそのサブセットに制限すると便利な場合があります。 条件を Q として指定します。 たとえば、condition=Q(pages__gt=400)は、400ページを超えるレコードにインデックスを付けます。
conditionを使用する場合は、 Index.name が必要です。
PostgreSQLの制限
PostgreSQLでは、条件で参照される関数をIMMUTABLEとしてマークする必要があります。 Djangoはこれを検証しませんが、PostgreSQLはエラーになります。 これは、日付関数や連結などの関数が受け入れられないことを意味します。 日付を DateTimeField に格納する場合、datetimeオブジェクトとの比較では、tzinfo引数を指定する必要があります。そうしないと、Djangoのキャストにより、比較によって可変関数が発生する可能性があります。 ルックアップに対して行います。
MySQLとMariaDB
condition引数は、MySQLとMariaDBではどちらも条件付きインデックスをサポートしていないため、無視されます。
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のドキュメントを参照してください。