Come si progetta uno schema come questo in MongoDB? Penso che non ci siano chiavi esterne!
Come si progetta uno schema come questo in MongoDB? Penso che non ci siano chiavi esterne!
Risposte:
Potresti essere interessato a utilizzare un ORM come Mongoid o MongoMapper.
http://mongoid.org/docs/relations/referenced/1-n.html
In un database NoSQL come MongoDB non ci sono "tabelle" ma raccolte. I documenti sono raggruppati all'interno delle raccolte. Puoi avere qualsiasi tipo di documento, con qualsiasi tipo di dati, in un'unica raccolta. In pratica, in un database NoSQL sta a te decidere come organizzare i dati e le loro relazioni, se ce ne sono.
Quello che fanno Mongoid e MongoMapper è fornire metodi convenienti per impostare le relazioni abbastanza facilmente. Controlla il link che ti ho fornito e chiedi qualsiasi cosa.
Modificare:
In mongoid scriverai il tuo schema in questo modo:
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
Modificare:
> 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" }
È possibile utilizzare tale ObjectId per creare relazioni tra i documenti.
Come progettare un tavolo come questo a Mongodb?
Primo, per chiarire alcune convenzioni di denominazione. MongoDB utilizza collections
invece di tables
.
Penso che non ci siano chiavi esterne!
Prendi il seguente modello:
student
{
_id: ObjectId(...),
name: 'Jane',
courses: [
{ course: 'bio101', mark: 85 },
{ course: 'chem101', mark: 89 }
]
}
course
{
_id: 'bio101',
name: 'Biology 101',
description: 'Introduction to biology'
}
Chiaramente l'elenco dei corsi di Jane punta ad alcuni corsi specifici. Il database non applica alcun vincolo al sistema (ad esempio: vincoli di chiave esterna ), quindi non ci sono "eliminazioni a cascata" o "aggiornamenti a cascata". Tuttavia, il database contiene le informazioni corrette.
Inoltre, MongoDB ha uno standard DBRef che aiuta a standardizzare la creazione di questi riferimenti. In effetti, se dai un'occhiata a quel link, ha un esempio simile.
Come posso risolvere questo compito?
Per essere chiari, MongoDB non è relazionale. Non esiste una "forma normale" standard. È necessario modellare il database in modo appropriato ai dati archiviati e alle query che si intende eseguire.
Possiamo definire il cosiddetto foreign key
in MongoDB. Tuttavia, dobbiamo mantenere l'integrità dei dati DA NOI STESSI . Per esempio,
student
{
_id: ObjectId(...),
name: 'Jane',
courses: ['bio101', 'bio102'] // <= ids of the courses
}
course
{
_id: 'bio101',
name: 'Biology 101',
description: 'Introduction to biology'
}
Il courses
campo contiene _id
i corsi. È facile definire una relazione uno-a-molti. Tuttavia, se vogliamo recuperare i nomi dei corsi degli studenti Jane
, dobbiamo eseguire un'altra operazione per recuperare il course
documento tramite _id
.
Se il corso bio101
viene rimosso, dobbiamo eseguire un'altra operazione per aggiornare il courses
campo nel filestudent
documento.
La natura tipizzata da documento di MongoDB supporta modi flessibili per definire le relazioni. Per definire una relazione uno-a-molti:
Esempio:
student
{
name: 'Kate Monster',
addresses : [
{ street: '123 Sesame St', city: 'Anytown', cc: 'USA' },
{ street: '123 Avenue Q', city: 'New York', cc: 'USA' }
]
}
Come l' esempio student
/ course
sopra.
Adatto per one-to-squillions, come i messaggi di registro.
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
}
Virtualmente, a host
è il genitore di a logmsg
. Fare riferimento host
all'ID consente di risparmiare molto spazio dato che i messaggi di log sono squillioni.
Riferimenti:
Un'altra alternativa all'uso dei join è denormalizzare i dati. Storicamente, la denormalizzazione era riservata al codice sensibile alle prestazioni o quando i dati dovevano essere snapshot (come in un registro di controllo). Tuttavia, con la popolarità sempre crescente di NoSQL, molti dei quali non hanno join, la denormalizzazione come parte della modellazione normale sta diventando sempre più comune. Questo non significa che dovresti duplicare ogni informazione in ogni documento. Tuttavia, anziché lasciare che la paura dei dati duplicati guidi le tue decisioni di progettazione, considera la possibilità di modellare i dati in base alle informazioni che appartengono a quale documento.
Così,
student
{
_id: ObjectId(...),
name: 'Jane',
courses: [
{
name: 'Biology 101',
mark: 85,
id:bio101
},
]
}
Se si tratta di dati API RESTful, sostituire l'ID del corso con un collegamento GET alla risorsa del corso
Lo scopo di ForeignKey è impedire la creazione di dati se il valore del campo non corrisponde alla sua ForeignKey. Per ottenere ciò in MongoDB, utilizziamo middleware Schema che garantiscono la coerenza dei dati.
Si prega di dare un'occhiata alla documentazione. https://mongoosejs.com/docs/middleware.html#pre