インデックス
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のみ
- サポートされているインデックスアクセス方法:
Hash
、Gist
、Gin
、SpGist
、および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
フィールドを宣言します
model Id {
id String @id @db.VarChar(3000)
}
これはMySQLでは無効です。MySQLのインデックスストレージ制限を超えるため、Prisma ORMはデータモデルを拒否します。生成されたSQLはデータベースによって拒否されます。
CREATE TABLE `Id` (
`id` VARCHAR(3000) PRIMARY KEY
)
length
引数を使用すると、id
値の部分文字列のみが主キーを表すように指定できます。以下の例では、最初の100文字が使用されます
model Id {
id String @id(length: 100) @db.VarChar(3000)
}
Prisma Migrateは、データモデルで指定されている場合、length
引数を使用して制約とインデックスを作成できます。これは、Prismaスキーマ型Byte
およびString
の値にインデックスと制約を作成できることを意味します。引数を指定しない場合、インデックスは以前と同様に値全体をカバーするものとして扱われます。
イントロスペクションは、既存のデータベースに存在する場合、これらの制限を取得します。これにより、Prisma ORMは以前は抑制されていたインデックスと制約をサポートできるようになり、この機能を活用しているMySQLデータベースのサポートが向上します。
length
引数は、以下の例のように、@@id
属性を使用して複合主キーにも使用できます
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)
)
は、イントロスペクションによって次のように解釈されます
model Unique {
unique Int @unique(sort: Desc)
}
sort
引数は複合インデックスにも使用できます
model CompoundUnique {
unique_1 Int
unique_2 Int
@@unique([unique_1(sort: Desc), unique_2])
}
例:sort
とlength
を一緒に使用する
次の例は、Post
モデルのインデックスと制約を構成するためのsort
引数とlength
引数の使用方法を示しています
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
インデックスアクセス方法に加えて、Hash
、Gist
、Gin
、SpGist
、およびBrin
です。type
引数は、バージョン4.0.0以降で一般公開されています。Hash
インデックスアクセス方法はバージョン3.6.0以降のextendedIndexes
プレビュー機能の一部として利用でき、Gist
、Gin
、SpGist
、およびBrin
インデックスアクセス方法はバージョン3.14.0以降のプレビューで利用できます。
Hash
Hash
タイプは、インデックスデータを検索と挿入がはるかに高速で、ディスク容量を少なくする形式で保存します。ただし、=
および<>
比較のみがインデックスを使用できるため、<
や>
などの他の比較演算子は、デフォルトのBTree
タイプを使用する場合よりもHash
の方がはるかに遅くなります。
例として、次のモデルは、Hash
のtype
を持つインデックスをvalue
フィールドに追加します
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
フィールドに追加します
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でも利用可能 |
JsonbOps | Json (@db.JsonB ) | ✅ | CockroachDBでも利用可能 |
JsonbPathOps | Json (@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
フィールドに追加します
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
関数を使用すると、検証なしでこれらの演算子クラスを使用できます。
演算子クラス | 許可されているフィールドタイプ(許可されているネイティブタイプ) |
---|---|
InetOps | String (@db.Inet ) |
raw("other") |
組み込み演算子クラスの詳細については、公式PostgreSQLドキュメントを参照してください。
Space-Partitioned GiST (SP-GiST)
SP-GiSTインデックスは、多くの異なる非平衡データ構造に適しています。クエリがパーティション分割ルールに一致する場合、非常に高速になる可能性があります。
GiSTと同様に、SP-GiSTはユーザー定義タイプの構成要素として重要であり、データベースでカスタム検索演算子を直接実装できます。
例として、次のモデルは、TextOps
をインデックスを使用する演算子として、SpGist
インデックスをvalue
フィールドに追加します
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バージョン |
---|---|---|---|
InetOps | String (@db.Inet ) | ✅ | 10+ |
TextOps | String (@db.Text 、@db.VarChar ) | ✅ | |
raw("other") |
組み込み演算子クラスの詳細については、公式PostgreSQLドキュメントを参照してください。
Block Range Index (BRIN)
BRINインデックスタイプは、日付や時刻の値など、挿入後に変更されない大量のデータがある場合に役立ちます。データがインデックスに適している場合、最小限のスペースで大量のデータセットを格納できます。
例として、次のモデルは、Int4BloomOps
をインデックスを使用する演算子として、Brin
インデックスをvalue
フィールドに追加します
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バージョン |
---|---|---|---|
BitMinMaxOps | String (@db.Bit ) | ✅ | |
VarBitMinMaxOps | String (@db.VarBit ) | ✅ | |
BpcharBloomOps | String (@db.Char ) | 14+ | |
BpcharMinMaxOps | String (@db.Char ) | ✅ | |
ByteaBloomOps | Bytes (@db.Bytea ) | 14+ | |
ByteaMinMaxOps | Bytes (@db.Bytea ) | ✅ | |
DateBloomOps | DateTime (@db.Date ) | 14+ | |
DateMinMaxOps | DateTime (@db.Date ) | ✅ | |
DateMinMaxMultiOps | DateTime (@db.Date ) | 14+ | |
Float4BloomOps | Float (@db.Real ) | 14+ | |
Float4MinMaxOps | Float (@db.Real ) | ✅ | |
Float4MinMaxMultiOps | Float (@db.Real ) | 14+ | |
Float8BloomOps | Float (@db.DoublePrecision ) | 14+ | |
Float8MinMaxOps | Float (@db.DoublePrecision ) | ✅ | |
Float8MinMaxMultiOps | Float (@db.DoublePrecision ) | 14+ | |
InetInclusionOps | String (@db.Inet ) | ✅ | 14+ |
InetBloomOps | String (@db.Inet ) | 14+ | |
InetMinMaxOps | String (@db.Inet ) | ||
InetMinMaxMultiOps | String (@db.Inet ) | 14+ | |
Int2BloomOps | Int (@db.SmallInt ) | 14+ | |
Int2MinMaxOps | Int (@db.SmallInt ) | ✅ | |
Int2MinMaxMultiOps | Int (@db.SmallInt ) | 14+ | |
Int4BloomOps | Int (@db.Integer ) | 14+ | |
Int4MinMaxOps | Int (@db.Integer ) | ✅ | |
Int4MinMaxMultiOps | Int (@db.Integer ) | 14+ | |
Int8BloomOps | BigInt (@db.BigInt ) | 14+ | |
Int8MinMaxOps | BigInt (@db.BigInt ) | ✅ | |
Int8MinMaxMultiOps | BigInt (@db.BigInt ) | 14+ | |
NumericBloomOps | Decimal (@db.Decimal ) | 14+ | |
NumericMinMaxOps | Decimal (@db.Decimal ) | ✅ | |
NumericMinMaxMultiOps | Decimal (@db.Decimal ) | 14+ | |
OidBloomOps | Int (@db.Oid ) | 14+ | |
OidMinMaxOps | Int (@db.Oid ) | ✅ | |
OidMinMaxMultiOps | Int (@db.Oid ) | 14+ | |
TextBloomOps | String (@db.Text 、@db.VarChar ) | 14+ | |
TextMinMaxOps | String (@db.Text 、@db.VarChar ) | ✅ | |
TextMinMaxMultiOps | String (@db.Text 、@db.VarChar ) | 14+ | |
TimestampBloomOps | DateTime (@db.Timestamp ) | 14+ | |
TimestampMinMaxOps | DateTime (@db.Timestamp ) | ✅ | |
TimestampMinMaxMultiOps | DateTime (@db.Timestamp ) | 14+ | |
TimestampTzBloomOps | DateTime (@db.Timestamptz ) | 14+ | |
TimestampTzMinMaxOps | DateTime (@db.Timestamptz ) | ✅ | |
TimestampTzMinMaxMultiOps | DateTime (@db.Timestamptz ) | 14+ | |
TimeBloomOps | DateTime (@db.Time ) | 14+ | |
TimeMinMaxOps | DateTime (@db.Time ) | ✅ | |
TimeMinMaxMultiOps | DateTime (@db.Time ) | 14+ | |
TimeTzBloomOps | DateTime (@db.Timetz ) | 14+ | |
TimeTzMinMaxOps | DateTime (@db.Timetz ) | ✅ | |
TimeTzMinMaxMultiOps | DateTime (@db.Timetz ) | 14+ | |
UuidBloomOps | String (@db.Uuid ) | 14+ | |
UuidMinMaxOps | String (@db.Uuid ) | ✅ | |
UuidMinMaxMultiOps | String (@db.Uuid ) | 14+ | |
raw("other") |
組み込み演算子クラスの詳細については、公式PostgreSQLドキュメントを参照してください。
clustered
を使用したインデックスのクラスタ化または非クラスタ化の構成(SQL Server)
clustered
引数は、SQL Serverで(非)クラスタ化インデックスを構成するために使用できます。これは、@id
、@@id
、@unique
、@@unique
、および@@index
属性で使用できます。これはバージョン4.0.0以降で一般公開されており、バージョン3.13.0以降ではextendedIndexes
プレビュー機能の一部として利用できます。
例として、次のモデルは、@id
を(クラスタ化されたデフォルトではなく)非クラスタ化されるように構成します
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
のデフォルト値は次のとおりです
属性 | 値 |
---|---|
@id | true |
@@id | true |
@unique | false |
@@unique | false |
@@index | false |
テーブルが持つことができるクラスタ化インデックスは最大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
インデックスタイプのみがサポートされていました。その他のサポートされているインデックス(Hash
、Gist
、Gin
、SpGist
、および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
機能フラグを追加します
generator client {
provider = "prisma-client-js"
previewFeatures = ["fullTextIndex"]
}
例
次の例は、Post
モデルのtitle
フィールドとcontent
フィールドに@@fulltext
インデックスを追加する方法を示しています
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
フィールドを降順でソートします
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で再度移行します。これを行わない場合、既存のインデックスは代わりに削除され、通常のインデックスが代わりに作成されます。