3 Кормилец доками 4 Направляющий 5 Почти архитектор ~10 мин

Базы данных для новичка: таблицы, индексы и миграции

Где живут данные твоего сайта и как случайно не снести их одной командой

Что такое база данных простыми словами: таблицы, индексы, миграции и типы колонок. Разбираем главные грабли вайбкодера - и как их обойти заранее.

Скиллы ECC в этом уроке: postgres-patternsprisma-patterns

Что такое база данных простыми словами

Представь огромный картотечный шкаф из старой библиотеки. Внутри - ящики (это таблицы). В каждом ящике лежат карточки (это строки). А на каждой карточке заполнены одни и те же поля: имя, дата, телефон (это колонки). Всё. Никакой магии.

Вот этот умный шкаф и есть база данных . Всё, что твоё приложение должно помнить навсегда - кто зарегистрировался, что заказали, какой пост лайкнули - живёт именно тут. Закрыл сайт, выключил сервер, споткнулся о провод и обесточил полквартала - данные на месте.

А разговаривает приложение со шкафом не по-человечески, а на отдельном языке - SQL. Это как записка библиотекарю: «принеси все карточки, где город = Москва». Зубрить SQL наизусть тебе как вайбкодеру не надо - его пишет агент или умная прослойка. Но понимать, что именно агент просит у шкафа, дико полезно. Иначе он однажды попросит «вынеси вообще всё», а ты и глазом не моргнёшь.

Картотечный шкаф-робот: ящики-таблицы, карточки-строки, к каждой колонке подпись
Таблица - ящик, строка - карточка, колонка - поле в карточке.

Зачем вайбкодеру понимать базу данных

Рано или поздно твой сайт перестанет быть красивой картинкой и захочет что-то запоминать: список заказов, аккаунты, комментарии. Вот тут и появляется база данных. А вместе с ней - целый зоопарк ошибок, от которых сайт либо тормозит, либо тихо теряет данные. Тихо - это самое противное.

Понимаешь, как устроен шкаф - и сразу выигрываешь четыре вещи:

  • не паникуешь, когда агент роняет слова «миграция» и «индекс»;
  • не даёшь агенту по незнанию стереть всю таблицу одной командой;
  • получаешь быстрый сайт, а не такой, где список грузится по 10 секунд и пользователь успевает сбежать к конкуренту;
  • ставишь задачу так, что агент делает правильно с первого раза.

Вся разница между «мой сайт иногда теряет заказы и тормозит» и «всё летает и ничего не пропадает» сводится к трём словам: тип колонки, индекс, миграция. Поехали.

Как агент работает с базой данных: четыре кита

1. Таблицы и типы колонок: форма карточки

Заводишь ящик (таблицу) - сразу для каждого поля скажи, что в нём лежит: текст, число, дата, «да/нет». Это и есть тип колонки. Промахнёшься с типом - потом переделывать долго и больно.

У опытных есть готовые правила, что чем хранить (это прямо из скилла postgres-patterns):

Правильные типы
  • Деньги - типом numeric (точное число), чтобы 0.1 + 0.2 не превратилось в 0.30000004.
  • Дата и время - timestamptz (с часовым поясом), чтобы клиент с Бали и из Москвы видели верное время.
  • Текст - просто text, без искусственных лимитов длины.
  • Галочка да/нет - boolean, а не строка «yes»/«no».
Чем НЕ надо хранить
  • Деньги через float - дробные копейки уезжают в туман, бухгалтерия плачет.
  • Дата через обычный текст - потом ни отсортировать, ни сравнить.
  • «Да/нет» цифрой 1 и 0 или строкой - каждый раз гадаешь, что это вообще значит.
  • Цена строкой «1000 руб» - ну-ка сложи такое с «990 руб».
Мем: спокойный кот за float и тот же кот в панике, когда в сумме появились лишние девятки
float и деньги: сначала кажется, что всё ок.

2. Что такое индекс в базе данных

Представь телефонную книгу, где имена идут вперемешку. Чтобы найти «Петрова», ты читаешь её всю с первой страницы. Тысяча страниц - тысяча страниц чтения ради одного имени. Вот так и работает база данных без индекса. Медленно и обидно.

Индекс - это тот самый алфавитный указатель. Говоришь шкафу: «держи отдельное оглавление по полю email» - и поиск по email становится мгновенным. Без «прочитай миллион карточек и вспотей».

3. Что такое миграция базы данных

Сайт растёт, и в карточку надо добавить новое поле - скажем, «телефон». Лезть в живой шкаф руками опасно: что-нибудь да заденёшь. Поэтому изменения структуры делают миграциями - записанными по шагам «чертежами ремонта».

И вот тут живёт САМАЯ опасная грабля вайбкодера. Команда, которой агенты обычно двигают эти чертежи, называется migrate dev. При определённых условиях она спрашивает разрешения стереть всю базу: если данные «не сходятся с чертежом», она обнуляет таблицы целиком (это прямо из скилла prisma-patterns). Один клик «да» - и привет.

Два рабочих у шкафа: один с маленьким чертежом аккуратно докручивает полку, второй замахивается кувалдой
migrate deploy - аккуратный ремонт. migrate dev на проде - кувалда.

4. Опасные команды: deleteMany и updateMany

Есть команды, которые меняют или удаляют много карточек разом. Мощные - и оттого коварные. Две главные ловушки (обе из prisma-patterns):

  • deleteMany без условия стирает ВСЁ. Хотел удалить заказы одного клиента, забыл дописать «чьи именно» - и шкаф молча вынес весь ящик. Без вопросов. Без «вы точно уверены?». Без корзины.
  • updateMany возвращает число, а не записи. Массово что-то поменял и думаешь, что получил назад обновлённые карточки. А получил сухую цифру «изменено: 5 штук». Кто эти пятеро - выясняй отдельным запросом.

Пример из жизни: как ломается интернет-магазин

Делаешь с агентом интернет-магазинчик. Сначала всё прекрасно: пять товаров, три заказа, летает как ракета. Через месяц у тебя тысяча заказов - и вот расплата:

  1. Страница «мои заказы» грузится 8 секунд - потому что нет индекса по полю «покупатель», и база каждый раз перечитывает всю таблицу.
  2. В отчёте сумма заказа «1499.9999998» - потому что цену сохранили как float, а не numeric.
  3. Ты попросил агента «удали тестовые заказы», он запустил deleteMany без условия - и снёс все заказы, включая боевые.

Ни одна из этих бед - не «глюк ИИ». Это три понятные грабли, и все три снимаются одной грамотной постановкой задачи:

Промпт - скопируй и попробуй

Спроектируй базу данных для интернет-магазина. Соблюдай правила:

  1. Цену храни точным числом для денег (numeric), НЕ дробным float. Дату и время - с часовым поясом.
  2. Поставь индекс на каждое поле, по которому будем искать или сортировать: покупатель, дата создания, статус заказа.
  3. Любую массовую команду удаления или обновления делай ТОЛЬКО с условием, над какими именно записями работаем. Без условия - стоп.
  4. Команду migrate dev используй только локально. Для боевого сервера готовь migrate deploy. Перед удалением чего-либо сначала покажи мне план.
  5. Объясни простыми словами, какие таблицы ты создал и зачем каждая.

Хитрость про скорость: курсорная пагинация

Когда список длинный (лента постов, заказы, товары), новички просят «дай мне страницу 50». Чтобы её отдать, база вынуждена отсчитать и пролистать первые 49 страниц впустую. Чем дальше страница - тем сильнее она кряхтит.

Опытные делают курсорную пагинацию : «дай 20 штук после последней показанной». Скорость одинаковая - хоть на первой странице, хоть на тысячной. Агент сам не предложил? Просто попроси: «сделай листание ленты курсором, а не по номерам страниц».

Частые ошибки новичка в базах данных

  • Хранишь деньги через float. Получишь дробные копейки и кривые суммы. Только numeric.
  • Забыл про индексы. На маленьких данных незаметно, на больших сайт встаёт колом. Индексируй поля поиска и сортировки.
  • Запустил migrate dev на боевом сайте. Может стереть всю базу. На проде - только migrate deploy.
  • Массово удаляешь или меняешь без условия. deleteMany без условия сносит всю таблицу. Всегда указывай «над кем».
  • Думаешь, что updateMany вернёт записи. Он вернёт только число. Сами обновлённые карточки доставай отдельным запросом.
  • Не делаешь бэкап перед опасной операцией. Резервная копия - твоя машина времени. Один раз спасёт весь проект.

TL;DR - если коротко

  • База данных - умный шкаф с картотекой. Таблицы - ящики, строки - карточки, колонки - поля.
  • Индекс - оглавление. Нет его - база читает весь ящик ради одной карточки и дико тормозит.
  • Миграция - ремонт шкафа по чертежу. `migrate dev` умеет стереть всё - ей место на твоём компе, не на проде.
  • `deleteMany` без условия сносит всю таблицу. `updateMany` отдаёт число, а не сами записи. Запомни оба.
  • Деньги - только точным `numeric`. Иначе однажды в корзине окажется «99.99999999 рубля».
  • Не проси агента «сделай базу как-нибудь». Задавай типы, индексы и правила удаления заранее.

Поиск по вики

Нажмите Esc для закрытия

Введите запрос для мгновенного поиска по всем страницам курсов и уроков.