Если A
друг друга B
, то я должен хранить оба значения AB
и BA
, или одного достаточно? Каковы преимущества и недостатки обоих методов.
Вот мое наблюдение:
- Если я сохраню оба, я должен обновить оба, когда получу запрос от друга.
- Если я не сохраню оба, то мне будет трудно, когда приходится делать несколько
JOIN
с этой таблицей.
В настоящее время я поддерживаю отношения в одном направлении.
Так что мне делать в этом случае? Любой совет?
mysql
что хранится в облаке Amazon.Ответы:
Я хотел бы хранить AB и BA. Дружба - это двусторонние отношения, каждая сущность связана с другой. Хотя интуитивно мы думаем о «дружбе» как об одной связи между двумя людьми, с точки зрения отношений это больше похоже на «А имеет друга Б» и «Б имеет друга А». Два отношения, две записи.
источник
Если дружба предназначена для того, чтобы быть симметричной (то есть
A
дружить с нейB
невозможно, но не наоборот), я бы просто сохранил односторонние отношения с проверочным ограничением, гарантирующим, что каждое отношение может быть представлено только одним способом.Также я отказался бы от суррогатного идентификатора и вместо этого использовал бы составной PK (и, возможно, составной уникальный индекс также на обращенных столбцах).
Вы не говорите запросы, которые это затрудняет, но вы всегда можете создать представление
источник
UNIQUE
, чтобы не создавать ненужного и избыточного дополнительного бремени дляINSERT
s? Так как у насPRIMARY KEY (a,b)
и так как PK являетсяUNIQUE
, обращеннаяKEY (b,a)
не такжеUNIQUE
независимо от того , что.Предполагая, что «дружба» всегда двусторонняя / взаимная, я бы, вероятно, справился с этим примерно так.
В результате вы измените его с соединения «многие ко многим» с «человека» на «человека» на соединение «многие ко многим» с «человека» на «дружбу». Это упростит объединения и ограничения, но побочным эффектом будет использование более двух человек в одной «дружбе» (хотя, возможно, дополнительная гибкость будет потенциальным преимуществом).
источник
Возможно, вам потребуется определить индексы для дружеских отношений, а не удваивать количество строк:
Таким образом, вы удваиваете хранилище для индексов, но не для табличных данных. В результате это должно быть 25% экономии дискового пространства. MySQL Query Optimizer выберет только выполнять сканирование диапазона индекса, поэтому концепция покрытия индексов здесь работает хорошо.
Вот несколько хороших ссылок по индексам покрытия:
ПРЕДОСТЕРЕЖЕНИЕ
Если дружба не взаимна, у вас есть основание для другого типа отношений: FOLLOWER
Если friend_to не является другом friend_of, вы можете просто оставить эти отношения вне таблицы.
Если вы хотите определить отношения для всех типов, независимо от того, являются ли они взаимными или нет, вы, вероятно, можете использовать следующую схему таблиц:
Из таблицы отношений вы можете расположить отношения так, чтобы они включали следующее:
Это должно быть более надежным для всех отношений, независимо от того, являются ли эти отношения взаимными или нет.
источник
Если вы можете контролировать в приложении, что идентификатор A всегда ниже, чем идентификатор B (предварительный порядок идентификаторов элементов A, B), вы можете использовать запрос без ИЛИ (выберите где id_A = a И id_B = b вместо запроса (id_A = a AND id_B = b) ИЛИ (id_A = b AND id_B = a)), а также ведите половину записей, которые вам понадобятся, с приближениями других. Затем вы должны использовать другое поле, чтобы поддерживать состояние отношений («друзья», «a-solicited-to-b», «b-solicited-to-a», «exfriends-a», «exfriends-b»), и все готово.
Так я управлял своей системой дружбы, и это упрощает систему и использует половину строк, которые вам понадобятся в других системах, только говоря, что A равно нижнему значению id в коде.
источник