Desain Skema Prisma
Saatnya merancang 'cetakan' databasemu! Pelajari sintaks Prisma Schema Language (PSL) untuk mendefinisikan model data (tabel), field, tipe data, atribut field (seperti ID, default, unik), dan relasi antar model.
Jadi Arsitek Database: Rancang Model Datamu Pake Prisma Schema!
Udah berhasil nyiapin "toko" Prisma di proyekmu dengan prisma init? Keren! Sekarang, kita bakal jadi arsitek yang ngerancang "ruangan-ruangan" dan "perabotan" di dalem "toko data" kita. Di Prisma, semua rancangan ini kita tuangin ke dalem satu file utama: prisma/schema.prisma.
File schema.prisma ini adalah jantung dari penggunaan Prisma. Di sinilah kamu bakal ngedefinisiin:
- Sumber Data (Datasource): Database apa yang kamu pake dan gimana cara nyambungnya. (Ini udah kita sentuh sedikit pas setup SQLite).
- Generator Klien (Client Generator): Ngasih tau Prisma buat nge-generate Prisma Client yang type-safe.
- Model Data (Data Models): Ini yang paling penting! Model data ini ngewakilin tabel-tabel di databasemu, kolom-kolom (field) di tiap tabel, tipe data tiap kolom, dan hubungan (relasi) antar tabel.
Kita bakal nulis semua ini pake bahasa khusus yang simpel dan gampang dibaca namanya Prisma Schema Language (PSL).
Ngintip Lagi schema.prisma Kita
Buka file prisma/schema.prisma yang udah di-generate sebelumnya. Isinya kurang lebih kayak gini (kalau kita udah ubah ke SQLite):
// prisma/schema.prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "sqlite" // Kita udah set ini ke sqlite
url = env("DATABASE_URL") // Ngambil dari file .env
}
// Model-model data kita bakal ditulis di bawah sinigenerator client { ... }: Bagian ini ngasih tau Prisma buat nge-generate Prisma Client dalam bahasa JavaScript (yang bisa dipake di TypeScript juga). Prisma Client ini yang nanti kita pake di kode aplikasi kita buat ngobrol sama database.datasource db { ... }: Bagian ini ngedefinisiin koneksi ke database kita.provider = "sqlite": Kita pake SQLite. Bisa jugapostgresql,mysql, dll.url = env("DATABASE_URL"): String koneksi diambil dari variabelDATABASE_URLdi file.envkita (yang udah kita set kefile:./dev.dbataufile:./prisma/dev.db).
Mendesain Model Data: "Cetakan" Tabelmu
Sekarang bagian paling serunya: bikin Model. Di PSL, satu model itu biasanya ngewakilin satu tabel di database relasionalmu.
- Sintaks Dasar Model:
prisma
model NamaModel { namaField1 TipeData1 @atributField1 @atributField2 namaField2 TipeData2 // Properti tanpa atribut juga bisa // ... field lain ... // Untuk relasi (dibahas nanti) // namaRelasi NamaModelRelasi @relation(...) }model NamaModel: Keywordmodeldiikuti nama modelmu (biasanya diawali huruf besar dan pake PascalCase, misalUser,ProductOrder). Nama model ini bakal jadi nama tabel di database (Prisma bisa ngatur konvensi penamaan tabelnya, misal jadiusersatauproduct_orders).namaField TipeData: Tiap baris di dalem model ngedefinisiin satu field (kolom) beserta tipe datanya.namaField: Nama kolom (biasanya camelCase, misalfirstName,createdAt).TipeData: Tipe data buat kolom itu.
Tipe Data Dasar di Prisma Schema Language (PSL)
PSL punya tipe data dasar yang bakal nge-map ke tipe data spesifik di databasemu:
String: Buat teks (VARCHAR, TEXT, dll. tergantung database).Int: Buat angka integer (INT, INTEGER).BigInt: Buat angka integer yang gede banget.Float: Buat angka desimal (FLOAT, REAL, DOUBLE).Decimal: Buat angka desimal dengan presisi tinggi (DECIMAL, NUMERIC), cocok buat data keuangan.Boolean: Buat nilaitrueataufalse(BOOLEAN, BIT).DateTime: Buat nyimpen tanggal dan waktu (TIMESTAMP, DATETIME).Json: Buat nyimpen data JSON langsung di satu kolom (JSON, JSONB di PostgreSQL).Bytes: Buat data biner.
Modifier Tipe:
?(Opsional): Tambahin?setelah tipe data buat nandain kalau field itu bolehNULL(opsional, gak wajib diisi). Contoh:deskripsi String?[](List/Array): Tambahin[]setelah tipe data buat nandain kalau field itu adalah array/list dari tipe tersebut. Penting: Gak semua database ngedukung tipe array secara native di kolom. Prisma bisa nyimulasiin ini, tapi perilakunya tergantung provider database. (Misal,String[]di PostgreSQL itu array beneran, di MySQL mungkin jadi JSON atau cara lain).
Atribut Field (@ dan @@)
Selain nama dan tipe, field juga bisa punya atribut buat ngasih "sifat" atau "aturan" tambahan. Atribut field diawali satu @, atribut level model (blok) diawali dua @@.
Beberapa atribut field yang paling sering dipake:
@id: Nandain kalau field itu adalah Primary Key buat tabel/model itu. Biasanya dipake di fieldid.@default(nilai_atau_fungsi): Nentuin nilai default buat field itu kalau gak diisi pas bikin data baru.- Contoh:
status String @default("pending"),createdAt DateTime @default(now()),poin Int @default(0),uuid String @default(uuid())(butuh fungsiuuid()dari database atau Prisma).
- Contoh:
@unique: Nandain kalau nilai di field itu harus unik di seluruh tabel (gak boleh ada yang sama). Cocok buat email, username.@updatedAt: Otomatis ngeset field (yang tipenyaDateTime) ke waktu saat ini setiap kali record itu di-update. Berguna buat ngelacak kapan data terakhir diubah.@map("nama_kolom_di_db"): Kalau kamu mau nama field di model Prismamu beda sama nama kolom di database benerannya.@relation(...): Ini dipake buat ngedefinisiin relasi antar model. Bakal kita bahas lebih detail.
Contoh Model User dan Post Sederhana:
// prisma/schema.prisma
// ... (generator dan datasource masih sama) ...
model User {
id Int @id @default(autoincrement()) // Primary Key, auto-increment (beda per DB)
email String @unique // Email harus unik
nama String? // Nama boleh kosong (opsional)
password String // Password wajib ada (nantinya di-hash ya!)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// Relasi: Satu User bisa punya banyak Post
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
judul String
konten String?
dipublikasi Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// Relasi: Satu Post dimiliki oleh satu User
author User @relation(fields: [authorId], references: [id])
authorId Int // Foreign Key ke tabel User
}Bedah Contoh:
-
UserModel:id: TipeInt, jadi Primary Key (@id), dan nilainya di-generate otomatis sama database pas data baru dibuat (@default(autoincrement())). (Sintaks autoincrement bisa beda dikit antar database, misaluuid()buat ID string unik).email:String, wajib unik.nama:String, opsional (?).createdAt:DateTime, otomatis diisi waktu saat ini pas User dibuat.updatedAt:DateTime, otomatis diupdate tiap kali User diubah.posts Post[]: Ini field relasi. Nunjukin kalau satuUserbisa punya banyak ([]) record dari modelPost. Prisma pinter, dia bakal ngerti ini relasi one-to-many.
-
PostModel:id,judul,konten,dipublikasi,createdAt,updatedAt: Mirip kayak di User.author User @relation(fields: [authorId], references: [id]): Ini juga field relasi.author User: Nunjukin kalau satuPostitu "milik" satuUser.@relation(...): Ngasih detail soal relasinya.fields: [authorId]: Ngasih tau Prisma kalau fieldauthorIddi modelPostini yang jadi foreign key.references: [id]: Ngasih tau Prisma kalauauthorIditu ngacunya ke fieldiddi modelUser.
authorId Int: Ini field foreign key benerannya yang nyimpeniddariUserpemilik post ini. Tipe datanya harus sama kayakiddiUser.
Dengan ngedefinisiin relasi kayak gini, Prisma Client nanti bakal ngasih kita cara gampang buat ngambil data user beserta semua post-nya, atau sebaliknya.
Mendesain Relasi Lebih Lanjut
Prisma ngedukung semua jenis relasi database umum:
-
One-to-One (1-1): Misal, satu
Userpunya satuProfile.prisma
model User { id Int @id @default(autoincrement()) profile Profile? // Profile opsional, dan unik per User } model Profile { id Int @id @default(autoincrement()) bio String? user User @relation(fields: [userId], references: [id]) userId Int @unique // userId di Profile harus unik, nandain 1-1 } -
One-to-Many (1-N): Udah kita liat di contoh
UserdanPost. Satu User -> Banyak Post. Satu Post -> Satu User. -
Many-to-Many (N-M): Misal, satu
Postbisa punya banyakCategory, dan satuCategorybisa dipake di banyakPost.- Cara Implisit (Prisma yang bikinin tabel join):
prisma
model Post { id Int @id @default(autoincrement()) judul String categories Category[] // Post punya banyak Category } model Category { id Int @id @default(autoincrement()) nama String @unique posts Post[] // Category dipake di banyak Post } // Prisma bakal otomatis bikin tabel join di belakang layar (_CategoryToPost) - Cara Eksplisit (Kita definisiin tabel join-nya sendiri): Kadang kita butuh nambahin info ekstra di tabel join (misal, tanggal kapan post ditambahin ke kategori).
prisma
model Post { id Int @id @default(autoincrement()) judul String kategoriDiPost KategoriDiPost[] // Ngacu ke model tabel join } model Category { id Int @id @default(autoincrement()) nama String @unique postDiKategori KategoriDiPost[] // Ngacu ke model tabel join } model KategoriDiPost { // Ini model tabel join-nya post Post @relation(fields: [postId], references: [id]) postId Int kategori Category @relation(fields: [kategoriId], references: [id]) kategoriId Int ditugaskanPada DateTime @default(now()) // Info tambahan di tabel join @@id([postId, kategoriId]) // Primary key gabungan }
- Cara Implisit (Prisma yang bikinin tabel join):
Milih antara implisit atau eksplisit buat many-to-many tergantung kebutuhan. Kalau gak butuh field ekstra di tabel join, implisit lebih simpel.
Atribut Level Model (Blok) @@
Selain atribut field (@), ada juga atribut yang diterapin ke seluruh model (blok), diawali dua @@.
@@id([...]): Buat bikin composite primary key (primary key yang terdiri dari beberapa field).@@unique([...]): Buat bikin composite unique constraint (kombinasi beberapa field harus unik).@@index([...]): Buat nambahin indeks database ke beberapa field (buat percepat query).@@map("nama_tabel_di_db"): Kalau mau nama model beda sama nama tabel di database.
Contoh di model KategoriDiPost tadi: @@id([postId, kategoriId]).
File schema.prisma ini adalah "cetak biru" buat seluruh struktur databasemu. Dengan Prisma Schema Language (PSL) yang deklaratif dan gampang dibaca, kamu bisa ngedesain model data dan relasinya dengan jelas.
Uji Pemahamanmu!
Memeriksa status login...