Вопрос заключается в том, как мне проектировать базу данных, это могут быть реляционные базы данных / nosql, в зависимости от того, что будет лучшим решением.
Учитывая требование, где вам нужно будет создать систему, которая будет включать базу данных для отслеживания «Компания» и «Пользователь». Один пользователь всегда принадлежит только одной компании
- Пользователь может принадлежать только одной компании
- Компания может иметь много пользователей
Дизайн стола «Фирменный» довольно прост. Компания будет иметь следующие атрибуты / столбцы: (давайте будем проще)
ID, COMPANY_NAME, CREATED_ON
Первый сценарий
Все просто и понятно, у всех пользователей одинаковый атрибут, так что это легко сделать в реляционном стиле, таблица пользователей:
ID, COMPANY_ID, FIRST_NAME, LAST_NAME, EMAIL, CREATED_ON
Второй сценарий
Что произойдет, если разные компании захотят сохранить разные атрибуты профиля для своего пользователя. Каждая компания будет иметь определенный набор атрибутов, которые будут применяться ко всем пользователям этой компании.
Например:
- Компания A хочет сохранить: LIKE_MOVIE (логическое значение), LIKE_MUSIC (логическое значение)
- Компания B хочет хранить: FAV_CUISINE (String)
- Компания C хочет сохранить: OWN_DOG (логическое), DOG_COUNT (int)
Подход 1
Грубый способ состоит в том, чтобы иметь единую схему для пользователя и позволить ему иметь нулевые значения, когда они не принадлежат компании:
ID, COMPANY_ID, FIRST_NAME, LAST_NAME, EMAIL, LIKE_MOVIE, LIKE_MUSIC, FAV_CUISINE, OWN_DOG, DOG_COUNT, CREATED_ON
Что довольно неприятно, потому что у вас будет множество NULLS и пользовательских строк, у которых есть столбцы, которые для них не имеют значения (т. Е. Все пользователи, принадлежащие компании A, имеют значения NULL для FAV_CUISINE, OWN_DOG, DOG_COUNT)
Подход 2
Второй подход заключается в том, чтобы иметь «поле свободной формы»:
ID, COMPANY_ID, FIRST_NAME, LAST_NAME, EMAIL, CUSTOM_1, CUSTOM_2, CUSTOM_3, CREATED_ON
Это было бы неприятно само по себе, поскольку вы не представляете, что такое настраиваемые поля, тип данных не будет отражать сохраненные значения (например, мы будем хранить значение int как VARCHAR).
Подход 3
Я посмотрел в поле PostgreSQL JSON, в этом случае у вас будет:
ID, COMPANY_ID, FIRST_NAME, LAST_NAME, EMAIL, CUSTOM_PROFILE_JSON, CREATED_ON
В таком случае, как вы сможете применять различные схемы для пользователя? У пользователя с компанией A будет схема, которая выглядит как
{"LIKE_MOVIE":"boolean", "LIKE_MUSIC": "boolean"}
Хотя пользователь с компанией C будет иметь другую схему:
{"OWN_DOG ":"boolean", "DOG_COUNT": "int"}
Как мне решить эту проблему? Как правильно спроектировать базу данных, чтобы использовать эту гибкую схему для одного «объекта» (пользователя) на основе их отношения (компании)?
реляционное решение? Nosql решение?
Изменить: я также думал о таблице "CUSTOM_PROFILE", которая будет по существу хранить пользовательские атрибуты в строках, а не столбцах.
Есть 2 проблемы с этим подходом:
1) Данные растут в расчете на пользователя в виде строк, а не столбцов - и это означает, что для получения полной картины пользователя необходимо выполнить много соединений, несколько соединений с таблицей «пользовательский профиль» с различными пользовательскими атрибутами
2) Значение данных всегда сохраняется как VARCHAR, чтобы быть универсальным, даже если мы знаем, что данные должны быть целыми или логическими и т. Д.