メインコンテンツにスキップ

インデックス

Prisma ORMを使用すると、データベースのインデックス、ユニーク制約、および主キー制約を構成できます。これはバージョン4.0.0以降で一般公開されています。バージョン3.5.0以降では、extendedIndexesプレビュー機能でこれを有効にできます。

バージョン3.6.0では、新しい@@fulltext属性を通じて、MySQLおよびMongoDBのフルテキストインデックスのイントロスペクションと移行のサポートも導入されました。これはfullTextIndexプレビュー機能を通じて利用できます。

警告

バージョン4.0.0より前のバージョンからアップグレードする場合、インデックス構成とフルテキストインデックスへのこれらの変更は、これらの機能をすでに使用しているデータベースがある場合、破壊的な変更になる可能性があります。アップグレード方法の詳細については、以前のバージョンからのアップグレードを参照してください。

インデックス構成

次の属性引数を使用して、インデックス、ユニーク制約、および主キー制約を構成できます

  • length引数を使用すると、String型およびBytes型でインデックスされる値の部分文字列の最大長を指定できます

    • @id@@id@unique@@unique、および@@index属性で使用可能
    • MySQLのみ
  • sort引数を使用すると、制約またはインデックスのエントリがデータベースに格納される順序を指定できます

    • すべてのデータベースの@unique@@unique、および@@index属性、およびSQL Serverの@idおよび@@id属性で使用可能
  • type引数を使用すると、PostgreSQLのデフォルトのBTreeアクセス方法以外のインデックスアクセス方法をサポートできます

    • @@index属性で使用可能
    • PostgreSQLのみ
    • サポートされているインデックスアクセス方法:HashGistGinSpGist、およびBrin
  • clustered引数を使用すると、制約またはインデックスがクラスタ化されているか非クラスタ化されているかを構成できます

    • @id@@id@unique@@unique、および@@index属性で使用可能
    • SQL Serverのみ

各機能が最初に導入されたバージョンについて詳しくは、リンク先のセクションを参照してください。

lengthを使用したインデックス長の構成(MySQL)

length引数はMySQLに固有のものであり、String型およびByte型の列にインデックスと制約を定義できます。これらの型の場合、MySQLでは、値の全体がMySQLのインデックスサイズの制限を超える場合に、インデックスされる値の部分文字列の最大長を指定する必要があります。詳細については、MySQLのドキュメントを参照してください。

length引数は、@id@@id@unique@@unique、および@@index属性で使用できます。これはバージョン4.0.0以降で一般公開されており、バージョン3.5.0以降ではextendedIndexesプレビュー機能の一部として利用できます。

例として、次のデータモデルは、最大長が3000文字のidフィールドを宣言します

schema.prisma
model Id {
id String @id @db.VarChar(3000)
}

これはMySQLでは無効です。MySQLのインデックスストレージ制限を超えるため、Prisma ORMはデータモデルを拒否します。生成されたSQLはデータベースによって拒否されます。

CREATE TABLE `Id` (
`id` VARCHAR(3000) PRIMARY KEY
)

length引数を使用すると、id値の部分文字列のみが主キーを表すように指定できます。以下の例では、最初の100文字が使用されます

schema.prisma
model Id {
id String @id(length: 100) @db.VarChar(3000)
}

Prisma Migrateは、データモデルで指定されている場合、length引数を使用して制約とインデックスを作成できます。これは、Prismaスキーマ型ByteおよびStringの値にインデックスと制約を作成できることを意味します。引数を指定しない場合、インデックスは以前と同様に値全体をカバーするものとして扱われます。

イントロスペクションは、既存のデータベースに存在する場合、これらの制限を取得します。これにより、Prisma ORMは以前は抑制されていたインデックスと制約をサポートできるようになり、この機能を活用しているMySQLデータベースのサポートが向上します。

length引数は、以下の例のように、@@id属性を使用して複合主キーにも使用できます

schema.prisma
model CompoundId {
id_1 String @db.VarChar(3000)
id_2 String @db.VarChar(3000)

@@id([id_1(length: 100), id_2(length: 10)])
}

同様の構文を@@uniqueおよび@@index属性にも使用できます。

sortを使用したインデックスのソート順序の構成

sort引数は、Prisma ORMでサポートされているすべてのデータベースで使用できます。これを使用すると、インデックスまたは制約のエントリがデータベースに格納される順序を指定できます。これは、データベースが特定のクエリにインデックスを使用できるかどうかに影響を与える可能性があります。

sort引数は、すべてのデータベースの@unique@@unique、および@@indexで使用できます。さらに、SQL Serverでは、@idおよび@@idでも使用できます。これはバージョン4.0.0以降で一般公開されており、バージョン3.5.0以降ではextendedIndexesプレビュー機能の一部として利用できます。

例として、次のテーブル

CREATE TABLE `Unique` (
`unique` INT,
CONSTRAINT `Unique_unique_key` UNIQUE (`unique` DESC)
)

は、イントロスペクションによって次のように解釈されます

schema.prisma
model Unique {
unique Int @unique(sort: Desc)
}

sort引数は複合インデックスにも使用できます

schema.prisma
model CompoundUnique {
unique_1 Int
unique_2 Int

@@unique([unique_1(sort: Desc), unique_2])
}

例:sortlengthを一緒に使用する

次の例は、Postモデルのインデックスと制約を構成するためのsort引数とlength引数の使用方法を示しています

schema.prisma
model Post {
title String @db.VarChar(300)
abstract String @db.VarChar(3000)
slug String @unique(sort: Desc, length: 42) @db.VarChar(3000)
author String
created_at DateTime

@@id([title(length: 100, sort: Desc), abstract(length: 10)])
@@index([author, created_at(sort: Desc)])
}

typeを使用したインデックスのアクセスタイプの構成(PostgreSQL)

type引数は、@@index属性を使用してPostgreSQLのインデックスタイプを構成するために使用できます。利用可能なインデックスアクセス方法は、デフォルトのBTreeインデックスアクセス方法に加えて、HashGistGinSpGist、およびBrinです。type引数は、バージョン4.0.0以降で一般公開されています。Hashインデックスアクセス方法はバージョン3.6.0以降のextendedIndexesプレビュー機能の一部として利用でき、GistGinSpGist、およびBrinインデックスアクセス方法はバージョン3.14.0以降のプレビューで利用できます。

Hash

Hashタイプは、インデックスデータを検索と挿入がはるかに高速で、ディスク容量を少なくする形式で保存します。ただし、=および<>比較のみがインデックスを使用できるため、<>などの他の比較演算子は、デフォルトのBTreeタイプを使用する場合よりもHashの方がはるかに遅くなります。

例として、次のモデルは、Hashtypeを持つインデックスをvalueフィールドに追加します

schema.prisma
model Example {
id Int @id
value Int

@@index([value], type: Hash)
}

これは、次のSQLコマンドに変換されます

CREATE TABLE "Example" (
id INT PRIMARY KEY,
value INT NOT NULL
);

CREATE INDEX "Example_value_idx" ON "Example" USING HASH (value);

Generalized Inverted Index (GIN)

GINインデックスは、配列やJsonBデータなどの複合値を格納します。これは、あるオブジェクトが別のオブジェクトの一部であるかどうかをクエリするのを高速化するのに役立ちます。これは、フルテキスト検索によく使用されます。

インデックス付きフィールドは、インデックスによって処理される演算子を定義する演算子クラスを定義できます。

警告

インデックス付きの値​​を決定するために関数(to_tsvectorなど)を使用するインデックスは、Prisma ORMではまだサポートされていません。この方法で定義されたインデックスは、prisma db pullでは表示されません。

例として、次のモデルは、JsonbPathOpsをインデックスを使用できる演算子のクラスとして、Ginインデックスをvalueフィールドに追加します

schema.prisma
model Example {
id Int @id
value Json
// ^ field type matching the operator class
// ^ operator class ^ index type

@@index([value(ops: JsonbPathOps)], type: Gin)
}

これは、次のSQLコマンドに変換されます

CREATE TABLE "Example" (
id INT PRIMARY KEY,
value JSONB NOT NULL
);

CREATE INDEX "Example_value_idx" ON "Example" USING GIN (value jsonb_path_ops);

JsonbPathOpsの一部として、@>演算子はインデックスによって処理され、value @> '{"foo": 2}'などのクエリを高速化します。

GINでサポートされている演算子クラス

Prisma ORMは、一般にPostgreSQLバージョン10以降で提供される演算子クラスをサポートしています。演算子クラスがフィールドタイプをPrisma ORMがまだサポートしていない型にする必要がある場合、文字列入力を伴うraw関数を使用すると、検証なしでこれらの演算子クラスを使用できます。

デフォルトの演算子クラス(✅でマーク)は、インデックス定義から省略できます。

演算子クラス許可されているフィールドタイプ(ネイティブタイプ)デフォルトその他
ArrayOps任意の配列CockroachDBでも利用可能
JsonbOpsJson@db.JsonBCockroachDBでも利用可能
JsonbPathOpsJson@db.JsonB
raw("other")

組み込み演算子クラスの詳細については、公式PostgreSQLドキュメントを参照してください。

CockroachDB

GINとBTreeは、CockroachDBでサポートされている唯一のインデックスタイプです。CockroachDBで動作するようにマークされた演算子クラスは、そのデータベースで許可されており、Prisma ORMでサポートされている唯一のものです。演算子クラスはPrismaスキーマ言語で定義できません。ops引数はCockroachDBでは不要であり、許可されていません。

Generalized Search Tree (GiST)

GiSTインデックスタイプは、ユーザー定義タイプのインデックス作成スキームを実装するために使用されます。デフォルトでは、GiSTインデックスの直接的な用途は多くありませんが、たとえば、B-TreeインデックスタイプはGiSTインデックスを使用して構築されています。

例として、次のモデルは、InetOpsをインデックスを使用する演算子として、Gistインデックスをvalueフィールドに追加します

schema.prisma
model Example {
id Int @id
value String @db.Inet
// ^ native type matching the operator class
// ^ index type
// ^ operator class

@@index([value(ops: InetOps)], type: Gist)
}

これは、次のSQLコマンドに変換されます

CREATE TABLE "Example" (
id INT PRIMARY KEY,
value INET NOT NULL
);

CREATE INDEX "Example_value_idx" ON "Example" USING GIST (value inet_ops);

value > '10.0.0.2'など、IPアドレスを比較するクエリは、インデックスを使用します。

GiSTでサポートされている演算子クラス

Prisma ORMは、一般にPostgreSQLバージョン10以降で提供される演算子クラスをサポートしています。演算子クラスがフィールドタイプをPrisma ORMがまだサポートしていない型にする必要がある場合、文字列入力を伴うraw関数を使用すると、検証なしでこれらの演算子クラスを使用できます。

演算子クラス許可されているフィールドタイプ(許可されているネイティブタイプ)
InetOpsString@db.Inet
raw("other")

組み込み演算子クラスの詳細については、公式PostgreSQLドキュメントを参照してください。

Space-Partitioned GiST (SP-GiST)

SP-GiSTインデックスは、多くの異なる非平衡データ構造に適しています。クエリがパーティション分割ルールに一致する場合、非常に高速になる可能性があります。

GiSTと同様に、SP-GiSTはユーザー定義タイプの構成要素として重要であり、データベースでカスタム検索演算子を直接実装できます。

例として、次のモデルは、TextOpsをインデックスを使用する演算子として、SpGistインデックスをvalueフィールドに追加します

schema.prisma
model Example {
id Int @id
value String
// ^ field type matching the operator class

@@index([value], type: SpGist)
// ^ index type
// ^ using the default ops: TextOps
}

これは、次のSQLコマンドに変換されます

CREATE TABLE "Example" (
id INT PRIMARY KEY,
value TEXT NOT NULL
);

CREATE INDEX "Example_value_idx" ON "Example" USING SPGIST (value);

value LIKE 'something%'などのクエリは、インデックスによって高速化されます。

SP-GiSTでサポートされている演算子クラス

Prisma ORMは、一般にPostgreSQLバージョン10以降で提供される演算子クラスをサポートしています。演算子クラスがフィールドタイプをPrisma ORMがまだサポートしていない型にする必要がある場合、文字列入力を伴うraw関数を使用すると、検証なしでこれらの演算子クラスを使用できます。

デフォルトの演算子クラス(✅でマーク)は、インデックス定義から省略できます。

演算子クラス許可されているフィールドタイプ(ネイティブタイプ)デフォルトサポートされているPostgreSQLバージョン
InetOpsString@db.Inet10+
TextOpsString@db.Text@db.VarChar
raw("other")

組み込み演算子クラスの詳細については、公式PostgreSQLドキュメントを参照してください。

Block Range Index (BRIN)

BRINインデックスタイプは、日付や時刻の値など、挿入後に変更されない大量のデータがある場合に役立ちます。データがインデックスに適している場合、最小限のスペースで大量のデータセットを格納できます。

例として、次のモデルは、Int4BloomOpsをインデックスを使用する演算子として、Brinインデックスをvalueフィールドに追加します

schema.prisma
model Example {
id Int @id
value Int
// ^ field type matching the operator class
// ^ operator class ^ index type

@@index([value(ops: Int4BloomOps)], type: Brin)
}

これは、次のSQLコマンドに変換されます

CREATE TABLE "Example" (
id INT PRIMARY KEY,
value INT4 NOT NULL
);

CREATE INDEX "Example_value_idx" ON "Example" USING BRIN (value int4_bloom_ops);

value = 2のようなクエリは、BTreeまたはHashインデックスで使用されるスペースのほんの一部を使用するインデックスを使用するようになります。

BRINでサポートされている演算子クラス

Prisma ORMは、一般にPostgreSQLバージョン10以降で提供される演算子クラスをサポートしており、一部のサポートされている演算子はPostgreSQLバージョン14以降でのみ利用可能です。演算子クラスがフィールドタイプをPrisma ORMがまだサポートしていない型にする必要がある場合、文字列入力を伴うraw関数を使用すると、検証なしでこれらの演算子クラスを使用できます。

デフォルトの演算子クラス(✅でマーク)は、インデックス定義から省略できます。

演算子クラス許可されているフィールドタイプ(ネイティブタイプ)デフォルトサポートされているPostgreSQLバージョン
BitMinMaxOpsString@db.Bit
VarBitMinMaxOpsString@db.VarBit
BpcharBloomOpsString@db.Char14+
BpcharMinMaxOpsString@db.Char
ByteaBloomOpsBytes@db.Bytea14+
ByteaMinMaxOpsBytes@db.Bytea
DateBloomOpsDateTime@db.Date14+
DateMinMaxOpsDateTime@db.Date
DateMinMaxMultiOpsDateTime@db.Date14+
Float4BloomOpsFloat@db.Real14+
Float4MinMaxOpsFloat@db.Real
Float4MinMaxMultiOpsFloat@db.Real14+
Float8BloomOpsFloat@db.DoublePrecision14+
Float8MinMaxOpsFloat@db.DoublePrecision
Float8MinMaxMultiOpsFloat@db.DoublePrecision14+
InetInclusionOpsString@db.Inet14+
InetBloomOpsString@db.Inet14+
InetMinMaxOpsString@db.Inet
InetMinMaxMultiOpsString@db.Inet14+
Int2BloomOpsInt@db.SmallInt14+
Int2MinMaxOpsInt@db.SmallInt
Int2MinMaxMultiOpsInt@db.SmallInt14+
Int4BloomOpsInt@db.Integer14+
Int4MinMaxOpsInt@db.Integer
Int4MinMaxMultiOpsInt@db.Integer14+
Int8BloomOpsBigInt@db.BigInt14+
Int8MinMaxOpsBigInt@db.BigInt
Int8MinMaxMultiOpsBigInt@db.BigInt14+
NumericBloomOpsDecimal@db.Decimal14+
NumericMinMaxOpsDecimal@db.Decimal
NumericMinMaxMultiOpsDecimal@db.Decimal14+
OidBloomOpsInt@db.Oid14+
OidMinMaxOpsInt@db.Oid
OidMinMaxMultiOpsInt@db.Oid14+
TextBloomOpsString@db.Text@db.VarChar14+
TextMinMaxOpsString@db.Text@db.VarChar
TextMinMaxMultiOpsString@db.Text@db.VarChar14+
TimestampBloomOpsDateTime@db.Timestamp14+
TimestampMinMaxOpsDateTime@db.Timestamp
TimestampMinMaxMultiOpsDateTime@db.Timestamp14+
TimestampTzBloomOpsDateTime@db.Timestamptz14+
TimestampTzMinMaxOpsDateTime@db.Timestamptz
TimestampTzMinMaxMultiOpsDateTime@db.Timestamptz14+
TimeBloomOpsDateTime@db.Time14+
TimeMinMaxOpsDateTime@db.Time
TimeMinMaxMultiOpsDateTime@db.Time14+
TimeTzBloomOpsDateTime@db.Timetz14+
TimeTzMinMaxOpsDateTime@db.Timetz
TimeTzMinMaxMultiOpsDateTime@db.Timetz14+
UuidBloomOpsString@db.Uuid14+
UuidMinMaxOpsString@db.Uuid
UuidMinMaxMultiOpsString@db.Uuid14+
raw("other")

組み込み演算子クラスの詳細については、公式PostgreSQLドキュメントを参照してください。

clusteredを使用したインデックスのクラスタ化または非クラスタ化の構成(SQL Server)

clustered引数は、SQL Serverで(非)クラスタ化インデックスを構成するために使用できます。これは、@id@@id@unique@@unique、および@@index属性で使用できます。これはバージョン4.0.0以降で一般公開されており、バージョン3.13.0以降ではextendedIndexesプレビュー機能の一部として利用できます。

例として、次のモデルは、@idを(クラスタ化されたデフォルトではなく)非クラスタ化されるように構成します

schema.prisma
model Example {
id Int @id(clustered: false)
value Int
}

これは、次のSQLコマンドに変換されます

CREATE TABLE [Example] (
id INT NOT NULL,
value INT,
CONSTRAINT [Example_pkey] PRIMARY KEY NONCLUSTERED (id)
)

各属性のclusteredのデフォルト値は次のとおりです

属性
@idtrue
@@idtrue
@uniquefalse
@@uniquefalse
@@indexfalse

テーブルが持つことができるクラスタ化インデックスは最大1つです。

以前のバージョンからのアップグレード

警告

これらのインデックス構成の変更は、特定の既存のPrismaスキーマを既存のデータベースに対して有効にする場合、破壊的な変更になる可能性があります。使用に必要なプレビュー機能を有効にした後、prisma db pullを実行して既存のデータベースをイントロスペクションし、Prisma Migrateを再度使用する前にPrismaスキーマを更新します。

破壊的な変更は、次の状況で発生する可能性があります

  • 既存のソート制約とインデックス:以前のバージョンのPrisma ORMでは、ソート順序が明示的に指定されていない場合、目的のソート順序は昇順であると想定されます。これは、降順のソート順序を使用している既存の制約またはインデックスがあり、データモデルでこれを最初に指定せずにデータベースを移行する場合、破壊的な変更になることを意味します。
  • 既存の長さ制約とインデックス:以前のバージョンのPrisma ORMでは、MySQLで長さが制約されたインデックスと制約をPrismaスキーマで表現できませんでした。したがって、prisma db pullはこれらを取得しておらず、手動で指定できませんでした。prisma db pushまたはprisma migrate devを実行すると、データベースにすでに存在する場合、これらは無視されました。これでこれらを指定できるようになったため、移行コマンドは、データモデルに欠落しているがデータベースに存在する場合、これらを削除するようになります。
  • BTree以外の既存のインデックス(PostgreSQL):以前のバージョンのPrisma ORMでは、デフォルトのBTreeインデックスタイプのみがサポートされていました。その他のサポートされているインデックス(HashGistGinSpGist、およびBrin)は、データベースを移行する前に追加する必要があります。
  • 既存の(非)クラスタ化インデックス(SQL Server):以前のバージョンのPrisma ORMでは、インデックスをクラスタ化または非クラスタ化として構成することをサポートしていませんでした。デフォルトを使用しないインデックスの場合、これらはデータベースを移行する前に追加する必要があります。

上記の各ケースでは、必要な場合にデータモデルでこれらのプロパティを適切に指定することにより、データベースへの不要な変更を防ぐことができます。これを行う最も簡単な方法は、prisma db pullを使用して既存の制約または構成を取得することです。または、これらの引数を手動で追加することもできます。これは、アップグレード後に最初にprisma db pushまたはprisma migrate devを使用する前に行う必要があります。

フルテキストインデックス(MySQLおよびMongoDB)

fullTextIndexプレビュー機能は、バージョン3.6.0以降のMySQLおよびMongoDBでのフルテキストインデックスのイントロスペクションと移行のサポートを提供します。これは、@@fulltext属性を使用して構成できます。データベース内の既存のフルテキストインデックスは、db pullでイントロスペクションした後、Prismaスキーマに追加され、Prismaスキーマに追加された新しいフルテキストインデックスは、Prisma Migrateを使用するとデータベースに作成されます。これにより、以前は機能していなかった一部のデータベーススキーマでの検証エラーも防止されます。

警告

今のところ、MongoDBのPrisma Clientでフルテキスト検索コマンドを有効にしていません。進捗状況は、MongoDB issueで確認できます。

fullTextIndexプレビュー機能を有効にする

fullTextIndexプレビュー機能を有効にするには、schema.prismaファイルのgeneratorブロックにfullTextIndex機能フラグを追加します

schema.prisma
generator client {
provider = "prisma-client-js"
previewFeatures = ["fullTextIndex"]
}

次の例は、Postモデルのtitleフィールドとcontentフィールドに@@fulltextインデックスを追加する方法を示しています

schema.prisma
model Post {
id Int @id
title String @db.VarChar(255)
content String @db.Text

@@fulltext([title, content])
}

MongoDBでは、@@fulltextインデックス属性(fullTextIndexプレビュー機能経由)をsort引数とともに使用して、フルテキストインデックスにフィールドを昇順または降順で追加できます。次の例は、Postモデルのtitleフィールドとcontentフィールドに@@fulltextインデックスを追加し、titleフィールドを降順でソートします

schema.prisma
generator js {
provider = "prisma-client-js"
previewFeatures = ["fullTextIndex"]
}

datasource db {
provider = "mongodb"
url = env("DATABASE_URL")
}

model Post {
id String @id @map("_id") @db.ObjectId
title String
content String

@@fulltext([title(sort: Desc), content])
}

以前のバージョンからのアップグレード

警告

これは、特定の既存のPrismaスキーマを既存のデータベースに対して有効にする場合、破壊的な変更になる可能性があります。使用に必要なプレビュー機能を有効にした後、prisma db pullを実行して既存のデータベースをイントロスペクションし、Prisma Migrateを再度使用する前にPrismaスキーマを更新します。

以前のバージョンのPrisma ORMでは、@@fulltext属性ではなく@@index属性を使用してフルテキストインデックスを変換していました。fullTextIndexプレビュー機能を有効にした後、prisma db pullを実行してこれらのインデックスを@@fulltextに変換してから、Prisma Migrateで再度移行します。これを行わない場合、既存のインデックスは代わりに削除され、通常のインデックスが代わりに作成されます。