Возможно, вам потребуется определить индексы для дружеских отношений, а не удваивать количество строк:
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)
);
Таким образом, вы удваиваете хранилище для индексов, но не для табличных данных. В результате это должно быть 25% экономии дискового пространства. MySQL Query Optimizer выберет только выполнять сканирование диапазона индекса, поэтому концепция покрытия индексов здесь работает хорошо.
Вот несколько хороших ссылок по индексам покрытия:
ПРЕДОСТЕРЕЖЕНИЕ
Если дружба не взаимна, у вас есть основание для другого типа отношений: FOLLOWER
Если 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');
Из таблицы отношений вы можете расположить отношения так, чтобы они включали следующее:
- Друзья должны быть взаимными
- Враги могут быть взаимными или нет
- Последователи могут быть взаимными или нет
- Другие отношения будут подлежать интерпретации (забытым или оставленным или получателем мести (фиксированный))
- Возможные отношения могут быть расширены
Это должно быть более надежным для всех отношений, независимо от того, являются ли эти отношения взаимными или нет.