MongoDB Альтернативный дизайн - PullRequest
1 голос
/ 25 февраля 2010

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

Вот ситуация. У меня есть объект Первый. Первый имеет массив вторых объектов. Второй имеет массив третьих объектов.

db.myDb.findOne()
{
    "_id" : ObjectId("..."),
    "Seconds" : [
        {
            "Second Name" : "value",
            "Thirds" : [
                {
                    "Third Name" : "value" 
                }
            ]
        }
    ]
}

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

Когда вы открываете третью страницу, кажется неправильным иметь запрос для получения единственного объекта First, а затем как-то детализировать код, чтобы получить данные для правильного третьего объекта. Было бы намного проще просто получить один третий объект напрямую, возможно, с помощью _id.

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

Это был бы правильный способ решения этой проблемы, или я просто не очень ясно представлял себе землю документа?

1 Ответ

1 голос
/ 01 марта 2010

Я думаю, это будет зависеть от использования. Если вам часто требуется доступ к элементам ' Second ' или ' Third ' без содержания ' First ', то, возможно, их лучше не внедрять.

Вопрос, который я использовал, чтобы помочь мне определить, может ли что-то быть лучше встроено или нет, состоит в том, чтобы спросить себя, является ли оно частью этого или связано с ним. Например, действительно ли ' First ' содержит один или несколько ' Seconds ' (и т. Д.), Или это отдельные вещи, которые каким-то образом связаны между собой? На первый взгляд, я бы сказал, что блог post содержит comments (если у вас нет острой необходимости запрашивать список комментариев без знания постов), но пользователь / автор , вероятно, не содержит списка сообщений, скорее они будут каким-то образом связаны, но находятся в разных коллекциях.

Связи между коллекциями можно установить с помощью MongoDB, используя DBRef . Это специальный тип, который описывает отношения с другим объектом. Если ваши элементы принадлежат их собственным коллекциям, они могут иметь DBRef для указания между ними. Они могут идти в любом направлении (то есть, в коллекции First , или в каждом Second может быть один, указывающий на его родителя первым).

Пример 1 - у каждого родителя есть коллекция дочерних ссылок:

db.firsts.findOne()
{
    "_id" : ObjectId("..."),
    "Seconds" : [
        { $ref : 'seconds', $id : <idvalue> },
        { $ref : 'seconds', $id : <idvalue> },
        { $ref : 'seconds', $id : <idvalue> }
    ]
}

db.seconds.findOne()
{
    "_id" : ObjectId("..."),
    "Second Name" : "value",
    "Thirds" : [
        { $ref : 'thirds', $id : <idvalue> },
        { $ref : 'thirds', $id : <idvalue> }
    ]
}

db.thirds.findOne()
{
    "_id" : ObjectId("..."),
    "Third Name" : "value"
}

Пример 2 - каждый ребенок имеет ссылку на своего родителя

db.firsts.findOne()
{
    "_id" : ObjectId("...")
}

db.seconds.findOne()
{
    "_id" : ObjectId("..."),
    "First" : { $ref : 'firsts', $id : <idvalue> }
    "Second Name" : "value",
}

db.thirds.findOne()
{
    "_id" : ObjectId("..."),
    "Second" : { $ref : 'seconds', $id : <idvalue> }
    "Third Name" : "value"
}

Большинство языковых драйверов MongoDB имеют способ работать с dbrefs более аккуратно, чем на консоли (обычно с использованием некоторого класса DBRef). Работа таким образом будет означать, что у вас будет больше запросов к базе данных, но если это имеет смысл для вашего приложения, это, вероятно, справедливый компромисс, особенно если список «секунд» или «третей» в вашем примере обычно необходим или ключ к взаимодействию с системой или ее функциональностью.

Второй подход наиболее похож на использование традиционной реляционной БД. Прелесть MongoDB в том, что он позволяет вам работать реляционно, когда это действительно имеет смысл, а не тогда, когда это не так. Очень гибкий, и в конечном итоге это зависит от ваших данных и приложения от того, что имеет смысл для вас. В конечном счете, ответ на ваш вопрос о том, какой метод вы должны использовать, зависит от вашего приложения и хранящихся в нем данных, а не от того, что мы можем сказать из вашего примера.

...