Як мені розробити таку схему в MongoDB? Думаю, зовнішніх ключів немає!
Як мені розробити таку схему в MongoDB? Думаю, зовнішніх ключів немає!
Відповіді:
Можливо, вам буде цікаво використовувати 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
Редагувати:
> 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?
По-перше, для уточнення деяких конвенцій щодо іменування. 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, оформлений документом, підтримує гнучкі способи визначення взаємозв’язків. Щоб визначити взаємозв'язок "один до багатьох":
Приклад:
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
є батьком a logmsg
. Посилання на host
ідентифікатор економить багато місця, враховуючи те, що повідомлення журналу є мільйонами.
Список літератури:
Ще однією альтернативою використання об’єднань є денормалізація даних. Історично денормалізація була зарезервована для коду, що чутливий до продуктивності, або коли дані повинні бути зроблені моментальними знімками (як у журналі аудиту). Однак із постійно зростаючою популярністю NoSQL, багато з яких не мають об’єднань, денормалізація як частина звичайного моделювання стає все більш поширеною. Це не означає, що ви повинні дублювати кожну інформацію в кожному документі. Однак замість того, щоб боятися дублікатів даних керувати вашими дизайнерськими рішеннями, подумайте про моделювання даних на основі того, яка інформація належить до якого документа.
Так,
student
{
_id: ObjectId(...),
name: 'Jane',
courses: [
{
name: 'Biology 101',
mark: 85,
id:bio101
},
]
}
Якщо це дані RESTful API, замініть ідентифікатор курсу на посилання GET на ресурс курсу
Метою ForeignKey є запобігання створенню даних, якщо значення поля не відповідає його ForeignKey. Для досягнення цього в MongoDB ми використовуємо проміжні засоби схеми, які забезпечують узгодженість даних.
Будь ласка, подивіться документацію. https://mongoosejs.com/docs/middleware.html#pre