Как правильно хранить такие данные?

Необходимо хранить сущность user с N полями, где N неизвестное заранее число, 1<=N<=2000. Многие поля будут повторяться (ФИО, email, тел. номер), но их наличие не гарантировано. Есть необходимость в любое время получить все существующие в типы полей в user.
Верхний потолок планируемого масштабирования - несколько миллионов записей.
Требуется высокая гибкость выборок.
Встал вопрос в выборе БД:

Реляционная база, PostgreSQL. Варианты хранения:

1. таблица user: (id + поле JSON) + отдельная таблица для хранения списка полей. Работать это дело, как я понимаю, будет очень-очень медленно.
2. таблица user: (id) + таблица field(primary key, name, value, user_id), обернутое внешними ключами сверху. Проблемы: избыточность данных -- если у миллиона юзеров есть ФИО, в таблице field будет миллион полей вида:
[ 999 | ФИО | Иван Иванович | 555 ], ... , [ 9999 | ФИО | Петр Петрович | 666 ], ... .
3. таблица user: (id) + таблица field (id, name) + таблица field_value (user_id, field_id, value). Плюсы: минимальная избыточность данных, очень просто получить список всех полей. Минусы: количество строк в таблице field_value будет стремиться к count(user) * count(field), что при миллионе user и тысяче field будет равняться миллиарду. Это ведь слишком много?

Документоориентированная БД (mongo)
Плюсы: Модель хранения идеально подходит под наши данные.
Минусы: в целом начитался большое количество страшилок про монгу, отношение слегка предвзятое; отсутствие опыта; опасение в будущем столкнуться со слишком несвязанными данными. (Хотелось бы иметь возможность безболезненно связывать данные с другими сущностями (товары/теги/etc)

Собственно, есть понимание, что ошибка сейчас может очень дорого обойтись в последствии, так что прошу совета. Стоит ли воспользоваться одним из перечисленных или незамеченных способов с sql-базой, или же стоит приступить к изучению Mongo?
  • Вопрос задан
  • 1888 просмотров
Решения вопроса 4
@vanyamba-electronics
ID (UNSIGNED INTEGER) AUTOINCREMENT, PRIMARY KEY
USER_ID (UNSIGNED INTEGER)
RECORD_ID (UNSIGNED INTEGER)
FIELD_ID (UNSIGNED INTEGER)
FIELD_VALUE (VARCHAR)
Ответ написан
Комментировать
@moem
Приглядитесь к структуре EAV. А база может быть любой
Ответ написан
Комментировать
2ord
@2ord
Подойдет что-нибудь из категории Wide-column store. Можно попробовать MariaDB ColumnStore.
Ответ написан
@v_m_smith
лучше бы я пил и курил
Если нужна одна таблица без джоинов, несколько миллионов записей, то храните просто таблицей в column oriented СУБД Clickhouse. 2000 столбцов там норма.
Задуматься о производительность придётся после миллиардов записей
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы