Wie entwerfe ich ein solches Schema in MongoDB? Ich denke es gibt keine Fremdschlüssel!
Wie entwerfe ich ein solches Schema in MongoDB? Ich denke es gibt keine Fremdschlüssel!
Antworten:
Möglicherweise möchten Sie ein ORM wie Mongoid oder MongoMapper verwenden.
http://mongoid.org/docs/relations/referenced/1-n.html
In einer NoSQL-Datenbank wie MongoDB gibt es keine 'Tabellen', sondern Sammlungen. Dokumente werden in Sammlungen gruppiert. Sie können jede Art von Dokument - mit jeder Art von Daten - in einer einzigen Sammlung haben. Grundsätzlich liegt es in einer NoSQL-Datenbank an Ihnen, zu entscheiden, wie die Daten und ihre Beziehungen, falls vorhanden, organisiert werden sollen.
Mongoid und MongoMapper bieten Ihnen bequeme Methoden zum einfachen Einrichten von Beziehungen. Schauen Sie sich den Link an, den ich Ihnen gegeben habe, und fragen Sie etwas.
Bearbeiten:
In Mongoid schreiben Sie Ihr Schema wie folgt:
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
Bearbeiten:
> 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" }
Sie können diese ObjectId verwenden, um Beziehungen zwischen Dokumenten herzustellen.
Wie entwerfe ich einen solchen Tisch in Mongodb?
Erstens, um einige Namenskonventionen zu klären. MongoDB verwendet collections
anstelle von tables
.
Ich denke es gibt keine Fremdschlüssel!
Nehmen Sie das folgende Modell:
student
{
_id: ObjectId(...),
name: 'Jane',
courses: [
{ course: 'bio101', mark: 85 },
{ course: 'chem101', mark: 89 }
]
}
course
{
_id: 'bio101',
name: 'Biology 101',
description: 'Introduction to biology'
}
Die Kursliste von Jane weist eindeutig auf bestimmte Kurse hin. Die Datenbank wendet keine Einschränkungen auf das System an ( dh Fremdschlüsseleinschränkungen ), daher gibt es keine "kaskadierenden Löschvorgänge" oder "kaskadierenden Aktualisierungen". Die Datenbank enthält jedoch die richtigen Informationen.
Darüber hinaus verfügt MongoDB über einen DBRef-Standard , mit dessen Hilfe die Erstellung dieser Referenzen standardisiert werden kann. Wenn Sie sich diesen Link ansehen, gibt es ein ähnliches Beispiel.
Wie kann ich diese Aufgabe lösen?
Um klar zu sein, ist MongoDB nicht relational. Es gibt keine Standard "Normalform". Sie sollten Ihre Datenbank entsprechend den von Ihnen gespeicherten Daten und den Abfragen modellieren, die Sie ausführen möchten.
Wir können das sogenannte foreign key
in MongoDB definieren. Allerdings müssen wir die Datenintegrität erhalten von uns . Beispielsweise,
student
{
_id: ObjectId(...),
name: 'Jane',
courses: ['bio101', 'bio102'] // <= ids of the courses
}
course
{
_id: 'bio101',
name: 'Biology 101',
description: 'Introduction to biology'
}
Das courses
Feld enthält _id
s von Kursen. Es ist einfach, eine Eins-zu-Viele-Beziehung zu definieren. Wenn wir jedoch die Kursnamen des Studenten abrufen möchten Jane
, müssen wir einen weiteren Vorgang ausführen, um das course
Dokument über abzurufen _id
.
Wenn der Kurs bio101
entfernt wird, müssen wir einen weiteren Vorgang ausführen, um das courses
Feld im student
Dokument zu aktualisieren .
Die dokumenttypisierte Natur von MongoDB unterstützt flexible Möglichkeiten zum Definieren von Beziehungen. So definieren Sie eine Eins-zu-Viele-Beziehung:
Beispiel:
student
{
name: 'Kate Monster',
addresses : [
{ street: '123 Sesame St', city: 'Anytown', cc: 'USA' },
{ street: '123 Avenue Q', city: 'New York', cc: 'USA' }
]
}
Wie das student
/ course
Beispiel oben.
Geeignet für Eins-zu-Billionen, wie z. B. Protokollnachrichten.
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 ist praktisch host
das Elternteil von a logmsg
. Das Verweisen auf die host
ID spart viel Platz, da die Protokollnachrichten Billionen sind.
Verweise:
Eine weitere Alternative zur Verwendung von Joins besteht darin, Ihre Daten zu denormalisieren. In der Vergangenheit war die Denormalisierung für leistungsabhängigen Code reserviert oder für den Fall, dass Daten als Snapshots erstellt werden sollten (wie in einem Überwachungsprotokoll). Mit der stetig wachsenden Popularität von NoSQL, von denen viele keine Verknüpfungen haben, wird die Denormalisierung als Teil der normalen Modellierung immer häufiger. Dies bedeutet nicht, dass Sie jede Information in jedem Dokument duplizieren sollten. Anstatt die Angst vor doppelten Daten Ihre Entwurfsentscheidungen bestimmen zu lassen, sollten Sie Ihre Daten anhand der Informationen modellieren, die zu welchem Dokument gehören.
So,
student
{
_id: ObjectId(...),
name: 'Jane',
courses: [
{
name: 'Biology 101',
mark: 85,
id:bio101
},
]
}
Wenn es sich um RESTful-API-Daten handelt, ersetzen Sie die Kurs-ID durch einen GET-Link zur Kursressource
Der Zweck von ForeignKey besteht darin, die Erstellung von Daten zu verhindern, wenn der Feldwert nicht mit dem ForeignKey übereinstimmt. Um dies in MongoDB zu erreichen, verwenden wir Schema-Middlewares, die die Datenkonsistenz sicherstellen.
Bitte schauen Sie sich die Dokumentation an. https://mongoosejs.com/docs/middleware.html#pre