行数を2倍にする代わりに、友情の周りにインデックスを定義する必要がある場合があります。
CREATE TABLE person
(
person_id INT NOT NULL AUTO_INCREMENT,
...
PRIMARY KEY (person_id)
);
CREATE TABLE friendship
(
friend_of INT NOT NULL,
friend_to INT NOT NULL,
PRIMARY KEY (friend_of,friend_to),
UNIQUE KEY friend_to (friend_to,friend_of)
);
この方法では、テーブルデータではなく、インデックスのストレージを2倍にします。その結果、これによりディスクスペースが25%節約されるはずです。MySQL Query Optimizerは、インデックス範囲のスキャンのみを実行するように選択するため、ここではインデックスをカバーするという概念がうまく機能します。
カバリングインデックスに関する便利なリンクを次に示します。
警告
友情が相互関係でない場合、別のタイプの関係の基礎があります。フォロワー
friend_toがfriend_ofの友達でない場合は、その関係をテーブルから単純に除外できます。
相互に関係なく、すべてのタイプの関係を定義する場合は、おそらく次のテーブルレイアウトを使用できます。
CREATE TABLE person
(
person_id INT NOT NULL AUTO_INCREMENT,
...
PRIMARY KEY (person_id)
);
CREATE TABLE relationship
(
rel_id INT NOT NULL AUTO_INCREMENT,
person_id1 INT NOT NULL,
person_id2 INT NOT NULL,
reltype_id TINYINT,
PRIMARY KEY (rel_id),
UNIQUE KEY outer_affinity (reltype_id,person_id1,person_id2),
UNIQUE KEY inner_affinity (reltype_id,person_id2,person_id1),
KEY has_relationship_to (person1_id,reltype_id),
KEY has_relationship_by (person2_id,reltype_id)
);
CREATE TABLE relation
(
reltype_id TINYINT NOT NULL AUTO_INCREMENT,
rel_name VARCHAR(20),
PRIMARY KEY (reltype_id),
UNIQUE KEY (rel_name)
);
INSERT INTO relation (relation_name) VALUES
('friend'),('follower'),('foe'),
('forgotabout'),('forsaken'),('fixed');
関係テーブルから、以下を含むように関係を調整できます。
- 友人は相互に
- 敵は相互かそうでないか
- フォロワーは相互かそうでないか
- その他の関係は、解釈の対象となります(忘れられた、見捨てられた、または復ofの受信者(修正済み))
- 可能性のある関係をさらに拡張できます
これは、関係が相互であるかどうかに関係なく、すべての関係に対してより堅牢である必要があります。