Como faço para projetar um esquema como este no MongoDB? Acho que não há chaves estrangeiras!
Como faço para projetar um esquema como este no MongoDB? Acho que não há chaves estrangeiras!
Respostas:
Você pode estar interessado em usar um ORM como Mongoid ou MongoMapper.
http://mongoid.org/docs/relations/referenced/1-n.html
Em um banco de dados NoSQL como o MongoDB, não há 'tabelas', mas coleções. Os documentos são agrupados em Coleções. Você pode ter qualquer tipo de documento - com qualquer tipo de dados - em uma única coleção. Basicamente, em um banco de dados NoSQL, cabe a você decidir como organizar os dados e suas relações, se houver.
O que o Mongoid e o MongoMapper fazem é fornecer métodos convenientes para configurar relações com bastante facilidade. Confira o link que te dei e pergunte qualquer coisa.
Editar:
No mongoid, você escreverá seu esquema assim:
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" }
Você pode usar esse ObjectId para fazer relações entre documentos.
Como projetar uma mesa como essa no Mongodb?
Primeiro, para esclarecer algumas convenções de nomenclatura. MongoDB usa em collections
vez de tables
.
Acho que não há chaves estrangeiras!
Pegue o seguinte 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, a lista de cursos de Jane aponta para alguns cursos específicos. O banco de dados não aplica nenhuma restrição ao sistema (por exemplo : restrições de chave estrangeira ), portanto, não há "exclusões em cascata" ou "atualizações em cascata". No entanto, o banco de dados contém as informações corretas.
Além disso, o MongoDB possui um padrão DBRef que ajuda a padronizar a criação dessas referências. Na verdade, se você der uma olhada nesse link, ele tem um exemplo semelhante.
Como posso resolver essa tarefa?
Para ser claro, o MongoDB não é relacional. Não existe uma "forma normal" padrão. Você deve modelar seu banco de dados de acordo com os dados armazenados e as consultas que pretende executar.
Podemos definir o chamado foreign key
no MongoDB. No entanto, precisamos manter a integridade dos dados POR NÓS MESMOS . Por exemplo,
student
{
_id: ObjectId(...),
name: 'Jane',
courses: ['bio101', 'bio102'] // <= ids of the courses
}
course
{
_id: 'bio101',
name: 'Biology 101',
description: 'Introduction to biology'
}
O courses
campo contém _id
s de cursos. É fácil definir um relacionamento um para muitos. No entanto, se quisermos recuperar os nomes dos cursos do aluno Jane
, precisamos realizar outra operação para recuperar o course
documento via _id
.
Se o curso bio101
for removido, precisamos realizar outra operação para atualizar o courses
campo no student
documento.
A natureza do tipo de documento do MongoDB oferece suporte a maneiras flexíveis de definir relacionamentos. Para definir uma relação um-para-muitos:
Exemplo:
student
{
name: 'Kate Monster',
addresses : [
{ street: '123 Sesame St', city: 'Anytown', cc: 'USA' },
{ street: '123 Avenue Q', city: 'New York', cc: 'USA' }
]
}
Como o student
/ course
exemplo acima.
Adequado para um para squillions, como mensagens de log.
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
é o pai de a logmsg
. Fazer referência ao host
id economiza muito espaço, visto que as mensagens de log são quilhões.
Referências:
Outra alternativa ao uso de junções é desnormalizar seus dados. Historicamente, a desnormalização era reservada para códigos sensíveis ao desempenho ou quando os dados deveriam ser capturados (como em um log de auditoria). No entanto, com a popularidade cada vez maior do NoSQL, muitos dos quais não têm junções, a desnormalização como parte da modelagem normal está se tornando cada vez mais comum. Isso não significa que você deve duplicar todas as informações em todos os documentos. No entanto, em vez de permitir que o medo de dados duplicados direcione suas decisões de design, considere modelar seus dados com base em quais informações pertencem a qual documento.
Assim,
student
{
_id: ObjectId(...),
name: 'Jane',
courses: [
{
name: 'Biology 101',
mark: 85,
id:bio101
},
]
}
Se for um dado API RESTful, substitua o ID do curso por um link GET para o recurso do curso
O objetivo de ForeignKey é evitar a criação de dados se o valor do campo não corresponder a sua ForeignKey. Para fazer isso no MongoDB, usamos middlewares Schema que garantem a consistência dos dados.
Por favor, dê uma olhada na documentação. https://mongoosejs.com/docs/middleware.html#pre