Prisma Schema
Prisma schema有自己的schema配置表的约定,它通常是一个名为schema.prisma的单一文件或者多个文件。
通常我们是现在.prisma文件里定义好库,表结构。再通过prisma cli生成真实的db结构,再通过generate更新prisma client的类型推导文件。
也就是更新本地.prisma文件后,执行
npx prisma migrate dev --name [message]来更新数据库表结构
接着执行npx prisma generate来更新prisma client的typescipt类型
那么schema是怎么定义的呢?
按照约定,所有model定义的表都将被生成为Table,里面定义的类型会被生成为表类型。
比如文档里定义的示例就包含了几乎常见的情况:
datasource db {
provider = "postgresql"
}
generator client {
provider = "prisma-client"
output = "./generated"
}
model User {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
email String @unique
name String?
role Role @default(USER)
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
published Boolean @default(false)
title String @db.VarChar(255)
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}
enum Role {
USER
ADMIN
}
这里创建了User和Post两张表,然后
id是autoincrement自增的,这一点和mysql定义类似;
createAt 也是默认填入create的时候的时间;
email是唯一的,它用了@unique修饰,这个关键词就是在生成表时告诉mysql这个字段唯一不能重复;
name 是字符串类型;title同样是字符串类型,但是约束了长度255,通过db.Varchar定义约束长度。注意这里db.Varchar仅仅对mysql有效,如果是其他数据库这里这么写就会报错!
role 则是枚举类型Role的值,enum Role并不会被生成为表,前面说了只有model才会被生成为真实的表;
authorId 这里声明了User与Post的关联关系,即Post里的authorId指向User表的id。即@relation里指定fileds字段authorId 指向User表里的id;要声明表之间的关系,必须在主表里声明一个字段指向关系表,同时在关系表里指定字段关联主表。所以这里是User一对多的关系
@updateAt同createAt在create时自增,这个修饰的是在update时自动填充更新时间;
除了上面这些常见的用法,schema还有@@index,@@unique,@@map这三个也是比较常见的修饰符(姑且这么定义吧,是我口头表达)
@@index是指定特定的字段添加索引,类似于CREATE INDEX Post_authorId_idx ON Post(authorId)这样,这样做的好处是在SELECT 查询的时候可以直接定位到索引位置而不用全盘查,这在数据量很大的表的时候非常有用,也强烈建议给一个需要查询的字段添加@@index([键名])
@@unique 同上面的@unique 描述为值唯一,@@unique通常用于约束比如User表里你希望userId和role 同一个用户不能重复拥有同一个role,此时用@@unique([userId, role])就可以达成这样的约束条件;
而@@map则是表名映射的意思,即@@map('posts'),在prisma里我叫Post,在mysql数据库里我叫posts
比如:
model User {
id Int @id @default(autoincrement())
email String
@@map("users")
}
这张表我在prisma里还是User,而在数据库里则是叫users
除了映射表名,你也可以映射字段名 用@map
最后来一个对照示例:
model Post {
id Int @id @default(autoincrement())
title String
authorId Int?
author User? @relation(fields: [authorId], references: [id])
@@index([authorId])
@@map("posts")
}
相当于在数据库里是:
CREATE TABLE posts (
id INT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(255),
authorId INT,
INDEX idx_authorId (authorId),
FOREIGN KEY (authorId) REFERENCES users(id)
);