Що таке ORM? Як застосунки працюють із базами даних, пояснено
ORM (object-relational mapper) — це програмна бібліотека, яка стоїть між застосунком і реляційною базою даних. Замість того щоб писати запити до бази мовою SQL, розробники працюють із даними як із звичайними об'єктами своєї мови програмування — db.booking.create(...) або Booking.find(...) — а ORM перекладає це на SQL, виконує його і перетворює результати назад на об'єкти. Популярні приклади: Prisma і Drizzle для TypeScript, SQLAlchemy для Python та Entity Framework Core для C#.
Чому ORM важливі, коли ви створюєте з ШІ
Коли конструктор застосунків на основі ШІ додає до вашого застосунку базу даних, він зазвичай додає й ORM, щоб з нею працювати. Писати код ORM вам не доведеться, але корисно знати, що він є:
- Модель даних живе в коді. Файл схеми ORM часто найзрозуміліше описує дані вашого застосунку: які таблиці існують, які поля має кожна і як вони пов'язані. Його читання — швидкий спосіб перевірити, що ШІ правильно зрозумів ваш застосунок.
- Зміни бази проходять через міграції. Коли ви просите «додай номер телефону до клієнтів», ШІ оновлює модель і створює міграцію. Розуміння цього допоможе зрозуміти, чому зміна може потребувати застосування, перш ніж запрацювати в продакшені.
- Безпека за замовчуванням. ORM будують запити так, щоб захищати від SQL-ін'єкцій — однієї з найпоширеніших дірок у безпеці застосунків, які складають запити вручну.
- Пастки продуктивності. ORM легко непомітно виконує сотні дрібних запитів там, де вистачило б одного. Це поширена причина повільних сторінок в застосунках, створених з ШІ.
Повсякденна аналогія
Уявіть мандрівника з Великої Британії та продавчиню в Японії, які не розмовляють спільною мовою і спілкуються через перекладача.
Мандрівник (ваш застосунок) каже: «Мені потрібні три найдешевші чаї, які у вас є». Перекладач (ORM) перекладає це на точну японську (SQL), передає продавчині (базі даних) і переказує відповідь англійською.
Мандрівник не вчить японську, і для більшості розмов це нормально. Але для складних перемовин краще говорити напряму — тому більшість ORM дозволяють писати сирий SQL, коли це потрібно.
Як працює ORM
Бази даних на кшталт Postgres зберігають дані в таблицях із рядками та стовпцями, і до них звертаються через SQL. Мови програмування працюють з об'єктами: бронювання з date, customer і status. ORM зіставляє одне з іншим:
| Сторона бази даних | Сторона ORM / коду |
|---|---|
Таблиця bookings | Модель Booking |
| Рядок | Один об'єкт бронювання |
Стовпець starts_at | Поле startsAt |
Зовнішній ключ customer_id | Зв'язок booking.customer |
SELECT, INSERT, UPDATE, DELETE | Методи find, create, update, delete |
Ці чотири операції — це CRUD, на якому будується майже кожен застосунок.
Практичний приклад: бронювання з Prisma
Ось спрощена схема Prisma для застосунку бронювання в салоні краси. Вона описує дві таблиці та їхній зв'язок:
model Customer {
id Int @id @default(autoincrement())
name String
email String @unique
bookings Booking[]
}
model Booking {
id Int @id @default(autoincrement())
startsAt DateTime
service String
customer Customer @relation(fields: [customerId], references: [id])
customerId Int
}
Простими словами: клієнт має ім'я, унікальну електронну пошту і багато бронювань; кожне бронювання має час початку, послугу і належить одному клієнту.
Тепер застосунку потрібно: «найближчі бронювання Олени, від найраніших»:
const bookings = await db.booking.findMany({
where: {
customer: { email: "lena@example.com" },
startsAt: { gte: new Date() },
},
orderBy: { startsAt: "asc" },
});
ORM перекладає це приблизно в такий SQL, виконує його і повертає список об'єктів бронювань:
SELECT b.* FROM "Booking" b
JOIN "Customer" c ON c.id = b."customerId"
WHERE c.email = $1 AND b."startsAt" >= $2
ORDER BY b."startsAt" ASC;
$1 і $2 — це заповнювачі: електронна пошта та дата передаються окремо від тексту запиту, і саме це запобігає SQL-ін'єкціям.
Міграції
Якщо далі ви попросите «дозволити клієнтам додавати номер телефону», ШІ додасть phone String? до моделі Customer (знак ? означає, що поле необов'язкове) і згенерує міграцію — невеликий SQL-скрипт на кшталт ALTER TABLE "Customer" ADD COLUMN "phone" TEXT;. Міграції зберігаються по порядку, тож кожну копію бази можна привести до тієї самої структури, а історія змін зберігається.
Поширені ORM за мовою
| Мова | Поширені ORM |
|---|---|
| TypeScript / JavaScript | Prisma, Drizzle, TypeORM, Sequelize |
| Python | SQLAlchemy, ORM Django, SQLModel |
| C# | Entity Framework Core |
| Java | Hibernate (часто через Spring Data JPA) |
| Ruby | Active Record |
ORM відрізняються тим, наскільки приховують SQL. Prisma використовує власну мову схем і стиль запитів; Drizzle свідомо залишається близьким до форми SQL, зберігаючи типізацію. Легші інструменти, які називаються конструкторами запитів — наприклад Knex або Kysely для TypeScript, — допомагають будувати SQL у коді без повного відображення рядків на об'єкти.
Ключові терміни
| Термін | Значення |
|---|---|
| Модель | Опис таблиці та її полів у коді. |
| Схема | Повний опис усіх таблиць, полів і зв'язків. |
| Зв'язок | Посилання між моделями, наприклад бронювання належить клієнту. |
| Міграція | Версійований скрипт, який змінює структуру бази даних. |
| Конструктор запитів | Легший інструмент для побудови SQL у коді без повного відображення на об'єкти. |
| Проблема N+1 | Один запит для списку, а потім ще один для кожного елемента — повільно при масштабуванні. |
| Сирий SQL | SQL, написаний вручну, коли ORM заважає. |
Поширені хибні уявлення
- «ORM — це база даних». Ні. Це перекладач. Вам усе одно потрібна база даних, наприклад Postgres.
- «З ORM не треба розуміти свої дані». Погано спроєктовані таблиці однаково створюють проблеми і через ORM. Добра модель даних важливіша за інструмент.
- «ORM завжди повільні». Повсякденні запити працюють добре. Повільність зазвичай спричиняють шаблони на кшталт запитів N+1 або відсутніх індексів, а їх можна виправити.
- «ORM означає, що ризику SQL-ін'єкцій немає взагалі». Стандартні методи ORM безпечні, але сирий SQL, у який вставлено введені користувачем дані, однаково небезпечний.
- «Редагування файлу схеми змінює живу базу». Лише після того, як створено міграцію і її застосовано до цієї бази.
Що запитати у вашого ШІ-конструктора
- «Покажи схему бази даних і простою мовою поясни кожну таблицю та зв'язок».
- «Який ORM використовує цей проєкт і де лежать міграції?»
- «Перш ніж змінювати будь-яку таблицю, скажи, чи постраждають наявні дані, і ніколи не видаляй стовпець із даними без запиту».
- «Перевір найповільніші сторінки на запити N+1 і додай індекси там, де списки фільтруються або сортуються».
- «Переконайся, що кожен запит з введеними користувачем даними проходить через ORM або використовує параметри — жодного SQL, складеного рядками».
ORM у Mythex
Коли вашому застосунку потрібно зберігати дані, Mythex додає до проєкту окрему базу Postgres — запитайте в чаті або скористайтеся командою /database — і передає її параметри підключення в робочий простір та опублікований застосунок (База даних). Далі агент пише код, який читає та зберігає ваші дані. Якщо у вас є вподобання — «використовуй Prisma», «використовуй SQLAlchemy» чи «чистий SQL, без ORM» — скажіть про це в чаті. Попросіть агента пояснити схему, коли захочете перевірити структуру; файли можна переглянути в редакторі коду. Ширша картина — у статтях що таке база даних і SQL проти NoSQL.
Запитання
Що таке ORM простими словами?
ORM (object-relational mapper, об'єктно-реляційне відображення) — це програмна бібліотека, яка стоїть між застосунком і реляційною базою даних. Вона дозволяє розробникам читати й зберігати дані як звичайні об'єкти своєї мови програмування, а SQL-запити пише за лаштунками.
Які є приклади ORM?
Поширені ORM: Prisma і Drizzle для TypeScript та JavaScript, SQLAlchemy і ORM Django для Python, Entity Framework Core для C#, Hibernate для Java та Active Record у Ruby on Rails.
Чи краща ORM, ніж написання SQL?
Це залежить від завдання. ORM робить повсякденні читання й записи швидшими у написанні, безпечнішими та простішими для змін, тоді як SQL, написаний вручну, дає повний контроль над складними звітами та запитами, де важлива продуктивність. Більшість ORM дозволяють за потреби перейти до сирого SQL.
Що таке міграція?
Міграція — це невеликий версійований скрипт, який змінює структуру бази даних, наприклад додає таблицю чи стовпець. ORM можуть генерувати міграції з вашої моделі даних, щоб кожна копія бази — на ноутбуці, у тестуванні та в продакшені — мала однакову структуру.