Решён
Как вы себе представляете базу данных пользователя?

Игорь JOIN SQL и базы данных
1.5k
7

Пишу курсовую по проектированию информационных систем, застрял на моменте с архитектурой хранения данных о пользователях.

Понятно что есть логин, пароль (хеш), email. Но дальше начинается каша. Роли хранить отдельной таблицей или массивом? Настройки пользователя - отдельная таблица или JSON-поле прямо в user? История действий - туда же или вообще в отдельную БД?

Интересно, как вы вообще себе представляете "идеальную" базу данных пользователя. Не академически, а как реально делаете в своих проектах.

Решение
66
Эксперт • 1 ответ

Смотри, базовый минимум который я кладу в таблицу users всегда один и тот же:

CREATE TABLE users (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  email VARCHAR(255) UNIQUE NOT NULL,
  password_hash VARCHAR(255) NOT NULL,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW(),
  deleted_at TIMESTAMPTZ NULL
);

Все. Больше ничего. Роли - отдельная таблица roles и связка user_roles. Настройки - отдельная user_settings с колонками key/value или jsonb если настроек много и они разношерстные. История действий - вообще отдельная БД, желательно Clickhouse или хотя бы отдельная схема.

Главное правило: таблица users должна быть тупой и плоской. Как только начинаешь туда пихать все подряд - получаешь монстра которого потом не мигрировать.

Аватар Елена И.

Зависит от объема. До 10 млн записей - deleted_at нормально, индекс по нему и не замечаешь. На больших объемах да, отдельная таблица deleted_users. Но для курсовой точно не нужно усложнять.

Аватар Игорь JOIN

А soft delete через deleted_at - это не антипаттерн? Читал что лучше архивную таблицу делать.

30
Эксперт • 1 ответ

Все зависит от того что за проект. В монолите на 500 юзеров и в highload-сервисе на 50 млн - архитектура кардинально разная.

Для небольшого проекта я бы не заморачивался: один users, один user_profiles (имя, аватар, телефон), один user_settings jsonb. Роли через enum если их 3-4 штуки.

Для серьезного - микросервисы, каждый сервис хранит только свой кусок данных о пользователе. Auth-сервис знает только credentials. Profile-сервис - имя и аватар. Billing - платежные данные. Ничего общего.

2
Участник • 3 ответа

А я все таки топлю за EAV (Entity-Attribute-Value) для хранения пользовательских атрибутов. Гибко, расширяемо без миграций. Коллеги смеются, но у нас в проде работает 4 года без проблем.

19
Участник • 2 ответа

Для курсовой вот стандартная схема которую преподы любят:

  • users - id, email, password_hash, role_id, created_at
  • roles - id, name, description
  • permissions - id, name
  • role_permissions - role_id, permission_id
  • user_profiles - user_id, first_name, last_name, avatar_url, phone

Вот и вся база. Нарисуй ER-диаграмму - защитишься на отлично.

15
Участник • 1 ответ

EAV это антипаттерн уровня "бог". Джойны на таком становятся абсолютно нечитаемыми, а производительность падает в пол при росте данных. Если нужна гибкость атрибутов - jsonb в Postgres решает ту же задачу без боли.

43
Эксперт • 1 ответ

Раньше делал users c 40 колонками. Адрес, телефон, дата рождения, аватар, соцсети, настройки уведомлений - все туда. Казалось удобно.

Потом понял что добавить любое новое поле это ALTER TABLE на живой базе с десятками тысяч записей. Три часа даунтайма в 2 часа ночи меня вылечили навсегда. Теперь у меня users на 6 полях и все остальное в отдельных таблицах.

0
Эксперт • 3 ответа

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

Написать ответ

Премодерация гостей

Вы отвечаете как гость. Ваш ответ будет скрыт до проверки модератором. Чтобы ответ появился сразу и вы получали репутацию — войдите в аккаунт.

Будьте вежливы и соблюдайте правила платформы.