2010-09-15 2 views
2

У меня есть n количество таблиц, которые связаны между собой по принципу «многие-ко-многим». Я хочу знать, как представить такую ​​модель, не создавая промежуточную таблицу для каждой связи, поскольку это приведет к некоторому большому количеству таблиц. Для этого предположим, что n достаточно велик, чтобы не создавать таблицы.Дизайн базы данных: рекурсивный Многие из многих отношений

Например, я, возможно, есть три таблицы, где п 3:

Parking_Lot 
Car 
Person 

Автомобиль можно припарковать во многих автостоянках и стоянка будет иметь много автомобилей. Человек может водить много автомобилей, и автомобиль может иметь много водителей. На стоянке есть много людей, и многие люди могут находиться на стоянке. (люди могут быть сотрудниками, или они могут просто физически находиться на стоянке. Пожалуйста, не анализируйте этот пример, так как это только пример.)

Для моделирования этого варианта у вас будет 3 таблицы (Lot, Car, Person) и три таблицы отношений.

Скажите, что вы добавили четвертый стол питания. Еда может быть съедена на многих автостоянках, на многих автомобилях и многих людей. Это занимает 4 таблицы + 6 = 10 таблиц.

Как вы моделируете такие отношения, не создавая большое количество промежуточных таблиц?

Меня больше интересует концепция, но я в основном использую C#, поэтому, если есть возможность сделать это в .net, я все уши.

ответ

0

вы можете создать таблицу отношений с именем типа/таблицы в ней.

relationship 
     relationship_type_parent 
     relationship_id_parent 
     relationship_type_child 
     relationship_id_child 
+0

relationship_type = "Parking_lot", "Car", "Person" –

0

Вы можете попробовать иметь центральную таблицу отношений с одним столбцом для каждой таблицы сущностей, которую вы имеете (разрешая NULL). Для каждой комбинации есть строка с указанными идентификаторами.

Это сложно, но может позволить вам также моделировать многополовые отношения. человек Вождение автомобиля B на стоянке C. Вам, возможно, захочется добавить какой-либо ярлык, например. провести различие между «лицом A вождения автомобиля B на стоянке C» и «человек A владеет автомобилем B, который припаркован в партии C».

+0

Таким образом, таблица имела бы столбцы: {LotID, CarID, PersonID, FoodID}, и я мог бы просто заполнить ее при необходимости. Это имеет смысл, есть ли какая-либо документация соответствующих работ относительно этого подхода? – joe

+0

Ближайшая вещь, о которой я читал, была бы «звездой» схемы для хранилища данных, хотя это не совсем так. При этом вы можете сопоставить свою проблему с более правильной «звездной» схемой (или, возможно, связанной с ней «снежинкой»). См. http://en.wikipedia.org/wiki/Star_schema – jsegal

1

как обычно, «это зависит» -

это зависит от того, что вы собираетесь делать с информацией

в нормализованном представлении таблицы отображения необходимо различать (предположительно данные богатых) отношения друг от друга

в KnowledgeBASE представления одной типизированной таблицы отношений будет достаточно, хотя это требует разыменовать идентификаторов источника и назначения в различных таблицах

+0

Согласен. Это может быть много таблиц сопоставления, но они есть не просто так. –

0

P Обычно Eople связывает системы с базами данных (особенно для правильного моделирования), включая ACID persistance, что не является небольшой особенностью. С другой стороны .net - это среда для приложений и не имеет ничего общего с persistancee (он может использовать разные бэкенды для устойчивости). Поэтому, если вы не уверены, нужна ли вам полная RDBMS или вы хотите поговорить в структурах памяти, то ваш вопрос, который сложно начать с самого начала, действительно не имеет ответа.

В противном случае явно моделирование n плюс все бинарные таблицы отношений считается плюсом.

Кроме того, вы указываете таблицы взаимосвязи n плюс, как если бы это была какая-то универсальная модель. Однако это не заботится о взаимоотношениях с тройным или более высоким порядком и не заботится о нескольких бинарных отношениях (а не о множественных отношениях более высокого порядка).

Я уверен, что кто-то предложит модель EAV или некоторое расширение на нем.

Проблема в том, что при таком подходе вы получаете гибкость, но теряете способность реально осуществлять отношения.

Все зависит от того, зачем и для чего вам нужно это сопротивление.

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

Вы можете сделать то же самое и с XML или с некоторыми объектно-реляционного отображения дорожных сборов и т.д ...

Вам нужно определить проблему лучше.

+0

Это были более теоретические вопросы, которые я размышлял, но у меня были только базовые двоичные отношения в реляционной базе данных. – joe

+0

@joe, почему только двоичный? Что вы на самом деле пытаетесь моделировать? Какие факты вы хотите захватить и запросить? – Unreason

0

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

Базы данных отлично подходят для выгрузки SETS данных и для категоризации и обобщения этих данных. Это то, для чего они предназначены (среди многих других).

Они не работают так хорошо при описании сложных отношений между отдельными значениями (x глубокие отношения n: m). Структуры случайного доступа из движения NoSQL лучше.

Если вы действительно склонны использовать классическую СУРБД, вы можете моделировать проблему как график в БД, используя концепцию ребер и узлов. Узлы имеют 0: N ребер и 0: N атрибутов/значений (EAV, как было предложено выше). Края имеют 2 узла и, возможно, вес.

Вы можете моделировать его:

NODE ([node_id, entity, attribute], value) 
EDGE ([src_node_id, dest_node_id], weight) 

Создание отношения между узлами (Ребро) требует просто добавив значение в таблицу EDGE.

Для перемещения по структуре требуется рекурсивный набор запросов, которые обнаруживают все возможные шаги из текущего узла, а затем выбирают один для перехода к следующему узлу. Это может быть интенсивным для РСУБД.

EG //

SELECT dest_node_id 
FROM EDGE 
WHERE src_node_id = <<This Node ID>> 
ORDER BY weight ASC 
LIMIT 1 

Lather, полоскание и повторите однако далеко вниз по пути, который вы хотите идти (это предполагает, что вес является стоимость, а не выгода метрики и что граф представляет собой ориентированный граф).

0

Предлагаю вам менее 10 таблиц. Подумайте о том, что человек есть еду X. Если человек A находится на стоянке B, то еда X съедается на той же стоянке B; поэтому вам не нужна таблица, касающаяся пищи и парковки.

3

Я бы решил это, используя почти полиморфный подход.Вы можете просто использовать две таблицы, например:

CREATE TABLE Node (id UNIQUEIDENTIFIER NOT NULL, PRIMARY KEY (id)); 
CREATE TABLE Relationships (
    parent UNIQUENIDENTIFIER NOT NULL, 
    child UNIQUEIDENTIFIER NOT NULL, 
    CONSTRAINT FK_Relationship_ParentNode 
     FOREIGN KEY (parent) REFERENCES Node(id), 
    CONSTRAINT FK_Relationship_ChildNode 
     FOREIGN KEY (child) REFERENCES Node(id) 
); 

Тогда все ваши другие объекты «наследуют» от узла:

CREATE TABLE Person (
    id UNIQUEIDENTIFIER NOT NULL, 
    name NVARCHAR(50) NOT NULL, 
    CONSTRAINT FK_Person_Node 
     FOREIGN KEY (id) REFERENCES Node(id) 
); 

CREATE TABLE ParkingLot (
    id UNIQUEIDENTIFIER NOT NULL, 
    name NVARCHAR(50) NOT NULL, 
    address NVARCHAR(250) NOT NULL, -- bad way to model 
    CONSTRAINT FK_ParkingLot_Node 
     FOREIGN KEY (id) REFERENCES Node(id) 
); 

CREATE TABLE Food (
    id UNIQUEIDENTIFIER NOT NULL, 
    name NVARCHAR(50) NOT NULL, 
    calories INT NOT NULL, -- hopefully only needs an int ;) 
    CONSTRAINT FK_Food_Node 
     FOREIGN KEY (id) REFERENCES Node(id) 
); 

Итак, теперь вы можете моделировать отношения между любыми двумя объектами, и искать их используя соединение.

Например, если вы хотите узнать, какие продукты принадлежат к которым люди, вы могли бы сказать:

SELECT p.name AS person, f.name AS food 
FROM Person AS p 
INNER JOIN Relationships AS r 
ON r.parent = p.id 
INNER JOIN Food AS f 
ON f.id = r.child 

Конечно, если вы тогда хотели найти что-то немного глубже в иерархии, вам нужно для запроса каждого уровня. Но поскольку ваши сущности (предположительно) - реальные вещи, а не только уровни в иерархии, это должно быть хорошо :).

Смежные вопросы