Как мне разработать такую схему в MongoDB? Думаю внешних ключей нет!
sql
mongodb
foreign-keys
nosql
Марк Пегасов
источник
источник
Ответы:
Возможно, вам будет интересно использовать ORM, например Mongoid или MongoMapper.
http://mongoid.org/docs/relations/referenced/1-n.html
В базе данных NoSQL, такой как MongoDB, есть не «таблицы», а коллекции. Документы сгруппированы внутри коллекций. У вас может быть любой документ - с любыми данными - в одной коллекции. По сути, в базе данных NoSQL вам решать, как организовать данные и их связи, если они есть.
Mongoid и MongoMapper предоставляют вам удобные методы для простой установки отношений. Просмотрите ссылку, которую я вам дал, и спросите о чем угодно.
Редактировать:
На монгоиде вы напишете свою схему так:
class Student include Mongoid::Document field :name embeds_many :addresses embeds_many :scores end class Address include Mongoid::Document field :address field :city field :state field :postalCode embedded_in :student end class Score include Mongoid::Document belongs_to :course field :grade, type: Float embedded_in :student end class Course include Mongoid::Document field :name has_many :scores end
Редактировать:
> db.foo.insert({group:"phones"}) > db.foo.find() { "_id" : ObjectId("4df6539ae90592692ccc9940"), "group" : "phones" } { "_id" : ObjectId("4df6540fe90592692ccc9941"), "group" : "phones" } >db.foo.find({'_id':ObjectId("4df6539ae90592692ccc9940")}) { "_id" : ObjectId("4df6539ae90592692ccc9940"), "group" : "phones" }
Вы можете использовать этот ObjectId для установления отношений между документами.
источник
Во-первых, чтобы уточнить некоторые соглашения об именах. MongoDB использует
collections
вместоtables
.Возьмем следующую модель:
student { _id: ObjectId(...), name: 'Jane', courses: [ { course: 'bio101', mark: 85 }, { course: 'chem101', mark: 89 } ] } course { _id: 'bio101', name: 'Biology 101', description: 'Introduction to biology' }
Очевидно, что список курсов Джейн указывает на некоторые конкретные курсы. База данных не применяет никаких ограничений к системе ( например: ограничения внешнего ключа ), поэтому нет «каскадных удалений» или «каскадных обновлений». Однако база данных действительно содержит правильную информацию.
Кроме того, MongoDB имеет стандарт DBRef, который помогает стандартизировать создание этих ссылок. На самом деле, если вы посмотрите на эту ссылку, там есть похожий пример.
Чтобы было ясно, MongoDB не является реляционным. Не существует стандартной «нормальной формы». Вы должны смоделировать свою базу данных в соответствии с данными, которые вы храните, и запросами, которые вы собираетесь выполнять.
источник
Мы можем определить так называемое
foreign key
в MongoDB. Однако нам необходимо поддерживать целостность данных САМИ . Например,student { _id: ObjectId(...), name: 'Jane', courses: ['bio101', 'bio102'] // <= ids of the courses } course { _id: 'bio101', name: 'Biology 101', description: 'Introduction to biology' }
courses
Поле содержит_id
е курсы. Отношения «один ко многим» легко определить. Однако, если мы хотим получить имена курсов студентаJane
, нам нужно выполнить другую операцию, чтобы получитьcourse
документ через_id
.Если курс
bio101
удален, нам нужно выполнить еще одну операцию для обновленияcourses
поля вstudent
документе.Подробнее: Дизайн схемы MongoDB
Типизированный документ MongoDB поддерживает гибкие способы определения отношений. Чтобы определить отношение «один ко многим»:
Встроенный документ
Пример:
student { name: 'Kate Monster', addresses : [ { street: '123 Sesame St', city: 'Anytown', cc: 'USA' }, { street: '123 Avenue Q', city: 'New York', cc: 'USA' } ] }
Ссылка на ребенка
Как и в
student
/course
примере выше.Родительские ссылки
Подходит для сообщений от одного к сквиллионам, например для сообщений журнала.
host { _id : ObjectID('AAAB'), name : 'goofy.example.com', ipaddr : '127.66.66.66' } logmsg { time : ISODate("2014-03-28T09:42:41.382Z"), message : 'cpu is on fire!', host: ObjectID('AAAB') // Reference to the Host document }
Фактически, a
host
является родительским элементом дляlogmsg
. Обращение кhost
идентификатору экономит много места, учитывая, что сообщения журнала являются сквиллионами.Ссылки:
источник
Из книги Little MongoDB
Так,
student { _id: ObjectId(...), name: 'Jane', courses: [ { name: 'Biology 101', mark: 85, id:bio101 }, ] }
Если это данные RESTful API, замените идентификатор курса ссылкой GET на ресурс курса.
источник
Цель ForeignKey - предотвратить создание данных, если значение поля не соответствует его ForeignKey. Для этого в MongoDB мы используем промежуточное программное обеспечение Schema, которое обеспечивает согласованность данных.
Пожалуйста, посмотрите документацию. https://mongoosejs.com/docs/middleware.html#pre
источник