Професійне налаштування Drizzle ORM для TypeScript-додатків

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Професійне налаштування Drizzle ORM для TypeScript-додатків
Середній
~1 день
Часті запитання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1360
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1251
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    957
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1188
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    929
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Розробка веб-сайту для компанії ФІКСПЕР
    948

Як налаштувати Drizzle ORM для веб-додатку

Типове CRUD-додаток на Express з нативним SQL-драйвером — це головний біль: дублювання коду, відсутність типів, неявні N+1 запити, ручна перевірка SQL. Після впровадження Drizzle ORM продуктивність запитів зросла на 40%, обсяг бойлерплейту скоротився на 60%, а розмір бандла зменшився на 30%. Схема на TypeScript без кодогенерації усуває ці проблеми на корені. Наші сертифіковані інженери з досвідом 5+ років налаштують Drizzle під ваш проект за 1–4 дні. Зв'яжіться з нами — отримайте готовий шаблон за 1 день.

Чому Drizzle ORM?

Drizzle — TypeScript ORM, де схема бази даних описується на TypeScript, а не в окремому DSL. Типи виводяться безпосередньо з коду схеми, немає проміжного шару. Це дає повний контроль над SQL: кожен запит можна перевірити та оптимізувати. Мінімальний overhead: Drizzle генерує лише необхідні запити, без зайвої обгортки. Edge-сумісність: працює в Cloudflare Workers, Vercel Edge, Deno.

В одному з проектів під високим навантаженням ми мігрували з Prisma на Drizzle — середній час виконання запитів знизився на 40%, а розмір бандла зменшився на 30%. Економія на інфраструктурі за рахунок меншого споживання пам'яті сягає 20%.

Як Drizzle ORM вирішує проблему N+1 запитів?

У традиційних ORM N+1 виникає при лінивому завантаженні пов'язаних сутностей. Drizzle цього уникає — всі JOIN-и явні, ви самі контролюєте, які дані вибирати. Наприклад, щоб отримати користувача з постами, ви пишете:

const user = await db.query.users.findFirst({
  where: eq(users.email, '[email protected]'),
  with: { posts: { where: eq(posts.published, true), limit: 5 } }
})

Цей запит виконується за один SQL — без додаткових викликів. Жодної магії, повна прозорість.

Як встановити та налаштувати Drizzle?

Встановлення пакетів

# PostgreSQL
npm install drizzle-orm postgres
npm install -D drizzle-kit

# MySQL
npm install drizzle-orm mysql2
npm install -D drizzle-kit

# SQLite / Turso (libSQL)
npm install drizzle-orm @libsql/client

Схема бази даних

Створіть файл db/schema.ts — опишіть таблиці, зв'язки та індекси.

// db/schema.ts
import {
  pgTable, pgEnum, text, varchar, integer, decimal,
  boolean, timestamp, uuid, index, uniqueIndex, primaryKey
} from 'drizzle-orm/pg-core'
import { relations } from 'drizzle-orm'

export const roleEnum = pgEnum('role', ['user', 'moderator', 'admin'])

export const users = pgTable('users', {
  id:        uuid('id').primaryKey().defaultRandom(),
  email:     varchar('email', { length: 255 }).notNull().unique(),
  name:      varchar('name', { length: 255 }).notNull(),
  role:      roleEnum('role').notNull().default('user'),
  createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
  updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
}, (table) => ({
  emailIdx: uniqueIndex('users_email_idx').on(table.email),
}))

export const posts = pgTable('posts', {
  id:          uuid('id').primaryKey().defaultRandom(),
  title:       text('title').notNull(),
  content:     text('content'),
  published:   boolean('published').notNull().default(false),
  authorId:    uuid('author_id').notNull().references(() => users.id, { onDelete: 'cascade' }),
  viewCount:   integer('view_count').notNull().default(0),
  publishedAt: timestamp('published_at', { withTimezone: true }),
  createdAt:   timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
}, (table) => ({
  authorIdx: index('posts_author_idx').on(table.authorId),
  publishedIdx: index('posts_published_idx').on(table.published, table.createdAt),
}))

// relations
import { relations } from 'drizzle-orm'
export const usersRelations = relations(users, ({ many }) => ({
  posts: many(posts),
}))

export const postsRelations = relations(posts, ({ one }) => ({
  author: one(users, { fields: [posts.authorId], references: [users.id] }),
}))

Конфігурація міграцій

// drizzle.config.ts
import type { Config } from 'drizzle-kit'

export default {
  schema: './db/schema.ts',
  out: './drizzle',
  driver: 'pg',
  dbCredentials: {
    connectionString: process.env.DATABASE_URL!
  },
  verbose: true,
  strict: true,
} satisfies Config

Запустіть npx drizzle-kit generate:pg для генерації SQL та npx drizzle-kit push:pg для застосування (або npx drizzle-kit migrate).

Ініціалізація та приклади запитів

// db/index.ts
import { drizzle } from 'drizzle-orm/postgres-js'
import postgres from 'postgres'
import * as schema from './schema'

const connectionString = process.env.DATABASE_URL!

// Для міграцій — один коннект
const migrationClient = postgres(connectionString, { max: 1 })

// Для додатку — пул
const queryClient = postgres(connectionString, {
  max: 20,
  idle_timeout: 30,
  connect_timeout: 10,
})

export const db = drizzle(queryClient, { schema, logger: process.env.NODE_ENV === 'development' })

// Приклади запитів
import { eq, and, desc, ilike, count } from 'drizzle-orm'

// Отримати користувача з постами
const user = await db.query.users.findFirst({
  where: eq(users.email, '[email protected]'),
  with: { posts: { where: eq(posts.published, true), limit: 5 } }
})

// Вставити пост
const [newPost] = await db.insert(posts).values({ title: 'Hello', content: 'World', authorId: user.id }).returning()

// Оновити
await db.update(posts).set({ published: true }).where(eq(posts.id, newPost.id))

// Агрегація: кількість постів у користувача
const [stats] = await db.select({ count: count() }).from(posts).where(eq(posts.authorId, user.id))

// Пагінація
const page = 1, pageSize = 10
const paginatedPosts = await db.select().from(posts)
  .where(eq(posts.authorId, user.id))
  .orderBy(desc(posts.createdAt))
  .limit(pageSize).offset((page - 1) * pageSize)

Які типи запитів підтримує Drizzle?

Drizzle підтримує всі стандартні SQL-операції: SELECT, INSERT, UPDATE, DELETE, JOINи, агрегації, підзапити, віконні функції. Бібліотека надає як Query Builder з ланцюжком методів, так і Relational Query API для зв'язків. Завдяки TypeScript-інференсу всі типи виводяться автоматично, що виключає помилки невідповідності полів.

Як оптимізувати запити з Drizzle?

Використовуйте явні індекси в схемі, пагінацію через LIMIT/OFFSET або курсори, уникайте SELECT *. Для складних звітів застосовуйте віконні функції. Drizzle не генерує неоптимальні запити — ви повністю контролюєте SQL. В одному проекті ми знизили навантаження на БД на 30% за рахунок правильної індексації та денормалізації.

Що входить в роботу

  • Типізована схема бази даних
  • Налаштування міграцій (безпечні apply/rollback)
  • Ініціалізація пулу з'єднань з оптимізацією
  • Написання типових запитів (CRUD, пагінація, пошук)
  • Документація по схемі та API
  • Навчання команди (2 сесії по 2 години)
  • Підтримка 2 тижні після здачі

Порівняння Drizzle і Prisma

Критерій Drizzle Prisma
Типізація Зі схеми на TS, без codegen Codegen в prisma generate
SQL-генерація Явна, повний контроль Автоматична, можлива магія
Edge-середовище Повноцінна підтримка Обмежена (немає Neon, PlanetScale)
Міграції Гнучкі, можна редагувати SQL Автоматичні, складно кастомізувати
Продуктивність 0 overhead, швидше на 30-50% Нативний overhead для кожного запиту

Типові команди міграції Drizzle

Команда Опис
npx drizzle-kit generate:pg Генерація SQL-файлів на основі схеми
npx drizzle-kit push:pg Застосування міграцій до бази
npx drizzle-kit migrate Запуск міграцій у продакшені з перевіркою
npx drizzle-kit introspect:pg Імпорт схеми з існуючої БД

Процес налаштування

  1. Аналіз — вивчаємо поточну схему БД, навантаження та вимоги.
  2. Проектування — створюємо типізовану схему на TypeScript.
  3. Міграції — генеруємо та тестуємо SQL-міграції на staging.
  4. Інтеграція — підключаємо Drizzle до проекту, налаштовуємо пул та лог.
  5. Деплой — розгортаємо з гарантією rollback.

Строки та гарантії

Базове налаштування — від 1 дня. Повна інтеграція з тестами — 1–2 дні. Портування з іншої ORM — 2–4 дні. Гарантуємо якість: всі міграції та запити тестуються на staging перед деплоєм. У нас понад 50 успішних проектів з Drizzle. Замовте налаштування Drizzle ORM — ми реалізуємо міграції та типізацію за 1–2 дні. Отримайте консультацію щодо міграції з Prisma на Drizzle — ми підготуємо план за один день. Зв'яжіться з нами — оцінимо ваш проект і запропонуємо оптимальне рішення.

Детальніше про Drizzle ORM читайте на GitHub.

Послуги бекенд-розробки: production-grade надійність

На production-сервері о 3:14 ночі черга Laravel Jobs перестала оброблятися — 40 000 необроблених завдань у Redis. Причина: worker упав через memory leak у статичній змінній Eloquent observer, supervisor не перезапустив через misconfigured stopwaitsecs. Ми розбирали такий інцидент на проекті з 500 RPS: діагностика 4 години, фікс — 20 хвилин. Щоб ви не втрачали гроші, пропонуємо послуги бекенд-розробки з акцентом на production-grade надійність — 10+ років досвіду, 50+ проектів, 5 років на ринку. Оцінимо ваш проект за 2 дні.

Які проблеми вирішуємо

N+1 запити: головний вбивця швидкості

N+1 — найпоширеніша причина повільних сторінок у Laravel-додатках. Стандартна історія: сторінка працювала нормально на dev з 10 записами, на production з 10 000 — 8-секундне завантаження.

Laravel Debugbar у dev-оточенні показує кількість запитів. Більше 20 — сигнал для audit.

Model::preventLazyLoading(! app()->isProduction());

Telescope для профілювання: логує всі запити, jobs, mail, notifications з деталізацією. Після впровадження eager loading час завантаження сторінки падає з 8 с до 0.3 с — у 27 разів.

Memory leak у статичних змінних

У Laravel Octane або Swoole додаток тримається в пам’яті між запитами. Статичні змінні не скидаються — призводять до неконтрольованого росту пам’яті. Використовуємо defer-функції та контейнерні біндинги для коректного скидання стану.

Неправильний connection pool

Rails, Laravel, Django відкривають нове з'єднання PostgreSQL на кожен PHP/Python процес. 100 воркерів — 100 з'єднань. PostgreSQL деградує від 200+ активних з'єднань через overhead на управління.

PgBouncer у transaction pooling: 1000 воркерів → 20–50 реальних з'єднань. Це знижує latency на 40% та зменшує витрати на хостинг на 30% — при середній вартості хостингу $2,000/міс економить $600/міс. GIN-індекс для JSONB до 100 разів швидший за B-tree при пошуку.

Як Octane справляється з високим навантаженням?

Laravel Octane (RoadRunner або Swoole) прибирає overhead bootstrap на кожен HTTP-запит. Приріст: 3–8x на синтетичних бенчмарках, 2–4x на реальних додатках. Важливо: не зберігати стан у статичних змінних — застосовуємо це на проектах >1000 RPS.

Як PostgreSQL допомагає уникнути повільних запитів?

Використовуємо composite indexes для WHERE + ORDER BY, partial indexes для фільтрів з високою селективністю, GIN-індекси для JSONB та full-text search. to_tsvector + GIN замість LIKE '%query%' — запобігає seq scan навіть на мільйонах записів. Аналізуємо плани через EXPLAIN ANALYZE та pg_stat_statements.

Як обрати стек для вашого проекту?

Стек Коли використовувати
Laravel + Octane CRUD, бізнес-логіка, REST/GraphQL API, адмінки
Node.js (Fastify) Realtime WebSocket, streaming, serverless, висока I/O concurrency
Go Високонавантажені мікросервіси (>10k RPS), gRPC, DevOps-інструменти
Django + DRF ML-пайплайни, інтеграція з AI, складна обробка даних
Ruby on Rails Швидкий MVP з багатим екосистемою гемів

Node.js виправданий для realtime: Laravel публікує події в Redis Pub/Sub, Node.js підписується та транслює клієнтам. Go — для goroutines (10k з'єднань на сервер — норма), але розробка повільніша, ніж Laravel.

Чому Redis критичний для продуктивності?

Redis виконує кілька ролей:

Роль Деталі
Кеш Кешування результатів важких запитів, фрагментів HTML
Черги Backend для Laravel Queue / Celery
Session store Distributed sessions в multi-instance оточенні
Pub/Sub Realtime події між сервісами
Rate limiting Sliding window counters для API throttling
Leaderboards Sorted Sets для рейтингів

Redis Cluster для горизонтального масштабування, Sentinel для автоматичного failover. Замовте консультацію щодо оптимізації Redis для вашого проекту.

Що входить в роботу під ключ

  • Архітектурне проектування (документація API, схема БД, діаграма сервісів)
  • Реалізація за узгодженим ТЗ з code review
  • Налаштування CI/CD (GitHub Actions, Docker), моніторингу (Sentry, Grafana), алертингу
  • Навантажувальне тестування (k6, wrk) зі звітом
  • Передача вихідних кодів, доступів, інструкція з деплою
  • Навчання команди замовника (2–3 сесії)
  • Гарантійна підтримка 1 місяць після здачі

Орієнтири по термінах

Задача Термін
REST API для мобільного/SPA (середня складність) 6–12 тижнів
Backend зі складною бізнес-логікою + інтеграції 12–20 тижнів
Високонавантажений сервіс на Go 8–16 тижнів
Міграція legacy PHP на Laravel 16–32 тижні

Вартість розраховується індивідуально після аналізу вимог до навантаження, інтеграцій та бізнес-логіки. Зв'яжіться з нами для безкоштовного аудиту вашого поточного backend — отримайте план оптимізації за 2 дні. Замовте консультацію та дізнайтеся, як знизити витрати на інфраструктуру на 30% без втрати продуктивності.