связывание двух разных первичных ключей из одной таблицы во вторую таблицу - PullRequest
0 голосов
/ 10 февраля 2010

Я только учусь нормализации, поэтому, пожалуйста, прости меня, если это глупый вопрос.

У меня есть таблица TBL_Users с Первичным ключом ID. Чтобы отследить, с кем дружить, моей последней мыслью было составить таблицу с двумя иностранными ключами, каждый из которых является идентификатором другого человека. Однако чем больше я думаю об этом, тем больше не могу не думать, что должен быть лучший путь.

+----+------+
| ID | Name |
+----+------+
| 1  | Al   |
| 2  | Bob  |
+----+------+

Эта модель означает, что я либо должен дублировать всю информацию, либо дважды вызывать TBL_Friends.

IE, если таблица

+----+--------+
| ID | Friend |
+----+--------+
| 1  | 2      |
| 2  | 1      |
+----+--------+

Затем я продублировал информацию и должен сделать два звонка, чтобы добавить / удалить друзей.

С другой стороны, если я просто сделаю

+----+-----+
| ID | ID2 |
+----+-----+
| 1  | 2   |
| 3  | 1   |
| 4  | 1   |
+----+-----+

Ситуация кажется еще хуже, потому что мне приходится дважды запрашивать базу данных каждый раз, когда я хочу что-то сделать, будь то сбор информации или добавление / удаление друзей.

Конечно, есть простое решение, которое я пропускаю?

Ответы [ 2 ]

1 голос
/ 10 февраля 2010

Вопрос, на который вам нужно ответить, следующий: эквивалентны ли следующие два утверждения?

  1. Боб друг Ал
  2. Ал друг Боба

Это зависит от контекста. В социальных сетях Al и Bob - это просто узлы на графике, и пока существует связь между ними, которой достаточно.

Но если Ал преследует Боба, то Ал может утверждать утверждение №1 сколько угодно, Боб никогда не согласится с утверждением №2. Или рассмотрим аналогичного государственного деятеля:

  1. Боб - менеджер Al
  2. Ал - менеджер Боба

Нечасто, что оба эти утверждения могут быть верными одновременно, но существуют некоторые сложные управленческие структуры.

В обеих этих ситуациях ваша первая таблица не содержит дубликатов данных, поскольку (1,2) не совпадает с (2,1). Если вы выберете второе решение, вы должны применить правило, что если (1,2) существует, (2,1) не может существовать.

Существуют ситуации, в которых ваше первое решение является подходящим, а в некоторых - второе. Другими словами, моделирование данных сложно :)

Главное, сначала верните правильную логическую модель. Забудьте о SQL, пока не начнете писать запросы. Если ваши таблицы разработаны правильно, SQL будет течь. Или, другими словами, если вам сложно написать запрос, скорее всего, ваша модель данных неверна.

1 голос
/ 10 февраля 2010

Вам не нужно использовать два запроса, просто используйте один запрос с предложением OR.

SELECT
    (CASE WHEN
       WHEN id1 = XXX THEN id2
       ELSE id1
    END) AS friend_id
WHERE
   id1 = XXX OR id2 = XXX

Где XXX - это идентификатор пользователя, которого вы ищете. Это соответствует простому предоставленному вами случаю.

Если ваша модель становится намного более сложной, мы можем посмотреть на другие решения таблиц и / или на денормализацию как ваше первое решение.

...