跳到主要内容

索引

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 schema 类型 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 Schema Language 中定义:在 CockroachDB 上不需要或不允许使用 ops 参数。

通用搜索树 (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 schema 激活功能时,这些索引配置更改可能是重大更改。在启用使用它们所需的预览功能后,运行 prisma db pull 以内省现有数据库以更新您的 Prisma schema,然后再一次使用 Prisma Migrate。

在以下情况下可能会发生重大更改

  • 现有排序约束和索引:如果未明确指定顺序,则早期版本的 Prisma ORM 将假定所需的排序顺序为升序。这意味着如果您有使用降序排序顺序的现有约束或索引,并且在未首先在您的数据模型中指定此顺序的情况下迁移数据库,则这是一个重大更改。
  • 现有长度约束和索引:在早期版本的 Prisma ORM 中,MySQL 中长度受限的索引和约束无法在 Prisma schema 中表示。因此,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 schema 中,并且当使用 Prisma Migrate 时,在 Prisma schema 中添加的新全文索引将在数据库中创建。这也防止了以前无法使用的一些数据库 schema 中的验证错误。

警告

目前,我们没有在 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 schema 激活功能时,这可能是重大更改。在启用使用它们所需的预览功能后,运行 prisma db pull 以内省现有数据库以更新您的 Prisma schema,然后再一次使用 Prisma Migrate。

早期版本的 Prisma ORM 使用 @@index 属性而不是 @@fulltext 属性转换全文索引。启用 fullTextIndex 预览功能后,运行 prisma db pull 以将这些索引转换为 @@fulltext,然后再使用 Prisma Migrate 再次迁移。如果您不这样做,则现有索引将被删除,并在其位置创建普通索引。