Иностранные ключи в монго?

enter image description here

Как мне создать такую ​​схему в MongoDB? Я думаю, что нет внешних ключей!

Ответ 1

Возможно, вас заинтересует использование ORM, например Mongoid или MongoMapper.

http://mongoid.org/docs/relations/referenced/1-n.html

В базе данных NoSQL, такой как MongoDB, есть не "таблицы", а коллекции. Документы сгруппированы внутри Коллекции. Вы можете иметь любой вид документа - с любым видом данных - в одной коллекции. По сути, в базе данных NoSQL вам решать, как организовать данные и их отношения, если они есть.

Mongoid и MongoMapper предоставляют вам удобные методы для установки отношений. Посмотрите на ссылку, которую я вам дал, и спросите что-нибудь.

Изменить:

В mongoid вы напишите свою схему так:

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

Edit:

> 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 для связи между документами.

Ответ 2

Как спроектировать такой стол в mongodb?

Во-первых, чтобы уточнить некоторые соглашения об именах. 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 не является реляционным. Стандартной "нормальной формы" не существует. Вы должны смоделировать свою базу данных в соответствии с данными, которые вы храните, и запросами, которые вы собираетесь выполнять.

Ответ 3

Из Книга Little MongoDB

Еще одна альтернатива использованию объединений - денормализация ваших данных. Исторически, денормализация была зарезервирована для чувствительный к производительности код или когда данные должны быть сняты (например, в журнале аудита). Однако, растущая популярность NoSQL, многие из которых не имеют объединений, денормализация как часть нормального моделирования становится чаще. Это не означает, что вы должны дублировать каждую информацию в каждом документе. Однако, вместо того, чтобы бояться дублирования данных, управляйте вашими проектными решениями, подумайте о моделировании своих данных на основе того, что информация принадлежит тому документу.

Итак,

student
{ 
    _id: ObjectId(...),
    name: 'Jane',
    courses: [
    { 
        name: 'Biology 101', 
        mark: 85, 
        id:bio101 
    },
  ]
}

Если это данные RESTful API, замените идентификатор курса ссылкой GET на ресурс курса

Ответ 4

Мы можем определить так называемый 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 поддерживает гибкие способы определения отношений. Чтобы определить отношение один ко многим:

Встроенный документ

  1. Подходит для одного-немногим.
  2. Преимущество: нет необходимости выполнять дополнительные запросы к другому документу.
  3. Недостаток: невозможно управлять сущностью встроенных документов по отдельности.

Пример:

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
}

Фактически, host является родителем logmsg. Ссылка на идентификатор host экономит много места, учитывая, что сообщения журнала составляют миллиарды.

Рекомендации:

  1. 6 практических правил для разработки схемы MongoDB: Часть 1
  2. 6 практических правил для разработки схемы MongoDB: часть 2
  3. 6 практических правил для разработки схемы MongoDB: Часть 3
  4. Смоделируйте отношения "один ко многим" со ссылками на документы