ユーザーに関する可能性のあるすべてのデータ用に1つの巨大なテーブルを用意するか、その多くはすべてのユーザーに適用されるわけではありません.たとえば、以前の仕事) と、各ユーザーに関するデータを複数のテーブルに分散させることです。
最初の方法はより合理化されていますが、大量の不要なオーバーヘッドを使用するように感じます.
ユーザーに関する可能性のあるすべてのデータ用に1つの巨大なテーブルを用意するか、その多くはすべてのユーザーに適用されるわけではありません.たとえば、以前の仕事) と、各ユーザーに関するデータを複数のテーブルに分散させることです。
最初の方法はより合理化されていますが、大量の不要なオーバーヘッドを使用するように感じます.
関連するものの複数のインスタンスは、常に別のテーブルに移動します。このプロセスは正規化と呼ばれます。
一見複雑に見えるかもしれませんが、長い目で見れば生活が楽になります。MySQL のようなデータベース システムでは、必要に応じて (キー フィールドが適切にインデックス化されている場合)、テーブルを再度結合 (非正規化) するという簡単な作業が行われます。
いくつかの理由により、説明したような非正規化されたテーブルを操作するのははるかに困難です。aPerson
に複数のアドレスがあるとします。それをどのようにメインテーブルに入れますか? Address1
、Address2
、Address3
? その人が4つの異なる住所を持っている場合はどうなりますか?
このようなテーブルでの作業は、作成するすべてのクエリでテーブル内の 1 つではなく3 つの列を処理する必要があるため、はるかに困難になります。
関連する資質がユーザーのタイプに依存し、特定のタイプのすべてのユーザーがそれらの資質をすべて備えている場合、タイプごとに表を作成できます。
CREATE TABLE Type1_Qualities (id int not null auto_increment 主キー、user_id int 参照 (ユーザー)、qual1 ...、qual2 ...、...)
Type2、Type3 についても同様です。これにより、すべてのユーザーに無関係なフィールドがすべて含まれることを回避できますが、xception の回答のような一般的な属性テーブルを使用して多くの結合を行うよりも簡単です。
データの保存方法によっては、複数の関係データ構造を使用する場合がありますが、これは単なる例です。
CREATE TABLE user (
id int not null auto_increment primary key,
name varchar[60] not null
);
CREATE TABLE attributes (
id smallint not null auto_increment primary key,
name varchar[20] not null,
order smallint --optional
);
CREATE TABLE userattributes (
user int not null references user (id),
attribute smallint not null references attributes(id),
value varchar[100] not null,
order tinyint --optional
);
INSERT INTO textattributes(name) VALUES ('alias'), ('address'), ('hobby')
あなたがそれらを気にしないかもしれないので、注文フィールドをオプションとしてマークしました
SELECT a.name, ua.value
FROM userattributes AS ua
JOIN attributes AS a
ON ua.attribute = a.id
WHERE user = :user
ORDER BY a.order, ua.order
必要に応じてユーザーに参加することもできますが、そのデータは行ごとに複製されるか、ユーザーからデータを取得するために別のクエリを使用できます。個人的には、そのために 2 番目のクエリを使用します。