Jak zaprojektować taki schemat w MongoDB? Myślę, że nie ma kluczy obcych!
sql
mongodb
foreign-keys
nosql
Mark Pegasov
źródło
źródło
Odpowiedzi:
Możesz być zainteresowany użyciem ORM, takiego jak Mongoid lub MongoMapper.
http://mongoid.org/docs/relations/referenced/1-n.html
W bazie danych NoSQL, takiej jak MongoDB, nie ma „tabel”, ale kolekcje. Dokumenty są pogrupowane w Kolekcje. Możesz mieć dowolny dokument - z dowolnymi danymi - w jednej kolekcji. Zasadniczo, w bazie danych NoSQL to Ty decydujesz, jak zorganizować dane i ich relacje, jeśli takie istnieją.
To, co robią Mongoid i MongoMapper, to zapewnienie wygodnych metod łatwego konfigurowania relacji. Sprawdź link, który ci dałem i zapytaj o wszystko.
Edytować:
W Mongoid napiszesz swój schemat w ten sposób:
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
Edytować:
> 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" }
Możesz użyć tego ObjectId do tworzenia relacji między dokumentami.
źródło
Po pierwsze, aby wyjaśnić pewne konwencje nazewnictwa. MongoDB używa
collections
zamiasttables
.Weź następujący model:
student { _id: ObjectId(...), name: 'Jane', courses: [ { course: 'bio101', mark: 85 }, { course: 'chem101', mark: 89 } ] } course { _id: 'bio101', name: 'Biology 101', description: 'Introduction to biology' }
Najwyraźniej lista kursów Jane wskazuje na określone kursy. Baza danych nie nakłada żadnych ograniczeń na system ( np. Ograniczenia klucza obcego ), więc nie ma „kaskadowego usuwania” ani „kaskadowych aktualizacji”. Jednak baza danych zawiera poprawne informacje.
Ponadto MongoDB ma standard DBRef, który pomaga ujednolicić tworzenie tych odniesień. W rzeczywistości, jeśli spojrzysz na ten link, ma on podobny przykład.
Żeby było jasne, MongoDB nie jest relacyjne. Nie ma standardowej „postaci normalnej”. Bazę danych należy modelować odpowiednio do przechowywanych danych i zapytań, które zamierzasz uruchamiać.
źródło
foreign key
W MongoDB możemy zdefiniować tzw . Jednak musimy sami dbać o integralność danych . Na przykład,student { _id: ObjectId(...), name: 'Jane', courses: ['bio101', 'bio102'] // <= ids of the courses } course { _id: 'bio101', name: 'Biology 101', description: 'Introduction to biology' }
courses
Pole zawiera_id
s kursów. Łatwo jest zdefiniować relację jeden do wielu. Jeśli jednak chcemy pobrać nazwy kursów uczniówJane
, musimy wykonać inną operację, aby pobraćcourse
dokument za pośrednictwem_id
.Jeśli kurs
bio101
zostanie usunięty, musimy wykonać kolejną operację, aby zaktualizowaćcourses
pole wstudent
dokumencie.Więcej: Projekt schematu MongoDB
Typ dokumentu MongoDB obsługuje elastyczne sposoby definiowania relacji. Aby zdefiniować relację jeden do wielu:
Dokument osadzony
Przykład:
student { name: 'Kate Monster', addresses : [ { street: '123 Sesame St', city: 'Anytown', cc: 'USA' }, { street: '123 Avenue Q', city: 'New York', cc: 'USA' } ] }
Odniesienia do dzieci
Podobnie jak
student
/course
przykładzie powyżej.Odniesienia do rodziców
Odpowiedni dla jednego do squillions, takich jak komunikaty dziennika.
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 }
Praktycznie a
host
jest rodzicemlogmsg
. Odwołanie się dohost
identyfikatora oszczędza dużo miejsca, biorąc pod uwagę, że komunikaty dziennika to miliardy.Bibliografia:
źródło
Z książki The Little MongoDB
Więc,
student { _id: ObjectId(...), name: 'Jane', courses: [ { name: 'Biology 101', mark: 85, id:bio101 }, ] }
Jeśli są to dane RESTful API, zamień identyfikator kursu na łącze GET do zasobu kursu
źródło
Celem ForeignKey jest zapobieganie tworzeniu danych, jeśli wartość pola nie jest zgodna z jego ForeignKey. Aby to osiągnąć w MongoDB, używamy oprogramowania pośredniego Schema, które zapewnia spójność danych.
Zapoznaj się z dokumentacją. https://mongoosejs.com/docs/middleware.html#pre
źródło