50

急ごしらえの質問:

要約すると、データベース内の既存のユーザー テーブルに構造的な変更を加えることなく、無期限にバッジ ルールを作成できるようなデータベースをどのように設計すればよいか、少し混乱しています。

バッジのタイトル、基準などを保存します。そのテーブルはどのように見えるでしょうか?

  • Badge_id (1)
  • Badge_title (10K バッジ)
  • バッジ画像 (10k.jpg)
  • Badge_criteria ([投稿] >= 10000)
    ...

曲がりくねった質問:

私自身の個人的なプロジェクトにバッジ システムを実装したいと考えていますが、そのようなことを行う最善の方法について少しアドバイスを求めています。バッジ システムに関するいくつかの質問をここで読みましたが、データベース アーキテクチャがあまり注目されていません。

ユーザー ポイントに基づくバッジ (仮想の「10k バッジ」) は、非常に単純に見えます。ユーザーの評判に影響を与えるイベント (賛成票、反対票、回答の承認など) は、ユーザーの新しい評判を確認するメソッドを呼び出し、バッジを授与する可能性があります。

このシステムはかなり単純明快に聞こえますが、管理者が将来簡単に無数のバッジを作成したいと考えている場合、データベースとしてどのように見えるでしょうか。評判。

ユーザーの評判は、ユーザー レコード自体の値である可能性があります。しかし理想的には、新しいバッジを作成するときにユーザー テーブルに新しいフィールドを追加する必要はありませんか? たとえば、「Edited 100 Entries」バッジの場合、Users テーブル内に新しい列「entries_edited」を作成することはありませんよね? そして、エントリが編集されるたびにそれを増やします...

ヒントはありますか?

Stackoverflow アーカイブ:


注: バッジをユーザーに関連付ける方法を尋ねているわけではありません。バッジを授与する方法を尋ねているわけではありません (これはプログラムによって行われます)。

4

7 に答える 7

23

バッジの基準が任意に複雑になる可能性があることを考えると、「単純な」データ要素に分割されたデータベース テーブルにバッジを格納することはできないと思います。任意に複雑な基準を処理できる「ルール エンジン」を作成しようとすると、プログラミング言語で使用しているすべてのツールを基本的に書き直すという道をたどることになります。

バッジを特定のフィールドのみに制限することが事前にわかっている場合 (つまり、バッジは評判や編集数などにのみ基づいています)、次のような単純なテーブルにそれらを保存できます。

ReputationBadgeCriteria
  BadgeId
  BadgeName
  MinReputation

あるいは、ある種の DSL を使用して「ルール」を作成することもできますが、最終的には、ルールを読み取るときにルールを解析するためのパーサーと、これらのルールを実行するための何かを作成する必要があります。DSL に必要な複雑さによっては、これは簡単な作業ではない場合があります。これは、「[評判] > 1000」または「[投稿] > 5」のようなものを含む基準列 (おそらくプレーンテキスト) を使用して、質問で行っているパスのように見えます。これらのルールを解析して実行する必要があり、そのための記述の複雑さは、それらのルールをどの程度複雑にするかによって異なります。

このアプローチが痛みにつながる理由については、デイリー WTFの記事を読むことをお勧めします

于 2009-06-26T14:17:47.797 に答える
22

どこまでやりたいかによって、スキーマはかなり複雑になる可能性があります。追跡する必要がある基本要素は次のとおりです。

Badges awarded
Points earned

ここまでは非常に単純ですが、新しいバッジと新しいポイント カテゴリを動的に作成できるようにしたいと考えています。バッジ賞は、1 つまたは複数のポイント カテゴリで獲得したポイントが一定の金額になるかどうかによって決まります。したがって、ポイント カテゴリ (および獲得したポイント) とバッジの関係を追跡する必要があります。

Point categories
Badge categories

したがって、重要なのはユーザー ポイント テーブルで、ポイント カテゴリにリンクし、バッジにリンクします。ユーザーは特定のカテゴリでポイントを獲得します。これは、1 つまたは複数のバッジに対するポイントの獲得に貢献します。

badges:
badge_id
badge_name
required_points
....

point_categories:
point_id
category_name
weighting (optional)
...

point_groups:
badge_id
point_id
weighting (optional)
...

user_points:
user_id
point_id
points
...

user_badges:
user_id
badge_id
points_earned
badge_awarded (yes/no)
...

「管理者」インターフェイスを使用すると、誰かが新しいバッジを作成し、そのバッジ (point_groups) を獲得するために必要なポイント カテゴリを選択できます。ユーザーがポイント (user_points) を獲得するたびに、user_points テーブルを更新し、それらのポイントが貢献できるバッジ (point_groups) を決定します。次に、獲得したポイントの影響を受けたバッジのポイントを再コンパイルし、point_earned で user_badges テーブルを更新します。次に、user_badges の points_earned フィールドを、badges テーブルの required_points と照合します。

さまざまなポイント カテゴリにさまざまな重みを割り当てたり、特定のバッジのポイント カテゴリにさまざまな重みを割り当てたりすることで、より洗練されたものにすることができます。しかし、このセットアップでは、テーブル構造を変更することなく、非常に簡単にバッジとポイント カテゴリを無制限に作成および管理できます。

それがあなたが探しているものではない場合は、多くのタイピングに対して少なくとも1つか2つの投票を得る必要があると思います.

于 2009-06-26T15:12:29.683 に答える
5

あるテーブルでユニークユーザーを追跡し、別のテーブルでユニークバッジを追跡してから、それらを関連付ける相互参照テーブルを作成します。

ユーザーは多くのバッジを持つことができ、バッジは多くのユーザーを持つことができます。

create table users (
id int,
name varchar
)

create table badges (
id int,
badge_name varchar
)


create table user_badges_xref (
user_id int,
badge_id int
)

ユーザーがバッジを獲得するかどうかに影響を与える可能性のある統計は、サイトの管理の一部として追跡されます。したがって、受け入れられる回答のようなものは、質問と回答を関連付けるスキーマに含まれます。回答と回答の所有者を表示するために、変更が行われるたびにバッジの状態をチェックするユーザーテーブルとトリガーとの関係があります。

バッジを授与する方法を尋ねているのではありません。データベース内に基準を保存する方法を尋ねています。

では、どこかのフィールドでバッジを獲得したかどうかを判断するために必要な論理演算を保存したいですか?

基準はビジネスロジックの一部であるべきだという他のポスターに同意すると思います。そのロジックは、アプリ側またはトリガー内にあります。それはスタイルの問題だと思います。

条件をフィールドに格納するというアイデアに本当に結婚している場合は、パラメータ化されたSQLとして格納し、動的に実行します。

したがって、この種のものはあなたの基準フィールドにあります:

select "Badge Earned"
from all_posts 
where user_id = @user_id
having count(*) > 10000
于 2009-06-26T13:49:47.667 に答える
5

私は次のようにアプローチしています。すべてのバッジを格納するテーブルを作成し、バッジが授与されるかどうかを確認するために実行される関数を1つの列で参照します。そうすれば、テーブルはシンプルなままで、バッジを決定するロジックをコードに保持でき、最適な場所に配置できます。

この方法では、バッジ要件を相互にリンクして、より複雑な依存関係を形成することもできます。たとえば、ユーザーがこのバッジを取得するには、特定の期間内に3つの個別の特定のバッジを受け取る必要があります。

于 2011-08-02T21:29:51.043 に答える
3

編集バッジの増分は作成しません。バックグラウンドでジョブを実行し、編集のバッジをまだ持っていないメンバーのために編集された投稿の数をcount()する必要があると思います。カウントが目的の範囲を超えていることがわかったら、データベースに、ユーザーがバッジを持っていることを示すエントリを追加します。

他のバッジもほぼ同じだと思います。書き込みの数を制限し、バッジ情報の数をユーザーテーブルに直接書き込まないようにしてください。バッジ情報を含むテーブルを使用し、それをユーザーテーブルにリンクします。

于 2009-06-26T13:50:56.337 に答える
3

簡潔に申し訳ありません。

このようなシステムを実装するために、特定のユーザーがバッジを取得したかどうかを判断するために使用されるストアドプロシージャ名または実際のクエリのいずれかを格納するテーブルを作成する場合があります。

badge_criteria
badge_key int
badge_criteria varchar(max)

ユーザーが中間層から獲得していないバッジのクエリを抽出して実行できますが、今後新しいバッジを追加するためにコードや構造を変更する必要はありません。

于 2009-06-26T14:47:01.263 に答える
2

これは、データベースではほぼ不可能になります。バッジの付与は、アプリケーション内のビジネスロジックで行う必要があります。そうすれば、必要な既存のデータ(編集、訪問、レピュテーションなど)がすべて揃っており、適切と思われる方法で処理できます。

アップデート:

基準によって、バッジが授与されるかどうか、および授与される方法を決定するルールを意味する場合、それはデータベースに保存されるべきものではありません。これをテストして維持することはほとんど不可能です。

たとえば、「編集数」を保存する場合、必要に応じてそのデータを含めるようにテーブルまたはストアドプロシージャを変更する方法はありません。

于 2009-06-26T13:52:03.417 に答える