مدل‌سازی داده با Prisma و MySQL

طراحی Schema در Prisma، انواع رابطه‌ها، Migration امن روی production، کوئری‌نویسی Type-Safe و نکات کارایی مثل ایندکس، تراکنش و جلوگیری از مشکل N+1.

مدل‌سازی داده با Prisma و MySQL
زمان انتشار:
۳۱ مرداد ۱۴۰۵
زمان مطالعه:
حدود 3 دقیقه
نویسنده:
علیرضا مهدی زاده
دسته‌بندی:بک‌اند

چرا Prisma؟

کار با پایگاه داده در Node.js همیشه با چالش‌هایی همراه بوده است: نوشتن کوئری‌های SQL خام، نبودن Type Safety و مدیریت دستی تغییرات جداول. Prisma یک ORM مدرن است که با یک فایل Schema خوانا، تولید خودکار تایپ‌های TypeScript و سیستم Migration قدرتمند، این مشکلات را حل می‌کند. در این مقاله با طراحی یک مدل داده‌ی واقعی برای یک وبلاگ روی MySQL آشنا می‌شویم.

پلی معلق در مه غلیظ؛ رابطه‌ها مثل پل، جدول‌ها را به هم متصل می‌کنند

تعریف مدل‌ها در schema.prisma

قلب هر پروژه‌ی Prisma فایل schema.prisma است. در این فایل منبع داده، ژنراتور کلاینت و مدل‌ها تعریف می‌شوند:

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}

model User {
  id        Int      @id @default(autoincrement())
  mobile    String   @unique @db.VarChar(15)
  name      String   @default("")
  posts     Post[]
  createdAt DateTime @default(now())
}

model Post {
  id          Int        @id @default(autoincrement())
  title       String
  slug        String     @unique
  content     String     @db.LongText
  published   Boolean    @default(false)
  author      User?      @relation(fields: [authorId], references: [id], onDelete: SetNull)
  authorId    Int?
  categories  Category[]
  publishedAt DateTime?

  @@index([published, publishedAt])
}

model Category {
  id    Int    @id @default(autoincrement())
  name  String @unique
  slug  String @unique
  posts Post[]
}

انواع رابطه‌ها

  • یک به چند: هر کاربر چند مقاله دارد. کلید خارجی authorId در جدول مقاله نگهداری می‌شود.
  • چند به چند: هر مقاله چند دسته‌بندی دارد و هر دسته‌بندی چند مقاله. Prisma جدول واسط را خودکار می‌سازد.
  • یک به یک: مثلاً هر کاربر یک تنظیمات اعلان دارد؛ با @unique روی کلید خارجی تعریف می‌شود.

گزینه‌ی onDelete: SetNull مشخص می‌کند که با حذف یک کاربر، مقاله‌هایش حذف نشوند و فقط نویسنده خالی شود. این تصمیم‌ها را همیشه آگاهانه بگیرید.

کتاب‌ها و نامه‌های قدیمی بسته‌بندی‌شده با نخ کنار قلم؛ داده‌های مرتب و به‌هم‌پیوسته

Migration؛ تاریخچه‌ی تغییرات پایگاه داده

هر تغییر در Schema باید به یک Migration تبدیل شود تا روی همه‌ی محیط‌ها یکسان اعمال شود:

# در محیط توسعه: ساخت و اجرای Migration
npx prisma migrate dev --name add_categories

# روی سرور production: فقط اجرای Migrationهای موجود
npx prisma migrate deploy

هرگز روی سرور اصلی از migrate dev یا db push استفاده نکنید؛ این دستورها ممکن است برای هماهنگ‌سازی، داده‌ها را حذف کنند.

کوئری‌نویسی Type-Safe

کلاینت Prisma بر اساس Schema تولید می‌شود، بنابراین ویرایشگر شما تمام فیلدها و رابطه‌ها را می‌شناسد:

const posts = await prisma.post.findMany({
  where: {
    published: true,
    categories: { some: { slug: "backend" } },
  },
  select: {
    title: true,
    slug: true,
    author: { select: { name: true } },
  },
  orderBy: { publishedAt: "desc" },
  take: 10,
})

اگر نام یک فیلد را اشتباه بنویسید، قبل از اجرا و در همان ویرایشگر خطا می‌گیرید.

لپ‌تاپ، دفترچه و فنجان قهوه روی میز چوبی؛ طراحی Schema پیش از نوشتن کد

نکات کارایی

  • فقط فیلدهای لازم را انتخاب کنید: با select از دریافت ستون‌های حجیم مثل content در لیست‌ها پرهیز کنید.
  • ایندکس بگذارید: برای فیلدهایی که در where و orderBy استفاده می‌شوند، @@index تعریف کنید.
  • مشکل N+1: به‌جای کوئری داخل حلقه، رابطه‌ها را با include یا select یک‌جا دریافت کنید.
  • تراکنش: عملیات وابسته را با prisma.$transaction اجرا کنید تا داده‌ها ناقص ذخیره نشوند.
  • یک نمونه‌ی کلاینت: در Next.js کلاینت Prisma را به‌صورت Singleton بسازید تا اتصال‌ها زیاد نشوند.

نمای پایین به بالای آسمان‌خراش‌ها؛ مقیاس‌پذیری پایگاه داده با طراحی درست

جمع‌بندی

یک مدل داده‌ی خوب، پایه‌ی هر اپلیکیشن موفق است. Prisma با Schema خوانا، Migrationهای قابل ردیابی و کوئری‌های Type-Safe، کار با MySQL را امن‌تر و لذت‌بخش‌تر می‌کند. پیش از نوشتن اولین خط کد، زمان کافی برای طراحی جدول‌ها و رابطه‌ها بگذارید؛ تغییر آن‌ها در آینده بسیار پرهزینه‌تر خواهد بود.

دیدگاه‌ها

برای ثبت دیدگاه باید شماره موبایل خود را تأیید کنید.

هنوز دیدگاهی ثبت نشده است. اولین نفر باشید!