¿Cómo diseño un esquema como este en MongoDB? ¡Creo que no hay claves foráneas!
¿Cómo diseño un esquema como este en MongoDB? ¡Creo que no hay claves foráneas!
Respuestas:
Puede que le interese utilizar un ORM como Mongoid o MongoMapper.
http://mongoid.org/docs/relations/referenced/1-n.html
En una base de datos NoSQL como MongoDB no hay 'tablas' sino colecciones. Los documentos se agrupan dentro de Colecciones. Puede tener cualquier tipo de documento, con cualquier tipo de datos, en una sola colección. Básicamente, en una base de datos NoSQL depende de usted decidir cómo organizar los datos y sus relaciones, si las hay.
Lo que hacen Mongoid y MongoMapper es proporcionarle métodos convenientes para establecer relaciones con bastante facilidad. Mira el enlace que te di y pregunta cualquier cosa.
Editar:
En mongoid escribirás tu esquema así:
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
Editar:
> 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" }
Puede usar ese ObjectId para hacer relaciones entre documentos.
¿Cómo diseñar una mesa como esta en mongodb?
Primero, para aclarar algunas convenciones de nomenclatura. MongoDB usa en collections
lugar de tables
.
¡Creo que no hay claves foráneas!
Toma el siguiente modelo:
student
{
_id: ObjectId(...),
name: 'Jane',
courses: [
{ course: 'bio101', mark: 85 },
{ course: 'chem101', mark: 89 }
]
}
course
{
_id: 'bio101',
name: 'Biology 101',
description: 'Introduction to biology'
}
Claramente, la lista de cursos de Jane apunta a algunos cursos específicos. La base de datos no aplica ninguna restricción al sistema ( es decir, restricciones de clave externa ), por lo que no hay "eliminaciones en cascada" o "actualizaciones en cascada". Sin embargo, la base de datos contiene la información correcta.
Además, MongoDB tiene un estándar DBRef que ayuda a estandarizar la creación de estas referencias. De hecho, si echa un vistazo a ese enlace, tiene un ejemplo similar.
¿Cómo puedo solucionar esta tarea?
Para ser claros, MongoDB no es relacional. No existe una "forma normal" estándar. Debe modelar su base de datos de manera apropiada para los datos que almacena y las consultas que pretende ejecutar.
Podemos definir el llamado foreign key
en MongoDB. Sin embargo, necesitamos mantener la integridad de los datos POR NOSOTROS MISMOS . Por ejemplo,
student
{
_id: ObjectId(...),
name: 'Jane',
courses: ['bio101', 'bio102'] // <= ids of the courses
}
course
{
_id: 'bio101',
name: 'Biology 101',
description: 'Introduction to biology'
}
El courses
campo contiene _id
s de cursos. Es fácil definir una relación de uno a varios. Sin embargo, si queremos recuperar los nombres de los estudiantes del curso Jane
, necesitamos realizar otra operación para recuperar el course
documento a través de _id
.
Si bio101
se elimina el curso , debemos realizar otra operación para actualizar el courses
campo en el student
documento.
La naturaleza de tipo documento de MongoDB admite formas flexibles de definir relaciones. Para definir una relación de uno a varios:
Ejemplo:
student
{
name: 'Kate Monster',
addresses : [
{ street: '123 Sesame St', city: 'Anytown', cc: 'USA' },
{ street: '123 Avenue Q', city: 'New York', cc: 'USA' }
]
}
Como el student
/ course
ejemplo anterior.
Adecuado para uno a escuillones, como mensajes de 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
}
Prácticamente, a host
es el padre de a logmsg
. Hacer referencia a la host
identificación ahorra mucho espacio dado que los mensajes de registro son millones.
Referencias:
Sin embargo, otra alternativa al uso de combinaciones es desnormalizar sus datos. Históricamente, la desnormalización se reservaba para el código sensible al rendimiento o cuando los datos debían tomarse una instantánea (como en un registro de auditoría). Sin embargo, con la creciente popularidad de NoSQL, muchos de los cuales no tienen combinaciones, la desnormalización como parte del modelado normal se está volviendo cada vez más común. Esto no significa que deba duplicar todos los datos de cada documento. Sin embargo, en lugar de dejar que el miedo a los datos duplicados impulse sus decisiones de diseño, considere modelar sus datos en función de qué información pertenece a qué documento.
Entonces,
student
{
_id: ObjectId(...),
name: 'Jane',
courses: [
{
name: 'Biology 101',
mark: 85,
id:bio101
},
]
}
Si se trata de datos de la API RESTful, reemplace la identificación del curso con un enlace GET al recurso del curso
El propósito de ForeignKey es evitar la creación de datos si el valor del campo no coincide con su ForeignKey. Para lograr esto en MongoDB, usamos middlewares Schema que aseguran la consistencia de los datos.
Consulte la documentación. https://mongoosejs.com/docs/middleware.html#pre