Чертёж и переводчик
Модель данных — главный чертёж; ORM — тот, кто его читает
Модель данных описывает, какие «вещи» есть в приложении, какие у них свойства и как они связаны. ORM превращает этот чертёж в реальные таблицы базы и берёт на себя всю рутину запросов.
Часть 1: модель данных
Модель данных — это описание сущностей (entity) вашего приложения и связей между ними. Сущность — это тип объекта: пользователь, заказ, товар, статья. Каждая сущность обычно становится одной таблицей в базе данных.
У каждой сущности есть поля: у пользователя — id, email, имя; у заказа — id, сумма, статус. И у сущностей есть связи (relationship) — отношения между ними:
- Один-ко-многим — один пользователь оформляет много заказов; один пост имеет много комментариев. Самая частая связь.
- Многие-ко-многим — студент записан на много курсов, курс включает много студентов. Здесь обычно нужна промежуточная таблица.
- Один-к-одному — у пользователя ровно один профиль, у профиля ровно один пользователь.
Хорошая модель — половина успеха. Если вы правильно описали сущности и связи в начале, агент выстраивает всё остальное логично и без костылей.1
Часть 2: ORM и Prisma
ORM (Object-Relational Mapping, объектно-реляционное отображение) — инструмент-«переводчик» между миром кода и миром базы данных. В коде разработчик работает с объектами и классами; база данных понимает только SQL-запросы. ORM стоит между ними и переводит в обе стороны.2
Разработчик (или агент) описывает модели один раз в специальном файле-схеме — а ORM сам создаёт таблицы, генерирует SQL и даёт удобный API для запросов. Вместо SELECT * FROM users WHERE id = 1 пишется просто prisma.user.findUnique({ where: { id: 1 } }).
В мире TypeScript/Node.js (а именно там работает большинство приложений, которые строят вайб-кодеры) чаще всего встречаются два ORM: Prisma2 и Drizzle3. Prisma — самый популярный, с подробной документацией; Drizzle — более лёгкий и близкий к сырому SQL.
Вот как выглядит упрощённая схема в стиле Prisma — именно такой файл агент пишет и редактирует в вашем проекте:
model User {
id Int @id @default(autoincrement())
email String @unique
orders Order[] // у пользователя МНОГО заказов
}
model Order {
id Int @id @default(autoincrement())
total Int
userId Int
user User @relation(fields: [userId], references: [id])
// заказ принадлежит ОДНОМУ пользователю
}
Здесь видно всё главное: две сущности (User и Order), их поля (id, email, total) и связь «один-ко-многим» — через Order[] у пользователя и @relation у заказа. Это и есть модель данных, записанная в ORM-схему.
📌 Правило заказчика: опишите агенту сущности и связи своими словами в самом начале проекта — «у нас есть X, Y, Z; X связан с Y так-то». Это дешевле, чем переделывать базу потом.