この質問は、データベースをどのように設計する必要がありますか?それは、より良いソリューションになるものに応じて、リレーショナル/ nosqlデータベースにすることができます
「会社」と「ユーザー」を追跡するデータベースを含むシステムを作成する必要があるという要件があるとします。1人のユーザーは常に1つの会社にのみ属します
- ユーザーは1つの会社にのみ所属できます
- 会社は多くのユーザーを持つことができます
「会社」テーブルの設計は非常に簡単です。会社には次の属性/列があります:(簡単にしましょう)
ID, COMPANY_NAME, CREATED_ON
最初のシナリオ
シンプルでわかりやすい、ユーザーはすべて同じ属性を持っているため、これはリレーショナルスタイルのユーザーテーブルで簡単に実行できます。
ID, COMPANY_ID, FIRST_NAME, LAST_NAME, EMAIL, CREATED_ON
2番目のシナリオ
さまざまな企業がユーザーのさまざまなプロファイル属性を保存する場合はどうなりますか。各会社には、その会社のすべてのユーザーに適用される定義済みの属性セットがあります。
例えば:
- 会社Aは、LIKE_MOVIE(ブール値)、LIKE_MUSIC(ブール値)を保管したいと考えています。
- 会社Bが保存したい:FAV_CUISINE(文字列)
- 会社Cは、OWN_DOG(ブール値)、DOG_COUNT(整数)を保存したい
アプローチ1
ブルートフォースの方法は、ユーザーに単一のスキーマを持たせ、彼らが会社に属していない場合にnullを持たせることです:
ID, COMPANY_ID, FIRST_NAME, LAST_NAME, EMAIL, LIKE_MOVIE, LIKE_MUSIC, FAV_CUISINE, OWN_DOG, DOG_COUNT, CREATED_ON
多くのNULLと、それらに関係のない列を持つユーザー行(つまり、会社Aに属するすべてのユーザーはFAV_CUISINE、OWN_DOG、DOG_COUNTのNULL値を持つ)になってしまうため、これはやや厄介です
アプローチ2
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として格納されます