Как применить внешние ключи в базах данных NoSql (MongoDB)? - PullRequest
15 голосов
/ 19 ноября 2011

Допустим, у меня есть коллекция документов, таких как:

{ "_id" : 0 , "owner":0 "name":"Doc1"},{ "_id" : 1 , "owner":1, "name":"Doc1"}, etc

И, с другой стороны, владельцы представлены отдельной коллекцией:

{ "_id" : 0 , "username":"John"}, { "_id" : 1 , "username":"Sam"}

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

Я знаю, что могу проверить правильность вставки из моего бизнес-кода, НО что если злоумышленник подделает мой запрос к серверу и выдаст «владелец»: 100, а Mongo не выдаст никакого исключения.

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

Заранее спасибо!

Ответы [ 6 ]

18 голосов
/ 20 ноября 2011

MongoDB не имеет внешних ключей (как вы, вероятно, заметили).По сути, ответ таков: «Не позволяйте пользователям вмешиваться в запросы. Разрешите приложению вставлять данные, соответствующие вашим правилам ссылочной целостности».

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

14 голосов
/ 20 ноября 2011

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

Тем не менее, Я не рекомендую использовать DBRef . Позвольте вашему клиентскому коду управлять связями или (еще лучше) связать документы вместе с самого начала. Вы можете рассмотреть возможность встраивания «документов» владельца в сам объект владельца. Соберите свои документы, чтобы они соответствовали вашим шаблонам использования, и MongoDB засияет.

1 голос
/ 20 декабря 2016

В качестве решения NoSQL вы можете использовать MariaDB (NewSQL) Это сочетание SQL и NoSQL, реализованное разработчиками MySQL с отличной производительностью.

0 голосов
/ 06 февраля 2018

Это отношения один-к-одному. Лучше встраивать один документ в другой, а не поддерживать отдельные коллекции. Проверьте здесь о том, как их моделировать в mongodb и их преимуществах.

Хотя в документах это явно не упоминается, встраивание дает тот же эффект, что и ограничения внешнего ключа. Просто хочу прояснить эту идею. Если у вас есть две такие коллекции:

С1:

{ "_id" : 0 , "owner":0 "name":"Doc1"},{ "_id" : 1 , "owner":1, "name":"Doc1"}, etc

С2:

{ "_id" : 0 , "username":"John"}, { "_id" : 1 , "username":"Sam"}

И если вы объявите ограничение внешнего ключа на C2._id для ссылки на C1._id (при условии, что MongoDB позволяет это), это будет означать, что вы не можете вставить документ в C2, где C2._id не существует в C1. Сравните это со встроенным документом:

{
    "_id" : 0 , 
    "owner" : 0,
    "name" : "Doc1",
    "owner_details" : {
        "username" : "John"
    }
}

Теперь поле owner_details представляет данные из коллекции C2, а остальные поля представляют данные из C1. Вы не можете добавить поле owner_details в несуществующий документ. По сути, вы достигаете того же эффекта.

0 голосов
/ 28 мая 2015

Если кто-то действительно хочет применить внешние ключи в Project / WebApp.Тогда вам следует использовать подход MixSQL, то есть SQL + NoSQL

. Я бы предпочел, чтобы объемные данные, которые не имеют такого большого количества ссылок, могли бы храниться в NoSQL database Store.Например: данные типа «Отели» или «Места».

Но если есть серьезные вещи, такие как OAuth-модули Tables, TokenStore и UserDetails, UserRole (Таблица сопоставления) и т. Д., То вы можете перейти с SQL.

0 голосов
/ 28 февраля 2012

Я также рекомендовал бы, чтобы, если имена пользователей были уникальными, используйте их в качестве _id. Вы сэкономите на индексе. В хранимом документе установите значение «owner» в приложении в качестве значения «username» при создании документа и никогда не позволяйте никаким другим частям кода обновлять его.

Если есть требования сменить владельца, предоставьте подходящие API с внедренными бизнес-правилами.

Внешние ключи не нужны.

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