我知道“唯一索引”等价于UNIQUE列约束,但是在阅读原始SQL时,这不是更清晰吗,并且避免与纯粹出于性能原因创建的索引混淆?
这是一个示例架构,直接取自 Prisma 的快速入门文档:
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "sqlite"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId Int
}
注意“电子邮件”唯一声明如何在模式末尾的唯一索引中实现(SQLite):
SELECT sql FROM sqlite_schema;
CREATE TABLE "_prisma_migrations" (
"id" TEXT PRIMARY KEY NOT NULL,
"checksum" TEXT NOT NULL,
"finished_at" DATETIME,
"migration_name" TEXT NOT NULL,
"logs" TEXT,
"rolled_back_at" DATETIME,
"started_at" DATETIME NOT NULL DEFAULT current_timestamp,
"applied_steps_count" INTEGER UNSIGNED NOT NULL DEFAULT 0
)
CREATE TABLE "User" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"email" TEXT NOT NULL,
"name" TEXT
)
CREATE TABLE sqlite_sequence(name,seq)
CREATE TABLE "Post" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"title" TEXT NOT NULL,
"content" TEXT,
"published" BOOLEAN NOT NULL DEFAULT false,
"authorId" INTEGER NOT NULL,
CONSTRAINT "Post_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "User" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
)
CREATE UNIQUE INDEX "User_email_key" ON "User"("email")
我试着猜测可能是什么原因。我最好的猜测是 Prisma 的内部逻辑更喜欢拥有尽可能多的东西作为索引,但也许还有另一个原因。
简而言之,这并不重要,因为最终结果实际上是相同的。
即索引,只是具体命名的索引而不是生成的命名索引可能不会那么混乱。可能还有一个因素是名字很容易确定。
考虑以下摘录
3.6 独特的约束
UNIQUE 约束类似于 PRIMARY KEY 约束,不同之处在于单个表可以具有任意数量的 UNIQUE 约束。对于表上的每个 UNIQUE 约束,每行必须包含由 UNIQUE 约束标识的列中值的唯一组合。出于 UNIQUE 约束的目的,NULL 值被视为与所有其他值(包括其他 NULL)不同。与 PRIMARY KEY 一样,UNIQUE 表约束子句必须仅包含列名 - 不支持在 UNIQUE 表约束的索引列中使用表达式。
在大多数情况下,UNIQUE和PRIMARY KEY 约束是通过在数据库中创建唯一索引来实现的。(例外情况是WITHOUT ROWID表上的INTEGER PRIMARY KEY和PRIMARY KEY。)因此,有以下模式逻辑上是等价的:
CREATE TABLE t1(a, b UNIQUE);
CREATE TABLE t1(a, b PRIMARY KEY);
CREATE TABLE t1(a, b);
CREATE UNIQUE INDEX t1b ON t1(b);
即
CREATE TABLE t1(a, b UNIQUE);
和 CREATE UNIQUE INDEX t1b ON t1(b);
在功能上相同,只是第一个索引的名称是系统生成的,而第二个索引是根据给定名称命名的。