1

Web サイトのユーザーとアカウントを処理する最善の方法を考えています。

すべてのユーザーは単一のアカウントに属し、アカウントは複数のユーザーを持つことができます。テーブルは MyISAM になるため、DB によって強制される参照整合性はありません。各ユーザーは、自分のコンテンツおよび/または所属するアカウントのすべてのユーザーのコンテンツを表示/追加/編集する権限を持っています。

CREATE TABLE account (
id INT,
name VARCHAR,
... etc
);

CREATE TABLE user (
id INT,
accountId INT, // references account.id
userName,
etc.
);

DB 内の他のほとんどすべてのテーブルは、User テーブルを参照します。例えば。

CREATE TABLE product (
id INT,
userId, // references user.id
name VARCHAR,
details TEXT
.. more stuff
);

CREATE TABLE event (
id INT,
userId INT,
name VARCHAR,
date DATETIME,
..etc
);

したがって、ユーザーがアクセスできる製品を取得するには、自分自身だけにアクセスする権限があると仮定します。

SELECT * FROM product WHERE userId = 17;

アカウント全体にアクセスできるユーザーがアクセスできる製品を取得するには:

SELECT p.* FROM product p, user u WHERE u.accountId = 3;

さて、問題は次のとおりです。製品、イベントなどにも accountId フィールドがある方がよいでしょうか?

CREATE TABLE product (
id INT,
userId, // references user.id
accountId, // references account.id
name VARCHAR,
details TEXT
.. more stuff
);

これにより、使用されるほぼすべてのクエリで余分な結合が不要になります。

SELECT p.* FROM product p.accountId = 3;

ユーザーが 1 つのアカウントから別のアカウントに移動することはないため、accountId は常に正しいものになります。サイトが使用する何百もの他のクエリからこれらの結合を削除するために、追加のデータ ストレージ要件と正規化を少し失う価値はありますか? 考慮すべきもう 1 つの点は、ユーザー テーブルはそれほど頻繁に書き込まれないため、結合の実行中にテーブルのロックに関する問題が発生する可能性は低いということです。

4

1 に答える 1

0

おそらくそうではありません。すべての行に余分なフィールドを格納するのはウエストだと思います。テーブルが適切にインデックス付けされていれば、それらを結合することはそれほど高価ではありません。

テーブルにとフィールドuserの両方を含めるには、テーブルにインデックスを追加してみてください。テーブルは MyISAM であるため、テーブル データで を検索する必要がなくなります。useridaccountidaccountid

また、クエリSELECT p.* FROM product p, user u WHERE u.accountId = 3;は OUTER 結合を実行しています。これは次のように変更する必要があります。

SELECT p.*
FROM product p JOIN user u ON p.userid = u.id
WHERE u.accountId = 3;
于 2011-01-17T04:16:42.260 に答える