Правила именования базы данных для админ‑панели, которые остаются читабельными
Используйте правила именования для админ‑панели, чтобы автоматически сгенерированные экраны были понятными: ясные правила для таблиц и полей, enums, связей и краткий чек‑лист.

Почему имена решают, кажется ли админ‑панель понятной или запутанной
Большинство админ‑панелей строятся из вашей модели данных. Имена таблиц и полей оказываются в пунктах меню, заголовках страниц, заголовках колонок, метках фильтров и даже в словах, которые люди вводят в поиск.
Когда имена понятны, администратор может пробежать взглядом список и понять его за секунды. Когда имена неочевидны, он останавливается, догадывается, открывает запись, возвращается и пробует снова. Эти колебания накапливаются. В итоге это превращается в вопросы поддержки «Как найти нужного клиента?» и в руководства по обучению, которые никто не хочет читать.
Разработчики обычно называют вещи так, чтобы им было удобно строить и отлаживать. Операторы называют вещи так, чтобы выполнять работу. Разработчику может быть достаточно acct, addr1 или stat, потому что он помнит, что это значит. Оператору нужен «Account», «Address line 1» и «Status» без расшифровки.
В админ‑экране «читабельным» обычно считается:
- Можно пробежать таблицу взглядом и понять каждую колонку без открытия строки.
- Можно искать и фильтровать, используя те же слова, что и в повседневной работе.
- Можно сортировать и сравнивать значения без сюрпризов (например, даты — действительно даты, статусы — согласованы).
Если вы используете платформу, которая генерирует экраны из модели (например, Data Designer и админ‑вью в AppMaster), то именование становится частью дизайна UI. Хорошие имена дают аккуратные экраны по умолчанию с первого дня, ещё до того как вы начнёте править метки и раскладки.
Простой базовый набор правил, которого может придерживаться вся команда
Если хотите, чтобы сгенерированные админ‑экраны выглядели аккуратно с первого дня, согласуйте базу до того, как кто‑то добавит первую таблицу. Большинство проблем с именами не технические — они про несогласованность.
Выберите один стиль идентификаторов и не смешивайте его. Для баз данных snake_case обычно проще читать и искать. Если ваш стек ожидает camelCase, используйте его везде (таблицы, колонки, внешние ключи, enums). Смена стиля в середине проекта — вот что делает метки и фильтры случайными.
Базовые правила, которые подходят большинству команд:
- Используйте полные слова:
customer_id, а неcust_id;description, а неdesc. - Для сущностей — существительные, для действий — глаголы:
invoice,payment,refund_requested. - Согласованные имена времён:
created_at,updated_at,deleted_at. - Избегайте расплывчатых слов вроде
data,info,valueилиtype, если вы не добавляете контекст (например,shipping_address,payout_method). - Держите единство единственного/множественного числа (многие команды используют множественные имена таблиц, например
customers, а для колонок — единственное, вродеcustomer_id).
Напишите маленький глоссарий и держите его на виду. Решите рано: customer, client, account или user — и используйте один термин. Так же поступайте с «order» vs «purchase» или «ticket» vs «case».
Быстрая проверка: если двое людей могут посмотреть на колонку account_status и согласиться, что она значит, не задавая вопросов, базовая политика работает. Если нет — переименуйте до того, как строить экраны и фильтры.
Правила именования таблиц, которые аккуратно мапятся на меню и списки
Большинство админ‑панелей превращают имена таблиц в пункты меню, заголовки списков и хлебные крошки. Ваша схема — не только для инженеров. Это первый черновик интерфейса.
Выберите один стиль для таблиц сущностей и придерживайтесь его: единственное (user, invoice, ticket) или множественное (users, invoices, tickets). Единственное часто лучше читается в заголовках форм («Edit Ticket»), а множественное — в меню («Tickets»). Любой вариант приемлем. Смешивание делает навигацию непоследовательной.
Называйте таблицы по тому, чем они являются, а не по тому, что делают. Таблица должна представлять предмет, на который можно указать. payment — это предмет; processing — действие. Если позже появятся refunds, retries и settlements, имя processing станет вводящим в заблуждение.
Правила, которые сохраняют меню и списки аккуратными:
- Используйте конкретные существительные (
customer,subscription,invoice,ticket_message). - Избегайте «ведёрных» таблиц для постоянных данных (
settings,misc,temp,data). Разбейте их на реальные сущности (notification_setting,tax_rate,feature_flag). - Предпочитайте короткие, читаемые составные имена с подчёркиванием (
purchase_order,support_ticket) вместо аббревиатур. - Добавляйте префикс модуля только когда он предотвращает конфликты (например,
billing_invoicevsinvoice). Если префикс используете — делайте это согласованно во всём модуле.
Если вы используете AppMaster для генерации экранов прямо из схемы, устойчивые имена‑сущности обычно дают аккуратное меню и представление списка по умолчанию с меньшей доработкой позже.
Join‑таблицы и идентификаторы: как сохранить many‑to‑many читабельным
Many‑to‑many связи — место, где админ‑панели часто начинают выглядеть грязно. Если join‑таблица и её ключи названы хорошо, сгенерированные экраны остаются читаемыми без ручной правки.
Начните с одного скучного правила и не нарушайте его: у каждой таблицы первичный ключ называется id. Не смешивайте user_id как первичный ключ в одной таблице и id в другой. Единые идентификаторы делают отношения предсказуемыми и помогают сгенерированным формам и полям ссылок оставаться согласованными.
Для чистых join‑таблиц называйте их по обеим сущностям, используя один шаблон и порядок. Распространённые варианты — в алфавитном порядке (product_tag) или «главная сущность первой» (user_role). Выберите порядок и держитесь его.
Избегайте расплывчатых имён вроде links или mappings, если таблица не хранит действительно общие связи между объектами. В большинстве админ‑панелей конкретность лучше хитрости.
Когда join‑таблица становится реальной сущностью
Если отношение имеет дополнительные поля, рассматривайте его как самостоятельную модель и называйте её существительным, понятным людям: membership, assignment, subscription. Например, если у роли пользователя есть starts_at, ends_at и granted_by, user_role подойдёт, но membership может в UI читаться лучше.
Простой набор правил, который сохраняет экраны профессиональными:
- Используйте
idкак первичный ключ в каждой таблице. - Называйте join‑таблицы по обеим сущностям в согласованном порядке (
user_role). - Используйте понятные внешние ключи вроде
user_idиrole_id. - Добавляйте правило уникальности, которое отражает реальность (например, один
role_idнаuser_id). - Если вы храните историю, делайте правило уникальности равным «активным» записям (например, уникально там, где
ended_at= null).
Эти выборы выдерживают рост данных и хорошо работают с Data Designer в AppMaster, где экраны могут генерироваться прямо из модели.
Шаблоны имен полей, которые дают понятные столбцы и фильтры
Имена полей делают больше, чем помогают разработчикам. Они определяют, что пользователи увидят в заголовках колонок, метках фильтров и полях форм.
Предсказуемые суффиксы убирают догадки:
- Используйте
_idдля внешних ключей:customer_id,assigned_agent_id. - Используйте
_atдля времён:created_at,paid_at,closed_at. - Используйте
_countдля счётчиков:login_count,attachment_count.
Булевы поля должны читаться как простые предложения. Предпочитайте префиксы is_ и has_, чтобы чекбоксы были понятны сразу: is_active, has_paid, is_verified. Избегайте двойных отрицаний вроде is_not_approved. Если нужен «не»‑состояние, моделируйте позитив и инвертируйте логику в коде.
Поля денег часто вызывают путаницу в решётках админки. Выберите один подход и придерживайтесь его: храните в минимальных единицах (центах) как integer или храните decimal с фиксированной точностью. Назовите поле так, чтобы никто не догадывался. Например: total_amount_cents + currency_code, или total_amount + currency_code. Не смешивайте price, amount и total, если они не обозначают разные понятия.
Текстовые поля должны явно отражать назначение, а не просто тип. description виден пользователю. internal_comment — приватный. notes — сборный вариант и его стоит использовать осторожно. Если несколько заметок, называйте по аудитории: customer_note, agent_note.
Контактные поля должны быть буквальными, потому что часто становятся быстрыми фильтрами: website_url, contact_email, billing_email. В сгенерированных AppMaster админ‑экранах такие имена обычно превращаются в аккуратные метки по умолчанию.
Связи и внешние ключи: имена, которые объясняют модель данных
Хорошие связи читаются как простая английская фраза. Когда админ‑панель генерируется из базы, имена внешних ключей часто становятся заголовками колонок, фильтрами и метками форм.
Держитесь одного правила: колонка внешнего ключа — имя ссылаемой таблицы плюс _id. Если есть customer.id, используйте customer_id. Если есть order.id, используйте order_id. Такая согласованность делает очевидным, на что указывает колонка.
Self‑relations требуют дополнительной ясности, потому что их легко неправильно прочитать. Избегайте общего related_id. Используйте имена, которые объясняют направление и смысл: parent_id для деревьев, manager_id для орг‑структур или merged_into_id для объединений.
Когда связь включает join‑таблицу, называйте её так, чтобы она читалась как предложение. Например, ticket_assignee.user_id понятнее, чем ticket_user.user_id, если роль — «assignee» (а не «reporter» или «watcher").
Практические проверки, которые предотвращают большинство проблем:
- Не переиспользуйте
owner_idс разными значениями в разных таблицах. Предпочитайтеcreated_by_user_id,account_manager_user_idилиbilling_contact_id. - Если у вас несколько связей на одну таблицу, указывайте роль:
requested_by_user_idиapproved_by_user_id. - Выберите один маркер soft delete и используйте его везде.
deleted_atшироко понятен и хорошо работает с фильтрами.
Если вы будете строить экраны в AppMaster позже, эти имена появятся повсюду, поэтому небольшая осторожность сейчас сэкономит много правок UI позже.
Enums и поля статуса, которые остаются понятными со временем
Если админ‑панель генерируется из базы, самый быстрый способ сделать экраны беспорядочными — разбросать смысл по множеству мелких флагов. Предпочитайте один понятный enum‑статус для основного жизненного цикла записи и держите дополнительные флаги только для действительно отдельного поведения.
Полезное правило: если пользователи будут спрашивать «Где сейчас этот элемент в своём пути?», это статус. Если вопрос «Нужно ли его скрыть?» или «Заблокирован ли он?», это отдельный булев флаг.
Один статус лучше пяти булевых флагов
Вместо is_new, is_in_progress, is_done, is_cancelled используйте одно поле ticket_status. Оно лучше читается в колонках списков, фильтрах и массовых действиях. Также это исключает невозможные комбинации вроде «done + in_progress».
Держите значения enum стабильными. Текст в UI можно менять, а хранимые значения менять нежелательно. Храните pending, а не waiting_for_review. Храните rejected, а не rejected_by_manager. Дружелюбные метки можно показывать позже без миграции данных.
Когда нужен дополнительный контекст, добавьте отдельное поле, а не перегружайте статус. Пример: оставьте payment_status для жизненного цикла, а для причины неудачи добавьте failure_reason (текст).
Именуйте enum по домену (чтобы фильтры были понятны)
Добавляйте префикс домена, чтобы экраны оставались читабельными, когда у разных моделей есть «status»:
payment_status(чекаут заказа)ticket_priority(срочность поддержки)user_role(уровень доступа)invoice_status(жизненный цикл выставления счетов)delivery_status(жизненный цикл доставки)
Отделяйте жизненный цикл от операционных флагов. Например: status описывает, где запись находится в рабочем процессе, в то время как is_archived означает, что её следует скрыть из повседневных списков.
Напишите однострочное объяснение для каждого значения enum в командных заметках. Вы забудете позже разницу между cancelled и voided. В AppMaster такие короткие определения помогают сохранять согласованные выпадающие списки и фильтры между вебом и мобильными экранами.
Крайние случаи: даты, поля аудита и колонки type
Руководства по именам часто охватывают таблицы и базовые поля, но админ‑панели путаются в крайних случаях. Даты, поля аудита и колонки type — это места, где путаные имена превращаются в путаные экраны.
Для дат и времён сделайте имя говорящим: запланировано, фактическое или напоминание? Простейший паттерн — глагол по смыслу плюс понятный суффикс. Например, due_at (планируемый дедлайн) и completed_at (фактическое завершение) будут читаться как понятные колонки и фильтры. Избегайте расплывчатых пар вроде start_date и end_date, если на самом деле вы имеете в виду scheduled_at и finished_at.
Опциональные связи — ещё одна ловушка. Не придумывайте новых шаблонов для каждой таблицы. Сохраняйте имя связи стабильным и выражайте «опциональность» через nullable, а не через переименование поля. manager_id остаётся manager_id, даже если он необязателен.
Адреса могут выглядеть нормально в коде, но некрасиво в таблицах. Нумерованные строки годятся, только если команда договорилась об их назначении. Делайте их явными:
address_line1,address_line2,city,region,postal_code,country_code- Избегайте
address1,address2(хуже читаются, легче дублируются)
Поля аудита должны быть скучными намеренно:
created_at,updated_atcreated_by_id,updated_by_id(только если действительно нужна история по пользователям)
Будьте осторожны с type. Это почти всегда слишком общее и со временем стареет. Вместо type называйте по смыслу: payment_method, ticket_channel, customer_tier. В схеме‑дривен админке (включая AppMaster) такой выбор часто определяет разницу между понятным фильтром и запутанным выпадающим списком.
Пример: как назвать модель тикета поддержки, чтобы она выглядела хорошо в админке
Небольшая реалистичная настройка поддержки: клиенты пишут, сотрудники отвечают, тикеты можно тегировать. Правила именования — то, что делает авто‑сгенерированные меню, списки и фильтры очевидными.
Начните с имён таблиц, которые читаются как существительные в сайдбаре:
customerticketticket_messageticket_tagticket_tag_link
В большинстве админ‑панелей они превратятся в метки типа «Tickets» и «Ticket Messages», а join‑таблица не будет мешать.
Для экрана списка тикетов выбирайте имена полей, которые станут понятными заголовками колонок и фильтрами:
subject,status,priorityassigned_to_id(указывает на сотрудника)last_message_at(помогает сортировать по последнему сообщению)created_at(стандартно и предсказуемо)
Enum‑ы — частое место, где читабельность ломается позже, поэтому держите набор стабильным и простым:
ticket_status:new,open,pending_customer,resolved,closedticket_priority:low,normal,high,urgent
Одно решение, которое предотвращает постоянную путаницу: не перегружайте «customer». В поддержке запросчик не всегда является клиентом (коллега может отправить от имени клиента). Если вы храните человека, который отправил тикет, назовите поле requester_id, а отдельно храните customer_id для аккаунта, о котором идёт речь. Это разделение делает формы и фильтры правдивыми с самого начала.
Пошагово: как назвать новую модель перед созданием экранов
Проще сохранить экраны читабельными, если называть вещи, пока вы думаете простыми словами, а не уже строите.
Повторяемый процесс для каждой фичи
-
Начните с мини‑глоссария (5–10 терминов). Запишите слова, которые нетехнический коллега использовал бы на встрече, затем выберите по одному предпочитаемому термину для каждой концепции (например, «customer» vs «client").
-
Набросайте экраны, которые ожидаете: список, карточка, создание, редактирование. Для списка решите, какие 5–8 колонок должны быть понятны сразу. Если имя поля будет выглядеть странно как заголовок, его стоит доработать.
-
Набросайте таблицы и связи, затем называйте поля по правилам суффиксов (
*_id,*_at,is_*,*_count). Когда вы потом генерируете админ‑экраны (включая AppMaster), эти паттерны дают аккуратные метки и предсказуемые фильтры.
Перед тем как двигаться дальше, убедитесь, что вы не смешиваете стили (customer_id в одной таблице и clientId в другой). Согласованность важнее хитрости.
-
Определите enum‑ы заранее, а не после появления первого UI. Напишите однострочное пояснение для каждого значения, как будто объясняете его сотруднику поддержки. Предпочитайте значения, которые выдержат изменения, например
pending,active,archived(неnew,newer,newest). -
Проведите «прочтение заголовков колонок». Представьте себя админом, пробегающим список взглядом.
- Были бы понятны «Created At», «Updated At», «Status», «Assigned To», «Total Amount» без инструкций?
- Есть ли поля, которые выглядят как внутренний код (
tmp_flag,x_type,data1)? - Являются ли единицы очевидными (
amount_centsvsamount,duration_secondsvsduration)?
Если что‑то звучит непонятно вслух — переименуйте сейчас. Переименование позже возможно, но часто протекает в отчёты, фильтры и привычки.
Частые ошибки именования, которые делают админ‑панели неудобными
Если схема грязная, экраны будут грязными, независимо от того, насколько красив UI. Правила именования — это не про «стиль», а про повседневную удобочитаемость.
Первая ловушка — смешанная лексика. Если в одной таблице client, а в другой customer, меню, фильтры и результаты поиска кажутся описывающими разные вещи. Выберите одно слово для каждой ключевой концепции и используйте его везде, в том числе в именах связей.
Ещё одна проблема — чрезмерные сокращения. Аббревиатуры вроде addr, misc или info экономят пару символов, но сильно снижают понятность в таблицах и экспортируемых данных.
Третья ошибка — запекание UI‑потока в базу. Поле вроде new_customer_wizard_step имеет смысл при запуске, но путает, когда процесс меняется. Храните бизнес‑факт (onboarding_status) и дайте UI решать, как вести пользователя.
Также остерегайтесь перегрузки булевыми флагами. Когда добавляете is_new, is_open, is_closed, рано или поздно получите конфликтующие состояния и непонятные фильтры. Предпочитайте одно поле статуса с небольшим набором значений.
Красные флаги, которые обычно ведут к уродливым экранам:
- Два разных имени для одного и того же (
client_idvscustomer_id) - «Ящики для мусора» в колонках (
notes,misc,extra), где смешиваются разные данные - Имена, зависящие от времени (
summer_campaign_*), которые переживают кампанию - Множество булевых полей, описывающих одно состояние
- Переименования, сделанные без плана миграции
Переименование — это не просто найти‑и‑заменить. Если вы меняете customer_phone на phone_number, спланируйте миграцию, обновите сгенерированные экраны и сохраните обратную совместимость там, где нужно (особенно если внешние системы читают API). В AppMaster аккуратные имена окупаются сразу, потому что списки, формы и фильтры наследуют метки из модели.
Быстрый чек‑лист перед релизом админ‑панели
Прежде чем объявить схему «готовой», пройдитесь по ней глазами человека, который будет жить в админ‑панели каждый день.
- Таблицы звучат как реальные вещи. Коллега должен уметь сказать, что представляет таблица (
ticket,customer,invoice) без домыслов. - Ключевые поля следуют предсказуемым суффиксам. Используйте шаблоны:
*_idдля ссылок,*_atдля времён,*_amount(или*_amount_cents) для денег иis_*для булевых флагов. - Enum‑ы стабильны и просты. Храните значения вроде
pending,paid,failed, а не фразы из UI, которые поменяются. - Новый коллега может вывести смысл. Если поля оказались бы в сгенерированном списке без подсказок, была бы интенция очевидна?
- Расплывчатые слова удалены или уточнены. Замените
data,value,type,infoна конкретныеstatus,source,category,notesилиexternal_reference.
Если вы используете Data Designer в AppMaster для генерации админ‑вью, этот чек‑лист практически моментально полезен: понятные имена дают понятные колонки и фильтры, и вам придётся меньше править метки после того, как пользователи начнут работать в системе.
Следующие шаги: превратите именование в привычку и сохраняйте согласованность экранов
Хорошие имена — это не разовая чистка, а небольшая рутина, которая сохраняет админ‑UI читабельным по мере роста схемы.
Начните с одного существующего модуля и примените правила только к следующей таблице, которую добавите. Это избегает пугающего переписывания и даёт реальную площадку для практики. Если следующая фича добавляет «returns» в систему заказов, назовите таблицу, внешние ключи и статусы по вашим шаблонам с самого начала, а затем переиспользуйте подход дальше.
Держите одностраничное руководство по именованию рядом с местом, где вы работаете со схемой. Оно должно быть коротким: как вы называете таблицы, первичные ключи, внешние ключи, временные метки и enum‑ы статусов. Цель — быстрые решения, а не долгие споры.
Если вы строите в AppMaster, полезно задать эти паттерны в Data Designer до того, как тронете UI. Когда вы переименовываете таблицы или поля, перегенерируйте приложение, чтобы экраны, API и логика оставались синхронизированы, а не расходились.
Лёгкий этап ревью перед каждым релизом обычно достаточен:
- Читаются ли имена таблиц и полей как пункты меню, заголовки колонок и фильтры?
- Ясны ли статусы и enum‑ы без дополнительных объяснений?
- Объясняют ли связи и внешние ключи себя (без таинственных аббревиатур)?
- Называются ли похожие модели одинаково (одни и те же слова, одинаковый порядок)?
Со временем реальная выгода — это согласованность. Когда каждая новая модель следует одним и тем же правилам, ваши админ‑панели начинают выглядеть продуманными даже если они сгенерированы, потому что метки и списки читаются как единый продукт.
Вопросы и ответы
Используйте имена, которые читаются как то, чем запись является, а не что она делает. Таблица ticket или invoice превратится в понятный пункт меню, тогда как processing быстро станет запутанной, когда процесс поменяется.
Выберите один стиль и придерживайтесь его повсюду. Для большинства баз snake_case легче сканировать и помогает сгенерированным меткам и фильтрам не выглядеть случайно.
По умолчанию используйте полные понятные слова, потому что они станут заголовками столбцов и метками фильтров. Аббревиатуры вроде acct или addr1 обычно заставляют операторов задуматься, даже если разработчики понимают их.
Выберите один подход и соблюдайте его: либо единственное (ticket), либо множественное (tickets). Главное, чтобы навигация и заголовки страниц не меняли стиль между модулями.
Одна простая догма: первичный ключ каждой таблицы — id, а внешние ключи выглядят как something_id. Это делает связи предсказуемыми и помогает сгенерированным формам и полям ссылок выглядеть единообразно.
Именуйте чистые join‑таблицы по двум сущностям в одном согласованном порядке, например user_role или product_tag. Если у отношения появляются свои поля и смысл, переименуйте таблицу в реальное существительное, например membership или assignment, чтобы UI читался естественно.
Используйте предсказуемые суффиксы, соответствующие типу и назначению данных: _at для времён, _count для счётчиков. Для булевых полей предпочитайте is_ и has_, тогда чекбоксы в сгенерированных экранах будут читаться как простые предложения.
Предпочитайте одно понятное поле статуса для основного жизненного цикла, например ticket_status или invoice_status, вместо нескольких пересекающихся булевых флагов. Храните значения стабильными и простыми, чтобы можно было менять текст отображения без миграций данных.
Не используйте одно и то же общее имя вроде owner_id или type, когда в разных контекстах оно означает разное. Применяйте роль‑специфичные имена: created_by_user_id, approved_by_user_id, payment_method, чтобы экраны и фильтры были понятны сами по себе.
Переименовывайте лучше на раннем этапе, до того как экраны, фильтры и отчёты начнут зависеть от старых имён. В AppMaster обновите имена в Data Designer и перегенерируйте приложение, чтобы UI и API оставались согласованными, а не расходились со временем.


