1

アプリケーションの 2 人のユーザー間の関係を作成するために、MySQL 用のデータベースを設計しています。この関係の詳細を格納する最善の方法がわかりませんが、現在、RELATIONS というリンク テーブルで関係ごとに 1 つのレコードを使用するつもりです。各ユーザーには、名前や職業などの基本的なデータが USERS テーブルに格納されており、FK によってリンクされたより具体的な個人データが他のテーブルに格納されています。これらは OTHER1、OTHER2、および OTHER3 と呼ばれ、すべて他のデータが含まれます。共有するには、[データ] というフィールドにそれぞれ入力し、ID と USER_ID で識別します。

難点は、このアプリケーションでは、ユーザーが各ユーザーに表示する基本データと詳細データを指定できることです。また、その逆も可能です。RELATIONS リンク テーブルには、2 人のユーザーが関係を設定するための USERS への FK が必要ですが、各ユーザーが共有できるデータを指定する最善の方法がわかりません。オプションで保存されますが、表示する権限を持たないユーザーからすべてを非表示にする必要がある可能性があります。ただし、2 番目のユーザーはそこにデータがあるかどうかを確認できる必要があるため、データを表示する許可を要求できます。

この時点での RELATIONS のモデルは次のようになります。

関係

ID
USER_ID1
USER_ID2
USER1OTHER1_ID [(Value), Unshared, Null]
...
USER1OTHER100_ID [(Value), Unshared, Null]
USER2OTHER1_ID [(Value), Unshared, Null]
...
USER2OTHER100_ID [(Value), Unshared, Null]

したがって、USER1OTHER1_ID には、User1 が User2 と共有している場合は OTHER1 への FK が含まれ、存在するが共有されていない場合は "Unshared" になり、User1 が OTHER1 にデータを持っていない場合は Null になります。User1 と共有するための USER2OTHER1 についても同じです。しかし、巨大なフィールド配列を持つのは好きではありません。また、User1 が後で OTHER1 にデータを追加することを決定した場合に、すべての関係を更新しなければならない方法も好きではありません。これを表現するためのより単純で正規化された方法はありますか?

4

4 に答える 4

3

正規化されたアプローチは、userA が userB のデータを表示する権限を持っているかどうかのみを保存し、関係テーブルに FK 参照を追加しないことであると思います。これは、userB のデータへの参照が既に別の場所にあるためです。Relations テーブルに追加の参照を保存することにより、データが複製され、質問で説明したように同期を維持する必要があります。これはおそらく継続的なメンテナンスの手間であり、コードをリファクタリングするたびに留意する必要があるもう 1 つのことです。 .

関係テーブルにアクセス許可のみを保存する (fks なし) 場合は、テーブル (ユーザー?) に参加して、ユーザーの共有データを取得するか、アクセス許可に応じて存在するかどうかを確認します。

リレーション テーブルに過剰な数の列がある限り、テーブルをクエリするときに実際の低下を確認するのに十分ではないと思います (これについては修正してください)。データベースコードとアプリケーションコードを明確にするために、Clob などでそれらを組み合わせるなどのショートカットを見つけようとするよりも、各アクセス許可の列を作成する方がよいと思います。

于 2012-07-07T18:47:11.180 に答える
0

私が容易に想像できる最も簡潔な方法は、1つのINTを関係とともに格納することです。これは、アクセス許可のビット単位の表現です。コード内のそのINTの解釈で。INTには、一意のアクセス許可を持つビットと同じ数のビットが必要であり、それぞれに定数を定義します。どの言語で実装しているのかわかりませんが、この猫の皮を剥ぐ方法はいくつかあります...

したがって、一部の擬似コードは次のようになります。

define RELATION_PERMISSION_SEE_MY_PHOTOS = 1;
define RELATION_PERMISSION_SEE_MY_FRIENDS = 1<<1;
define RELATION_PERMISSION_SEE_MY_EMAIL = 1<<2;

次に、サポート情報の配列(ローカライズされた文字列など)を作成してインターフェイスを構築し、次のようにして変更します。

int new_permission = 0
foreach(user-selected-permissions as selected_permission) {
  new_permission |= selected_permission
}
my_relation_model.permissions_flags = new_permission
于 2012-07-07T18:38:19.943 に答える
0

.. データベースに保存される事実上すべてのデータがオプションで保存されるため ...

これを考慮すると、すべてのユーザー属性に対して6NFをお勧めします。

  • テーブルはUserアンカーとして機能し、理想的には のみを保持しますUserID

  • UserID各ユーザー属性には、属性値 ( 6NF )のみを含む独自のテーブルがあります。行は、属性が指定されている場合にのみ存在します (すべての属性値は NOT NULL)。

  • 各属性には、 のみの共有テーブルもありますOwnerID, VisitorID。行は、所有者が属性を訪問者と共有している場合にのみ存在します。


ここに画像の説明を入力


  • このモデルでは、ユーザーは存在する属性のみを共有できます。指定されていない属性の共有を許可する場合はOwnerID、 もテーブルにポイントしUserます。

簡単にするために、ユーザー データのビューを作成できます (作成する必要があります)。

于 2012-07-07T22:00:28.087 に答える
0

1 つの方法は、基本的にキーと値のペアを使用することです。

これに似ています:

user_1_id
user_2_id
field
privilege
于 2012-07-07T18:45:22.560 に答える