Разрешить отношения многих ко многим - PullRequest
2 голосов
/ 31 января 2009

Есть ли у кого-нибудь процесс или подход, который можно использовать для определения того, как восстановить отношение «многие ко многим» в реляционной базе данных? Вот мой сценарий. У меня есть группа контактов и группа телефонных номеров. Каждый контакт может быть связан с несколькими телефонными номерами, а каждый телефонный номер может быть связан с несколькими контактами.

Простым примером такой ситуации может служить офис с двумя сотрудниками (e1 и e2), одной основной голосовой линией (v1) и одной частной голосовой линией (v2). e1 является генеральным директором, поэтому у них есть собственная частная голосовая линия v1, но с ними также можно связаться, позвонив по основной линии v2 и попросив генерального директора. e2 - просто сотрудник, и связаться с ним можно только по телефону v2.

Итак, e1 должен быть связан с v1 и v2. e2 должен быть связан с v2. И наоборот, v1 должен быть связан с e1, а v2 должен быть связан с e1 и e2.

Цель здесь состоит в том, чтобы получить возможность запускать такие запросы, как «какие цифры можно получить на e1» и «какие сотрудники можно получить на v2» и т. Д. Я знаю, что ответ будет включать промежуточную таблицу или таблицы, но я просто не могу точно сказать, какая именно архитектура.

Ответы [ 5 ]

7 голосов
/ 31 января 2009

Вам не нужны временные таблицы для запроса. Существует промежуточная таблица для сопоставления.

numbers_tbl
-----------
nid   int
number    varchar

employees_tbl
-----------
eid       int
name  varchar

employee_to_phone_tbl
-----------
eid       int
nid       int

Как мне позвонить Бобу?

select *
from employees_tbl e
inner join employee_to_phone_tbl m
  on e.eid = m.eid
inner join numbers_tbl n
  on m.nid = n.nid
where e.name = 'Bob'

Кто может забрать, если я позвоню по этому номеру?

select *
from numbers_tbl n
inner join employee_to_phone_tbl m
  on m.nid = n.nid
inner join employees_tbl e
  on e.eid = m.eid
where n.number = '555-5555'
6 голосов
/ 31 января 2009

Количество сотрудников:

eID, eName
1, e1
2, e2

номера телефонов:

pID, pNumber
1, v1
2, v2

EmployeePhones:

eID, pID
1, 1
1, 2
2, 2

тогда вы внутреннее соединение. если вам нужно узнать, какое число (я) e1 может быть достигнуто в (t-sql):

SELECT E.eName, P.pNumber 
FROM   dbo.Employees E 
INNER JOIN dbo.EmployeePhones EP ON E.eID = EP.eID 
INNER JOIN dbo.PhoneNumbers P ON EP.pID = P.eID 
WHERE E.eName = 'e1'

Я считаю, что это должно сработать (тестируем прямо сейчас ...)

РЕДАКТИРОВАТЬ: Мне потребовалось несколько минут, чтобы напечатать, извините за дублирование ...

4 голосов
/ 31 января 2009

Другие объяснили схему, но я собираюсь объяснить концепцию. То, что они создают для вас, таблица с именами EmployeePhones и employee_to_phone_tbl, называется Ассоциативная сущность , которая является типом Слабая сущность .

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

Подробнее о теории отношений см. по этой ссылке

1 голос
/ 31 января 2009
  1. Нормализация
  2. Рекомендации по ссылочной целостности
  3. Проверьте это - http://statisticsio.com/Home/tabid/36/articleType/ArticleView/articleId/327/Need-Some-More-Sample-Databases.aspx
0 голосов
/ 31 января 2009

Немного подумав, вот что я придумала. Это, вероятно, согласуется с подходом, о котором думает AviewAnew.

сотрудников
идентификатор (индекс)
имя

номер
id (индекс)
номер

отношения
employee.id (индекс)
numbers.id (индекс)


сотрудников
1: e1
2: e2

номер
1: v1
2: v2

отношения
1: 1
1: 2
2: 1

Это лучший / единственный подход?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...