Facebookの友達リストに似ています。各ユーザーは、ユーザーのプロフィールを表示して、部族に追加することができます。各ユーザーは、1 つの部族のみの首長です。
さて、あなたはUser
テーブルを持っています、そしてまたテーブルが必要になりTribe
ます.
次に、あなたが説明している関係は ですchief-of
、これは1対1です(1人のユーザーが1つの部族の首長になることができます; 1つの部族には1人の首長しかいません)、したがって、これをUser
(chief_of: Tribe) またはTribe
(チーフ: ユーザー)。
CREATE TABLE User ...
chief_of integer
ここでchief_of
は、トライブを削除すると、関連するタプルがchief_of
NULL に設定されるように、外部キーである可能性があります (ユーザーは、存在しないトライブのチーフになることはできません)。
1 人のユーザーが複数の部族に属することができ、1 つの部族には複数のメンバーが存在するため、メンバーシップはもう少し複雑です。
これは多対多の関係であり、通常はキー ペアを保持するテーブルで行われます。
CREATE TABLE member_of (
user_id integer,
tribe_id integer
);
両方のフィールドは、外部キーの自然な候補です。ここでAuthors
は、 と を使用した同様の実装を見つけることができますBooks
。
Bob が Cave Bear のクランのメンバーであることを示すには、Bob と Bears の ID を取得し、タプルを に挿入しmember_of
ます。
一族のすべてのメンバーを取得するには、JOIN を使用できます。
SELECT Users.* FROM Users
JOIN member_of ON (Users.user_id = member_of.user_id)
WHERE member_of.tribe_id =
(SELECT tribe_id FROM Tribes WHERE tribe_name = 'Clan of the Cave Bear');
MySQL の ON の短いバージョンはUSING(user_id)
(両方のテーブルに同じ名前の同じ列があることを意味します) だと思いますが、私の意見では、のON
方が明確です。
仮想の「is_chief」列を取得することもできます。
SELECT Users.*, chief_of = tribe_id AS is_chief FROM Users
JOIN member_of ON (Users.user_id = member_of.user_id)
WHERE member_of.tribe_id =
(SELECT tribe_id FROM Tribes WHERE tribe_name = 'Clan of the Cave Bear');
chief_of
属性が部族 ID と等しい1 人のユーザーis_chief
は、1 に等しい TRUE に設定されているため、
SELECT Users.*, chief_of = tribe_id AS is_chief FROM Users
JOIN member_of ON (Users.user_id = member_of.user_id)
WHERE member_of.tribe_id =
(SELECT tribe_id FROM Tribes WHERE tribe_name = 'Clan of the Cave Bear')
ORDER BY (chief_of = tribe_id) DESC, user_name;
は、ユーザーをアルファベット順に取得します。ただし、チーフが存在する場合は最初になります。
トライブへの受け入れに関しては、これは 3 つの状態を識別します: ユーザーがトライブに参加していない、ユーザーがトライブに参加している、ユーザーがトライブに参加することを要求された。最初の 2 つは、実際には同じ属性の 2 つの面ですmember_of
。したがって、当然、新しい属性を作成して、それを と呼びますwants_in
。と同じテーブルにマップされmember_of
ます。
チーフは、自分のタプルと等しいすべてのタプルwants_in
を取得できます(したがって、それが NULL の場合、つまり彼がチーフではないことを意味する場合、これは自動的に何も返しません)。次に、これをユーザー名を含むチェックボックスの表として見ることができます。彼が結合を承認すると、承認ごとに からタプルを削除してに入れます。tribe_id
chief_of
wants_in
member_of
または、「メンバーシップ」自体が状態であると判断して、より複雑な結合テーブルを作成することもできます。
user_id,
tribe_id,
status
status
たとえば、
- なし ((U, T, ?) タプルがない): ユーザー U と部族 T はお互いに不明です
- 100: ユーザー U は部族 T の正会員です
- -1: 部族 T は、U がメンバーではなく、メンバーになることを要求することさえできないと判断しました。
- 0: ユーザー U は T のメンバーになりたい
- 1-99:ユーザーUは見習い(見習い)会員。