MongoDB'de böyle bir planı nasıl tasarlarım? Sanırım yabancı anahtar yok!
MongoDB'de böyle bir planı nasıl tasarlarım? Sanırım yabancı anahtar yok!
Yanıtlar:
Mongoid veya MongoMapper gibi bir ORM kullanmak ilginizi çekebilir.
http://mongoid.org/docs/relations/referenced/1-n.html
MongoDB gibi bir NoSQL veritabanında 'tablolar' değil koleksiyonlar vardır. Belgeler, Koleksiyonlar içinde gruplandırılır. Her türlü veriye sahip her türlü belgeye tek bir koleksiyonda sahip olabilirsiniz. Temel olarak, bir NoSQL veritabanında, verilerin ve varsa ilişkilerinin nasıl düzenleneceğine karar vermek size kalmıştır.
Mongoid ve MongoMapper'ın yaptığı şey, ilişkileri oldukça kolay kurmanız için size uygun yöntemler sağlamaktır. Size verdiğim bağlantıya bakın ve herhangi bir şey sorun.
Düzenle:
Mongoid'de planınızı şöyle yazacaksınız:
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
Düzenle:
> 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" }
Belgeler arasında ilişki kurmak için bu ObjectId'yi kullanabilirsiniz.
Mongodb'da böyle bir masa nasıl tasarlanır?
İlk olarak, bazı adlandırma kurallarını açıklığa kavuşturmak. MongoDB collections
yerine tables
.
Sanırım yabancı anahtar yok!
Aşağıdaki modeli alın:
student
{
_id: ObjectId(...),
name: 'Jane',
courses: [
{ course: 'bio101', mark: 85 },
{ course: 'chem101', mark: 89 }
]
}
course
{
_id: 'bio101',
name: 'Biology 101',
description: 'Introduction to biology'
}
Açıkça Jane'in kurs listesi bazı belirli kurslara işaret ediyor. Veritabanı sisteme herhangi bir kısıtlama uygulamaz ( yani: yabancı anahtar kısıtlamaları ), bu nedenle "basamaklı silme" veya "basamaklı güncellemeler" yoktur. Ancak, veritabanı doğru bilgileri içerir.
Ek olarak, MongoDB, bu referansların oluşturulmasını standartlaştırmaya yardımcı olan bir DBRef standardına sahiptir. Aslında o bağlantıya bakarsanız, benzer bir örneği var.
Bu görevi nasıl çözebilirim?
Açık olmak gerekirse, MongoDB ilişkisel değildir. Standart bir "normal form" yoktur. Veritabanınızı sakladığınız verilere ve çalıştırmayı düşündüğünüz sorgulara uygun olarak modellemelisiniz.
Sözde foreign key
MongoDB'de tanımlayabiliriz . Ancak veri bütünlüğünü KENDİMİZE korumamız gerekiyor . Örneğin,
student
{
_id: ObjectId(...),
name: 'Jane',
courses: ['bio101', 'bio102'] // <= ids of the courses
}
course
{
_id: 'bio101',
name: 'Biology 101',
description: 'Introduction to biology'
}
courses
Alan içeren _id
derslerin s. Bire çok ilişkisini tanımlamak kolaydır. Ancak, öğrencinin ders adlarını almak istiyorsak Jane
, course
belgeyi almak için başka bir işlem yapmamız gerekiyor _id
.
Kurs bio101
kaldırılırsa, belgedeki courses
alanı güncellemek için başka bir işlem yapmamız gerekir student
.
MongoDB'nin belge türü yapısı, ilişkileri tanımlamanın esnek yollarını destekler. Bire çok ilişki tanımlamak için:
Misal:
student
{
name: 'Kate Monster',
addresses : [
{ street: '123 Sesame St', city: 'Anytown', cc: 'USA' },
{ street: '123 Avenue Q', city: 'New York', cc: 'USA' }
]
}
Gibi student
/ course
Yukarıdaki örnekte.
Günlük mesajları gibi birden çok çizgi için uygundur.
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
}
Gerçekte, a host
, a'nın ebeveynidir logmsg
. Referanslanma host
id günlük mesajlarını squillions olduğu göz önüne alındığında fazla yer kazandırır.
Referanslar:
Gönderen Küçük MongoDB Kitabı
Birleştirme kullanmanın bir başka alternatifi de verilerinizi normalden farklı hale getirmektir. Tarihsel olarak, normalden arındırma performansa duyarlı kod için veya verilerin ne zaman anlık görüntülenmesi gerektiği (bir denetim günlüğünde olduğu gibi) için ayrılmıştı. Bununla birlikte, çoğu birleşme içermeyen NoSQL'in gittikçe artan popülaritesi ile normal modellemenin bir parçası olarak normal olmayanlaştırma giderek yaygınlaşmaktadır. Bu, her belgedeki her bilgiyi kopyalamanız gerektiği anlamına gelmez. Ancak, yinelenen veri korkusunun tasarım kararlarınızı yönlendirmesine izin vermek yerine, verilerinizi hangi bilgilerin hangi belgeye ait olduğuna göre modellemeyi düşünün.
Yani,
student
{
_id: ObjectId(...),
name: 'Jane',
courses: [
{
name: 'Biology 101',
mark: 85,
id:bio101
},
]
}
RESTful API verisi ise, kurs kimliğini kurs kaynağına giden bir GET bağlantısıyla değiştirin
ForeignKey'in amacı, alan değeri ForeignKey ile eşleşmiyorsa veri oluşturulmasını önlemektir. Bunu MongoDB'de başarmak için veri tutarlılığını sağlayan Schema ara yazılımlarını kullanıyoruz.
Lütfen belgelere bir göz atın. https://mongoosejs.com/docs/middleware.html#pre