質問
私は今、webappを作成していますが、データベース設計について頭を悩ませようとしています。
ユーザーモデル(ユーザー名(プライマリキー)、パスワード、電子メール、Webサイト)があります エントリモデル(id、title、content、comments、commentCount)があります
ユーザーがエントリにコメントできるのは1回のみです。これを行うための最良かつ最も効率的な方法は何ですか?
現時点では、ユーザー名(ユーザーモデルから)とエントリID(エントリモデルから)を持つ別のテーブルを考えています
**username id**
Sonic 4
Sonic 5
Knuckles 2
Sonic 6
Amy 15
Sonic 20
Knuckles 5
Amy 4
したがって、エントリ4のコメントをリストするには、id = 4を検索します。
補足説明: commentCountを保存する代わりに、必要なときにデータベースからコメントカウントを計算する方が良いでしょうか?
解決
あなたのデザインは基本的に健全です。 3番目のテーブルには、UserName、EntryID、Commentの各フィールドを持つ、UsersEntriesCommentsなどの名前を付ける必要があります。このテーブルでは、UserNameフィールドとEntryIDフィールドで構成される複合主キーがあります。これにより、各ユーザーが各エントリに1回だけコメントできるというルールが適用されます。テーブルには、UserNameがUsersテーブルにあり、EntryIDがEntriesテーブル(具体的にはIDフィールド)にある必要があるという外部キー制約もあります。
UsersテーブルにIDフィールドを追加することもできますが、多くのプログラマー(私自身も含めて)は" natural"の使用を推奨しています。可能な場合はキー。 UserNamesはシステム内で一意である必要があるため、これは完全に有効な(簡単に読み取り可能な)主キーです。
更新:もう一度質問を読んでください。エントリテーブルにCommentsまたはCommentsCountフィールドは必要ありません。コメントはUsersEntriesCommentsテーブルに適切に保存され、カウントはクエリで動的に計算されます(この値を自分で更新する手間が省けます)。
Update 2 :James Blackは、UserNameを主キーとして使用せず、代わりに人為的な主キー(UserIDまたはいくつかのような)。 UserNameを主キーとして使用する場合、関連するすべてのテーブルのユーザー名も変更する必要があるため、ユーザーがユーザー名を変更できるようにすることはより困難です。
他のヒント
どういう意味ですか
entry model(id, title, content, **comments**, commentCount)
(強調鉱山)?エンティティごとに複数のコメントがあるように見えるため、それらは別のテーブルに保存する必要があります。
comments(id, entry_id, content, user_id)
entry_id
および user_id
は、それぞれのテーブルへの外部キーです。 ( entry_id
、 user_id
)に一意のインデックスを作成するだけで、ユーザーがエンティティごとにコメントを1つだけ追加できるようになります。
また、ユーザー名をPKにする代わりに、ユーザーテーブルの代理(数値、シーケンス/ IDで生成された)主キーを作成することもできます。
データモデルに対する推奨事項は次のとおりです。
USERS テーブル
- USER_ID(pk、int)
- USER_NAME
- パスワード
- メール
- ウェブサイト
エントリ表
- ENTRY_ID(pk、int)
- ENTRY_TITLE
- コンテンツ
ENTRY_COMMENTS テーブル
- ENTRY_ID(pk、fk)
- USER_ID(pk、fk)
- コメント
この設定により、エントリに0以上のコメントを含めることができます。コメントが追加されると、 ENTRY_ID
と USER_ID
の複合キーである主キーは、ペアがテーブルに一度しか存在できないことを意味します(IE:1、1が ' tは1、1の再追加を許可します)。
カウントをテーブルに保存しない-VIEWを使用して、実行時に既存のデータに基づいて数値を生成できるようにします。
- ユーザー名をプライマリIDとして使用しません。自動インクリメントで数値IDを作成します
- リレーションテーブルで新しいIDを使用して、2つのフィールドに一意のキーを設定します
それは問題ではありませんが、主キーであるユーザーIDが必要な場合があります。ユーザー名。
結合されたテーブルに、ユーザーIDとエントリIDに一意の制約を設定します。このように、データベースは、コメント/エントリ/ユーザーが1つだけであることを強制します。
データベースを指定すると役立ちます。btw。
コメントのセットが username
X post_id
に関して一意であることを保証したいようです。これを行うには、一意の制約を使用するか、データベースシステムが明示的にそれをサポートしていない場合、同じ制約を使用します。以下にそれを表現するSQLを示します。
CREATE TABLE users (
username VARCHAR(10) PRIMARY KEY,
-- any other data ...
);
CREATE TABLE posts (
post_id INTEGER PRIMARY KEY,
-- any other data ...
);
CREATE TABLE comments (
username VARCHAR(10) REFERENCES users(username),
post_id INTEGER REFERENCES posts(post_id),
-- any other data ...
UNIQUE (username, post_id) -- Here's the important bit!
);