web-dev-qa-db-ja.com

MySQLデータベースを使用したユーザープライバシー設定の実装

私は実際にソーシャルWebサイトで作業しています。大きくはない、非常に少数の人々のグループを対象とした。また、MySQLドリブンデータベースでユーザーのプライバシー設定を最適に実装する方法に興味があります。たとえば、Facebook、Google +、そしておそらく他のソーシャルWebサイトなどのWebサイトでは、プライバシー設定があり、ユーザーはオブジェクト(共有するコンテンツなど)に設定できます。

私の問題は、使用している言語でコードを作成することではありませんが、実際には、ユーザーの設定を管理できるようにするDBスキーマを構成することです。私はこのようなことをしたことがなく、どんな助けにも感謝します。また、ある程度スケーラブルでなければなりません。どうもありがとう。

これは私がいくつかのWebサイトから見つけたJSON出力であり、各部分のように見えます:allowdenydescriptionfriends、およびvalueはすべて列です。ただし、MySQLでは、コンマで区切られた大量の値を実際に格納することはできません。単一の列に格納するスペースはありません。

{
  "privacy": {
    "allow": "",
    "deny": "299716926803603",
    "description": "Contacts; Except: Restricted",
    "friends": "ALL_Contacts",
    "value": "CUSTOM"
  },
  "created_time": "2015-09-04T13:01:40+0000",
  "id": "100002958951118_777860722322552"
}

私はこのようなことをしましたが、それは単に機能しません。

enter image description here

プライバシーテーブル:

allow       string
deny        string
description string
friends     string
id          int
object_id   int
owner_id    int
value       string

このプライバシーテーブルのサンプルについては不明です。

適切な解決策があり、それが当てはまることを願っています。このコミュニティのほとんどのユーザーは、この投稿から利益を得るでしょう。

4
John Smith

どの程度の正規化を希望するか、どの程度の非正規化を実現する準備ができているか、現在持っているユースケース、そして今後サポートすることが合理的に期待できる機能に応じて、さまざまなオプションが利用できます。

最も簡単な実装は、JSONをblobとして扱い、それに応じてVARCHAR列に格納することです。アプリケーションは、JSONの作成と解析を行います。 MySQLは栄光のあるKey-Valueストアとして機能します。これは簡単に実装できます。うまくスケーリングする可能性があります。使用の柔軟性がなくなり、組み込みのデータ整合性がなくなり、アドホッククエリはひどいものになります。

次に、 タイプJSON の列を使用します。 DBMSはJSONのコンテンツを洞察し、インデックス、よりコンパクトなストレージ、検証などで最適化できます。ただし、リレーショナルデータベースは最適化されていないため、最善の策とは言えません。

完全を期すためにこれら2つを含めます。どちらもMySQLのリレーショナル性質を使用していません。この方法をとるなら、利用可能な多くの優れたオープンソースNoSQLソリューションの1つを採用する方がよいでしょう。

選択した製品の関係の性質を使用するには、データを正規化する必要があります。与えられた例とビジネスルールはまばらなので、ある程度推測して推定しますが、私のモデルは本質的な側面をカバーすると思います。

明らかに、「User」と呼ばれるエンティティタイプがあり、いくつかの大きな整数タイプが主キーになります。これをUserIDと呼びます。

可視性を制御したいすべての異なるものは、おそらく独自の表現を持っています。スーパータイプ/サブタイプ パターン を使用することをお勧めします。他の利点の中で、これは他の懸念からセキュリティを抽象化し、このモデルを変更せずに新しいタイプの相互作用の追加を可能にします。これらすべての種類のルートタイプをPostingと呼び、代理キーPostingIDを割り当てます。

サンプル画像には5つの可視性カテゴリがあり、そのうちの1つはカスタムです。このリストをカバーするエンティティタイプをお勧めします。それを可視性と呼びましょう。友情の変化をシステムがどのように反映するかという問題があります。投稿が友達にのみ表示され、新しい友情が作成された場合、その新しい友達は古い投稿を見る必要がありますか、それとも投稿時に友達であった人だけに表示されたままにする必要がありますか?同様に、友だちでない場合、悪意のあるユーザーはアイテムを見る権利を失いますか?動的オプションが優先されると想定しています。

特定の投稿に対する権利を保持するために、これら3つの交差点を形成するのは魅力的です。ただし、これは非常に急速に大きくなり、友情の変化を反映した書き込みアクティビティがかなり発生します。

VisibilityをPosting(外部キー列)の属性として保持し、各ユーザーの対応するUserFriendリストを保持することをお勧めします。特定のルールによっては、「友達」リストと「知人以外の友達」リストをフラグと組み合わせて、後者を区別できる場合があります。私は友情が相互として定義されていると想定しています。したがって、AがBの友だちである場合、Bは定義によりAの友だちです。これにより、UserFriendの行数が2倍になりますが、セマンティクスは単純になります。

Visibilityの値が「Custom」の場合、別のエンティティタイプが必要になります。これにより、そのPostingIDの特定のUserID値がリストされます。

これから、テーブルは

User
  UserID

UserFriend
  UserID    -- FK to UserID; the owner of this list
  FriendID  -- FK to UserID; the friend's UserID

Visibility
  VisibilityID

Posting
  PostingID
  PostedBy      -- FK to UserID
  VisibilityID

PostingUser
  PostingID
  VisibleTo    -- FK to UserID; the friend who can see this posting

ユーザーの友達の最近の活動のリストを作成するには、特定のユーザーのUserFriend行を読み取り、投稿の公開が「public」、「friends」、または「custom」である友達のUserIDでPostingに参加します。カスタムリストを持っている人は、PostingIDと指定されたUserIDでそれに参加します。

「拒否」の意味が「これ以外のすべての友達」であると想定すると、許可と拒否を区別するフラグをPostingUserに追加してこれを実装します。

上記を非正規化することで、オプションのスペクトルに沿って一歩戻ることができます。たとえば、UserFriendがFriendにある可能性があるため、PostingUserをPostingのコンマリストとして格納できます。これにより、IO、およびおそらく経過時間が短縮されます。トレードオフは、DBMSではなくアプリケーションでより多くの作業を実行する必要があることです。

Facebookは有名にMySQLを使用していますが、上記は確実にではなくどのように使用するかです。彼らは間違いなく、何年にもわたってカスタムコーディング、キャッシング、シャーディング、およびその他のトリックを導入して、これを大規模に機能させてきました。

最後のポイントとして、これらの種類の問題を解決することがまさにグラフデータベースの目的です。 MySQLを使用してこれをNeo4Jなどに実装します。

4
Michael Green

あなたの質問はあまり詳細ではありませんが、とにかくあなたが望むものを実装する方法は次のとおりです:

プライバシー設定スキーマをモデル化する最も簡単な方法は、visibilityフィールドをユーザープロファイルの各関連プロパティに追加することです。

User
------------------
id (int, PK)
username (varchar, IDX unique)
fullname (varchar)
fullname_vis (int)
email (varchar)
email_vis (int)
dob (date)
dob_vis (int)
nationality (varchar)
nationality_vis (int)

*_visフィールドにマップされたint値は、さまざまなグループに関するフィールドの可視性を設定します。例:

  • 0 =非公開(所有者のみが表示できます)
  • 1 =友達
  • 2 =友達の友達
  • 3 =パブリック(他のすべてのログインユーザーが見ることができます)
  • 4 =完全に公開(サイトにログインしていない訪問者、検索エンジンなど、誰でも見ることができます)

明らかに、最初に、さまざまなプライバシー設定を適用するグループを定義する必要があります。

次に、これらの各フィールドを設定して(Customボタン)、これらのプライバシー設定を細かく設定するか、すべてのフィールドを特定の値(Public =およびFriendsボタン)。

2
dr_

最初に、JSONをモデル化する方法について述べた質問に答えます。

ユーザーテーブル

  • UserId-私の推測では、現在のユーザーのUserIdはjsonの「id」の半分であり、もう1つの番号は組織IDです
  • その他のユーザーの詳細

プライバシー設定

  • UserId-コンテンツ所有者へのFK
  • 説明-プライバシー設定のわかりやすい説明と見なされます
  • 友達-これの意味がわからない...
  • 価値-コンテキストがなければ意味がない
  • CreatedTime-タイムスタンプ
  • Id-この設定を一意に識別するためのPK、これはおそらくJSONの「ID」ではありません

プライバシーの可視性

  • UserId-ユーザーを設定に関連付けるユーザーテーブルへのFK
  • PrivacySettingId-プライバシー設定テーブルへのFK
  • IsVisible-許可/拒否のブールフラグ

このデータをデータベースから取得する必要がある場合は、次のいずれかを実行します。

  1. 許可/拒否ユーザーリストなしですべてのプライバシー設定データを取得するselectステートメントを記述します。プライバシーの可視性の設定をPrivacySettingIdとともに取得する2番目のselectステートメントを記述して、可視性の設定をプライバシーの設定と一致させることができます。両方の選択ステートメントを同じストアドプロシージャに配置します。ストアドプロシージャの結果セットを、サンプルjsonにシリアル化されるアプリケーションレイヤーオブジェクトにマップします。 おそらくより良い
  2. すべてのプライバシー設定データを取得し、許可/拒否されたUserIdをコンマ区切りの文字列に連結する1つのselectステートメントを記述します。 selectステートメントを同じストアドプロシージャに入れます。ストアドプロシージャの結果セットを、サンプルjsonにシリアル化されるアプリケーションレイヤーオブジェクトにマップします。 おそらくもっと悪い

これは、与えられたjsonをデータベーススキーマに変換する実行可能な方法を提供するため、技術的に賞金の対象となります。残念ながら、それが本当に解決することは、とりわけ次の理由で問題の解決に役立つとは思えません。

  • 要求されたjsonを出力できても、プライバシー設定のビジネスロジックを適用する方法は明確ではありません。
  • ニーズに最適なソリューションに到達するのに役立つ十分なコンテキスト/情報を提供していません。
  • このソリューションは、ほとんどの場合理想的ではないテキスト文字列に基づいてフィルタリング/結合することをお勧めします

プライバシー設定をサポートするデータベーススキーマは、アプリケーションのニーズによって異なります。アプリケーションのプライバシーのニーズを説明していないため、最適なソリューションを提供することはほぼ不可能です。さらに、あなたが提供したjsonサンプルは、設定を適用せずに設定を更新するために使用することを意図しています。設定の更新に必要な情報は設定の適用に関連していますが、それらは十分に異なるため、重要なビジネスロジックが欠落しています。たとえば、表面上では、jsonに許可リストと拒否リストが表示されるのはばかげているように見えます。おそらく、許可されていないすべての人を拒否する必要があります...それらが両方とも存在するという事実は、おそらく、一部のグループメンバーに対してリソースへのグループアクセスを許可し、特定の個人へのアクセスの許可をサポートするためのシステム要件のアーティファクトです。これは、企業の設定でのGoogleドキュメントのニーズに一致しますが、必要としない場合もあります。

2
Erik