跳到主要內容

索引

Prisma ORM 允許設定資料庫索引、唯一約束和主鍵約束。這在 4.0.0 及更高版本中為正式發行版。您可以在 3.5.0 及更高版本中使用 extendedIndexes 預覽功能啟用此功能。

3.6.0 版本也引入了透過新的 @@fulltext 屬性支援 MySQL 和 MongoDB 中全文索引的內省和遷移,此屬性可透過 fullTextIndex 預覽功能取得。

警告

如果您是從早於 4.0.0 的版本升級,如果您已經有一個使用這些功能的資料庫,則索引配置和全文索引的這些變更可能是重大變更。請參閱從先前版本升級,以取得有關如何升級的更多資訊。

索引配置

您可以使用以下屬性引數配置索引、唯一約束和主鍵約束

  • length 引數可讓您指定要在 StringBytes 類型上建立索引的值子部分的最大長度

    • 適用於 @id@@id@unique@@unique@@index 屬性
    • 僅限 MySQL
  • sort 引數可讓您指定約束或索引的條目在資料庫中儲存的順序

    • 適用於所有資料庫中的 @unique@@unique@@index 屬性,以及 SQL Server 中的 @id@@id 屬性
  • type 引數可讓您支援 PostgreSQL 預設 BTree 存取方法以外的索引存取方法

    • 適用於 @@index 屬性
    • 僅限 PostgreSQL
    • 支援的索引存取方法:HashGistGinSpGistBrin
  • clustered 引數可讓您設定約束或索引是否為叢集式或非叢集式

    • 適用於 @id@@id@unique@@unique@@index 屬性
    • 僅限 SQL Server

請參閱連結章節以了解每個功能首次推出的版本詳細資訊。

使用 length 配置索引長度 (MySQL)

length 引數是 MySQL 特有的,可讓您在 StringByte 類型的欄位上定義索引和約束。對於這些類型,在完整值超出 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)
}

如果您的資料模型中指定了 length 引數,Prisma Migrate 便能夠建立具有該引數的約束和索引。這表示您可以在 Prisma 結構描述類型 ByteString 的值上建立索引和約束。如果您未指定引數,則索引會像以前一樣被視為涵蓋完整值。

內省功能將擷取現有資料庫中存在的這些限制。這可讓 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

以下範例示範如何使用 sortlength 引數來配置 Post 模型的索引和約束

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 引數可用於在 PostgreSQL 中使用 @@index 屬性配置索引類型。可用的索引存取方法有 HashGistGinSpGistBrin,以及預設的 BTree 索引存取方法。type 引數通常在 4.0.0 及更高版本中提供。Hash 索引存取方法在 3.6.0 及更高版本中作為 extendedIndexes 預覽功能的一部分提供,而 GistGinSpGistBrin 索引存取方法在 3.14.0 及更高版本中以預覽版提供。

Hash

Hash 類型將以更快的搜尋和插入速度以及更少的磁碟空間來儲存索引資料。但是,只有 =<> 比較可以使用索引,因此使用 Hash 時,其他比較運算子 (例如 <>) 會比使用預設 BTree 類型慢得多。

例如,以下模型將 Hash 類型的索引新增至 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);

廣義反向索引 (GIN)

GIN 索引儲存複合值,例如陣列或 JsonB 資料。這對於加速查詢某個物件是否為另一個物件的一部分非常有用。它通常用於全文搜尋。

索引欄位可以定義運算子類別,該類別定義索引處理的運算子。

警告

Prisma ORM 尚不支援使用函數 (例如 to_tsvector) 來決定索引值的索引。以這種方式定義的索引將不會透過 prisma db pull 可見。

例如,以下模型將 Gin 索引新增至 value 欄位,並以 JsonbPathOps 作為允許使用索引的運算子類別

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.JsonB)也適用於 CockroachDB
JsonbPathOpsJson (@db.JsonB)
raw("other")

請在PostgreSQL 官方文件中閱讀有關內建運算子類別的更多資訊。

CockroachDB

GIN 和 BTree 是 CockroachDB 唯一支援的索引類型。標記為可與 CockroachDB 搭配使用的運算子類別是該資料庫上唯一允許且 Prisma ORM 支援的運算子類別。運算子類別無法在 Prisma 結構描述語言中定義:ops 引數在 CockroachDB 上不是必要或允許的。

廣義搜尋樹 (GiST)

GiST 索引類型用於為使用者定義類型實作索引配置。預設情況下,GiST 索引沒有太多直接用途,但例如,B 樹狀索引類型是使用 GiST 索引建立的。

例如,以下模型將 Gist 索引新增至 value 欄位,並以 InetOps 作為將使用索引的運算子

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);

比較 IP 位址的查詢 (例如 value > '10.0.0.2') 將使用索引。

GiST 的支援運算子類別

Prisma ORM 通常支援 PostgreSQL 10 及更高版本提供的運算子類別。如果運算子類別要求欄位類型為 Prisma ORM 尚不支援的類型,則使用帶有字串輸入的 raw 函數可讓您使用這些運算子類別而無需驗證。

運算子類別允許的欄位類型 (允許的原生類型)
InetOpsString (@db.Inet)
raw("other")

請在PostgreSQL 官方文件中閱讀有關內建運算子類別的更多資訊。

空間分割 GiST (SP-GiST)

對於許多不同的非平衡資料結構,SP-GiST 索引是一個不錯的選擇。如果查詢符合分割規則,則速度會非常快。

與 GiST 一樣,SP-GiST 作為使用者定義類型的建構區塊非常重要,可讓直接使用資料庫實作自訂搜尋運算子。

例如,以下模型將 SpGist 索引新增至 value 欄位,並以 TextOps 作為使用索引的運算子

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.Inet)10+
TextOpsString (@db.Text, @db.VarChar)
raw("other")

請從PostgreSQL 官方文件中閱讀有關內建運算子類別的更多資訊。

區塊範圍索引 (BRIN)

如果您有大量在插入後不會變更的資料 (例如日期和時間值),則 BRIN 索引類型很有用。如果您的資料非常適合索引,則可以最小的空間儲存大型資料集。

例如,以下模型將 Brin 索引新增至 value 欄位,並以 Int4BloomOps 作為將使用索引的運算子

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 之類的查詢現在將使用索引,該索引使用的空間僅為 BTreeHash 索引使用空間的一小部分。

BRIN 的支援運算子類別

Prisma ORM 通常支援 PostgreSQL 10 及更高版本提供的運算子類別,而某些支援的運算子僅在 PostgreSQL 14 及更高版本中可用。如果運算子類別要求欄位類型為 Prisma ORM 尚不支援的類型,則使用帶有字串輸入的 raw 函數可讓您使用這些運算子類別而無需驗證。

預設運算子類別 (以 ✅ 標記) 可以從索引定義中省略。

運算子類別允許的欄位類型 (原生類型)預設支援的 PostgreSQL 版本
BitMinMaxOpsString (@db.Bit)
VarBitMinMaxOpsString (@db.VarBit)
BpcharBloomOpsString (@db.Char)14+
BpcharMinMaxOpsString (@db.Char)
ByteaBloomOpsBytes (@db.Bytea)14+
ByteaMinMaxOpsBytes (@db.Bytea)
DateBloomOpsDateTime (@db.Date)14+
DateMinMaxOpsDateTime (@db.Date)
DateMinMaxMultiOpsDateTime (@db.Date)14+
Float4BloomOpsFloat (@db.Real)14+
Float4MinMaxOpsFloat (@db.Real)
Float4MinMaxMultiOpsFloat (@db.Real)14+
Float8BloomOpsFloat (@db.DoublePrecision)14+
Float8MinMaxOpsFloat (@db.DoublePrecision)
Float8MinMaxMultiOpsFloat (@db.DoublePrecision)14+
InetInclusionOpsString (@db.Inet)14+
InetBloomOpsString (@db.Inet)14+
InetMinMaxOpsString (@db.Inet)
InetMinMaxMultiOpsString (@db.Inet)14+
Int2BloomOpsInt (@db.SmallInt)14+
Int2MinMaxOpsInt (@db.SmallInt)
Int2MinMaxMultiOpsInt (@db.SmallInt)14+
Int4BloomOpsInt (@db.Integer)14+
Int4MinMaxOpsInt (@db.Integer)
Int4MinMaxMultiOpsInt (@db.Integer)14+
Int8BloomOpsBigInt (@db.BigInt)14+
Int8MinMaxOpsBigInt (@db.BigInt)
Int8MinMaxMultiOpsBigInt (@db.BigInt)14+
NumericBloomOpsDecimal (@db.Decimal)14+
NumericMinMaxOpsDecimal (@db.Decimal)
NumericMinMaxMultiOpsDecimal (@db.Decimal)14+
OidBloomOpsInt (@db.Oid)14+
OidMinMaxOpsInt (@db.Oid)
OidMinMaxMultiOpsInt (@db.Oid)14+
TextBloomOpsString (@db.Text, @db.VarChar)14+
TextMinMaxOpsString (@db.Text, @db.VarChar)
TextMinMaxMultiOpsString (@db.Text, @db.VarChar)14+
TimestampBloomOpsDateTime (@db.Timestamp)14+
TimestampMinMaxOpsDateTime (@db.Timestamp)
TimestampMinMaxMultiOpsDateTime (@db.Timestamp)14+
TimestampTzBloomOpsDateTime (@db.Timestamptz)14+
TimestampTzMinMaxOpsDateTime (@db.Timestamptz)
TimestampTzMinMaxMultiOpsDateTime (@db.Timestamptz)14+
TimeBloomOpsDateTime (@db.Time)14+
TimeMinMaxOpsDateTime (@db.Time)
TimeMinMaxMultiOpsDateTime (@db.Time)14+
TimeTzBloomOpsDateTime (@db.Timetz)14+
TimeTzMinMaxOpsDateTime (@db.Timetz)
TimeTzMinMaxMultiOpsDateTime (@db.Timetz)14+
UuidBloomOpsString (@db.Uuid)14+
UuidMinMaxOpsString (@db.Uuid)
UuidMinMaxMultiOpsString (@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 配置為非叢集式 (而不是叢集式預設值)

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

一個表格最多只能有一個叢集式索引。

從先前版本升級

警告

當為現有資料庫的某些現有 Prisma 結構描述啟用功能時,這些索引配置變更可能是重大變更。在啟用使用它們所需的預覽功能後,再次使用 Prisma Migrate 之前,請執行 prisma db pull 以內省現有資料庫以更新您的 Prisma 結構描述。

在以下情況下可能會發生重大變更

  • 現有的排序約束和索引:如果未明確指定順序,則早期版本的 Prisma ORM 會假設所需的排序順序為遞增。這表示如果您現有的約束或索引正在使用遞減排序順序,並且在未先在資料模型中指定此順序的情況下遷移資料庫,則這將是重大變更。
  • 現有的長度約束和索引:在早期版本的 Prisma ORM 中,MySQL 中受長度約束的索引和約束無法在 Prisma 結構描述中表示。因此 prisma db pull 沒有擷取這些索引和約束,您也無法手動指定它們。當您執行 prisma db pushprisma migrate dev 時,如果它們已存在於您的資料庫中,則會被忽略。由於您現在可以指定這些索引和約束,因此如果它們在您的資料模型中遺失但存在於資料庫中,遷移命令現在將會捨棄它們。
  • BTree 以外的現有索引 (PostgreSQL):早期版本的 Prisma ORM 僅支援預設的 BTree 索引類型。其他支援的索引 (HashGistGinSpGistBrin) 需要在遷移資料庫之前新增。
  • 現有的 (非) 叢集式索引 (SQL Server):早期版本的 Prisma ORM 不支援將索引配置為叢集式或非叢集式。對於不使用預設值的索引,需要在遷移資料庫之前新增這些索引。

在上述每種情況下,都可以透過在資料模型中適當指定這些屬性來防止對資料庫進行不必要的變更。執行此操作的最簡單方法是使用 prisma db pull 來擷取任何現有的約束或配置。或者,您也可以手動新增這些引數。升級後第一次使用 prisma db pushprisma migrate dev 之前,應先完成此操作。

全文索引 (MySQL 和 MongoDB)

fullTextIndex 預覽功能在 3.6.0 及更高版本中提供對 MySQL 和 MongoDB 中全文索引的內省和遷移支援。可以使用 @@fulltext 屬性來配置此功能。在透過 db pull 進行內省後,資料庫中現有的全文索引會新增至您的 Prisma 結構描述,並且在使用 Prisma Migrate 時,在 Prisma 結構描述中新增的新全文索引會在資料庫中建立。這也可以防止先前無法運作的某些資料庫結構描述中出現驗證錯誤。

警告

目前,我們未在 Prisma Client for MongoDB 中啟用全文搜尋命令;可以在 MongoDB 問題中追蹤進度。

啟用 fullTextIndex 預覽功能

若要啟用 fullTextIndex 預覽功能,請將 fullTextIndex 功能標記新增至 schema.prisma 檔案的 generator 區塊

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

範例

以下範例示範如何將 @@fulltext 索引新增至 Post 模型的 titlecontent 欄位

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

@@fulltext([title, content])
}

在 MongoDB 上,您可以使用 @@fulltext 索引屬性 (透過 fullTextIndex 預覽功能) 和 sort 引數,以遞增或遞減順序將欄位新增至您的全文索引。以下範例將 @@fulltext 索引新增至 Post 模型的 titlecontent 欄位,並以遞減順序排序 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 Migrate 之前,請執行 prisma db pull 以內省現有資料庫以更新您的 Prisma 結構描述。

早期版本的 Prisma ORM 使用 @@index 屬性而不是 @@fulltext 屬性轉換全文索引。在啟用 fullTextIndex 預覽功能後,執行 prisma db pull 以將這些索引轉換為 @@fulltext,然後再次使用 Prisma Migrate 進行遷移。如果您不這樣做,現有的索引將被捨棄,並在它們的位置建立一般索引。