我知道"唯一索引"等同于唯一列约束,但在读取原始SQL时,这不是更清楚了吗?避免与纯粹出于性能原因而创建的索引混淆?

以下是直接取自Prisma的QuickStart文档的示例模式:

// 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的内部逻辑更倾向于拥有尽可能多的内容作为索引,但可能还有另一个原因.

推荐答案

简而言之,这并不重要,因为最终结果实际上是相同的.

即索引,只是具体命名的索引而不是生成的命名索引可能不那么容易混淆.还可能存在一个因素,即如果该名称随后被使用,则该名称很容易确定/已经命名.

  • 具体命名为当使用CREATE INDEX ....
  • 生成的名称是自动创建的索引

考虑这一摘录,

3.6 UNIQUE constraints

UNIQUE约束类似于PRIMARY KEY约束,不同之处在于单个表可以具有任意数量的UNIQUE约束.对于表上的每个UNIQUE约束,每行都必须包含由UNIQUE约束标识的列中的值的唯一组合.对于UNIQUE约束,NULL值被认为与所有其他值(包括其他NULL)不同.与PRIMARY KEY一样,UNIQUE表约束子句必须只包含列名-不支持在UNIQUE表约束的索引列中使用表达式.

100和主键101(例外是整数主键和不带ROWID表的主键ON).因此,以下模式在逻辑上是等价的:

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);在功能上是相同的.

Demonstration

请考虑使用这两种方法然后输出架构的以下内容:

CREATE TABLE User1 (
    id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    email TEXT NOT NULL,
    name TEXT
);
CREATE UNIQUE INDEX User_email_key ON User1(email);
CREATE TABLE User2 (
    id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    email TEXT NOT NULL UNIQUE,
    name TEXT
);
SELECT * FROM sqlite_master;

这将导致:

enter image description here

如您所见,已根据SQLite命名约定创建并命名了生成的索引.

  • 不太可能有用,也没有关联的SQL,因为它是自动生成的.

Sql相关问答推荐

如何在SQL查询中只比较日期时间的年份和月份(而忽略日期比较)?

Trino/Presto sq:仅当空值位于组中第一个非空值之后时,才用值替换空值

我如何计算字母a出现的字符串的次数?

在请求结束之前,PostgreSQL不会考虑使用中的删除

如何从查询中的三个或更多个表中添加另一个相同的列?

Postgresql - WHERE 中的 MAX 标准 - 初学者问题

按二维数组的第一个元素排序

根据具有特定值的 ID 创建自定义组

从输出中删除 jsonb_build_object

使用 XML 作为 SQL 表

获取上个月和上一年的值

SQL Server中使用min()和max()从选定的特定值id表中删除不必要的时间

如何在插入时将字符串'03-January-2023'转换为日期时间

使用给定的变量对在循环中执行更新语句

SQL Server 分区和 Run Case 语句

基于源表的 SQL INSERT、UPDATE 和 DELETE

我现在如何显示重复的汽车? postgresql

PlSql 陷入死循环

来自 SQL Server 的树层次 struct 图的 JSON

CURRENT_ROW 窗口框架上的 SQL 滞后