giriiş
MongoDB ve Mongoose'da, belgeler arasındaki ilişkileri yönetmek, ölçeklenebilir ve verimli bir veri modeli tasarlamanın önemli bir parçasıdır. Tablo ve yabancı anahtar kullanan ilişkisel veritabanlarının aksine, MongoDB, ilgili verileri belgelere yerleştirme veya koleksiyonlardaki verilere referans verme arasında seçim yapmanıza olanak tanır. Her yaklaşımın kendine özgü avantajları ve dezavantajları vardır ve doğru seçim, uygulamanızın yapısına ve gereksinimlerine bağlıdır.
Bu kılavuzda, Mongoose'da ilişkileri etkili bir şekilde modellemenize yardımcı olacak pratik örneklerle birlikte, verileri ne zaman gömeceğinizi ve ne zaman bunlara başvuracağınızı tartışacağız.
MongoDB'deki İlişkileri Anlama
MongoDB, veri ilişkilerini yönetmede esneklik sunan bir NoSQL veritabanıdır. MongoDB'de ilişkileri iki temel şekilde tasarlayabilirsiniz:
- Gömme: İlgili verileri bir belgede depolamak.
- Referanslama: İlgili verileri ayrı bir koleksiyonda saklayın ve referansları (ObjectId'ler) kullanarak bunları birbirine bağlayın.
Gömme ve referanslama arasındaki seçim, veri erişim modellerine, belge boyutuna, uyumluluk gereksinimlerine ve ilgili verilerin güncellenme sıklığına bağlıdır.
1. Belgeleri Yerleştirme
Gömme, ilgili verilerin doğrudan ana belgede iç içe geçmiş bir nesne veya dizi olarak depolanmasını içerir. Bu, sıklıkla birlikte erişilen ve bire çok veya bire çok ilişkisi olan veriler için idealdir.
Gömmenin faydaları
- Tek belgeye erişim: Tüm veriler tek bir belgede yer aldığından birleştirme veya ek isteklere olan ihtiyaç azalır.
- Atomik işlemler: Güncellemeler ve okumalar atomik olduğundan veri tutarlılığını korumak daha kolaydır.
- Hızlı okuma fonksiyonu: İlgili veriler bir arada saklandığı için belge alımı daha hızlı olur ve ek veritabanı çağrıları önlenir.
Yerleştirme kısıtlamaları
- Belge boyut sınırı: MongoDB belgelerinin boyutu 16 MB ile sınırlıdır. Büyük iç içe diziler bu sınıra hızla yaklaşabilir.
- Güncellemede tekrar: Belgelerdeki iç içe geçmiş verilerin güncellenmesi, veri çoğaltılmasına ve potansiyel tutarsızlıklara yol açabilir.
- Sınırlı esneklik: Gömülü belgeler, özellikle veriler zamanla artıyorsa, ilişkileri sorgulamak için daha az esnektir.
Örnek: Bir blog yazısına yorum yerleştirme
Bir blog uygulamasında, yorumlar yazıyla tamamen ilişkili olduğundan yorumları doğrudan yazı belgesine gömebilirsiniz.
const mongoose = require("mongoose");
const commentSchema = new mongoose.Schema({
user: { type: String, required: true },
message: { type: String, required: true },
date: { type: Date, default: Date.now }
});
const postSchema = new mongoose.Schema({
title: { type: String, required: true },
content: { type: String, required: true },
comments: [commentSchema] // Embedding comments in the post
});
const Post = mongoose.model("Post", postSchema);Bu kurulumda, her gönderi belgesi bir dizi yorum içerir; bu da gönderiyi ve yorumlarını tek bir sorguda almayı kolaylaştırır.
2. Referans Belgeleri
Referans (veya normalizasyon), ilgili verileri ayrı koleksiyonlarda depolar ve bunları birbirine bağlamak için ObjectId'leri kullanır. Bu, büyük veri kümeleri için veya ilgili verilerin bağımsız olarak sorgulanması gerektiğinde idealdir.
Yönlendirmenin Faydaları
- Verilerin yeniden kullanılabilirliği: Kullanıcı profilleri gibi paylaşılan verilerin yalnızca bir kez depolanması gerekir ve birden fazla belge tarafından referans alınabilir.
- Belge boyutunu azaltın: Referanslama, belge boyutunu küçük tutar ve büyük iç içe geçmiş yapıların oluşmasını önler.
- Ölçeklenebilirlik: Referanslar, veriler büyüdükçe esneklik sağlar ve çoktan çoğa ilişkileri daha verimli bir şekilde yönetmenize olanak tanır.
Yönlendirme kısıtlamaları
- Çoklu sorgular: İlgili verileri almak ek sorgular veya doldurma işlemleri gerektirir, bu da yanıt süresini artırabilir.
- Uyumluluk zorlukları: Ayrı belgelerin ayrı ayrı güncellenmesi gerekir; bu da veri tutarsızlıklarına yol açabilir.
- Karmaşıklık: Referanslar, ilişkileri yönetmek ve veri bütünlüğünü sağlamak için daha fazla karmaşıklık getirir.
Örnek: Bir blog yazısında yazar atıfı ve yorumlar
Daha karmaşık kurulumlarda, yazarları ve yorumları ayrı koleksiyonlarda saklayabilir ve bunlara gönderi belgesinde başvurabilirsiniz.
const authorSchema = new mongoose.Schema({
name: String,
bio: String
});
const commentSchema = new mongoose.Schema({
userId: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
message: String,
date: { type: Date, default: Date.now }
});
const postSchema = new mongoose.Schema({
title: String,
content: String,
author: { type: mongoose.Schema.Types.ObjectId, ref: "Author" },
comments: [{ type: mongoose.Schema.Types.ObjectId, ref: "Comment" }]
});
const Author = mongoose.model("Author", authorSchema);
const Comment = mongoose.model("Comment", commentSchema);
const Post = mongoose.model("Post", postSchema);Bu kurulumda, Post modeli Yazar ve Yorum belgelerine ObjectId'leri kullanarak başvurur. Bu yaklaşım, gönderilerden bağımsız olarak yorumlara ve yazarlara erişmesi veya bunları güncellemesi gerekebilecek uygulamalar için en uygunudur.
Referansların doldurulması
Başvurulan verileri almak için Mongoose'un fill metodunu kullanabilirsiniz.
const post = await Post.findById(postId)
.populate("author")
.populate("comments");Bu belge, gönderiyi tam yazar ve yorum belgeleriyle birlikte alır ve gönderinin, yazarının ve yorumların tam bir görünümünü sağlar.
Hibrit yaklaşım: yerleştirme ve referanslamayı birleştirme
Karmaşık uygulamalarda, belirli verileri yerleştirip diğerlerine referans verdiğiniz hibrit bir yaklaşıma ihtiyaç duyabilirsiniz. Örneğin, bir e-ticaret uygulamasında, ürün bilgilerini bir siparişe yerleştirip müşteri bilgilerine referans verebilirsiniz.
Örnek: Ürünleri yerleştirme ve müşterileri bir siparişe yönlendirme
const productSchema = new mongoose.Schema({
productId: mongoose.Schema.Types.ObjectId,
name: String,
price: Number,
quantity: Number
});
const orderSchema = new mongoose.Schema({
customer: { type: mongoose.Schema.Types.ObjectId, ref: "Customer" },
products: [productSchema], // Embedding products
orderDate: { type: Date, default: Date.now }
});
const Order = mongoose.model("Order", orderSchema);Bu örnekte:
- Müşteriye yönlendirilir çünkü çok sayıda siparişi olabilir ve bağımsız olarak sorgulanabilir.
- Ürünler, her bir siparişle doğrudan ilişkili oldukları için siparişin içine yerleştirilmiştir.
Bu yaklaşım, sık erişilen verileri bir arada tutarken, daha karmaşık ilişkilerin ayrı ayrı yönetilmesine olanak tanır.
Sonuç
Mongoose'da yerleştirme ve referanslama ile ilişki yönetimi, MongoDB'de verimli veri modelleri tasarlamak için esneklik sağlar. Yerleştirme, yakından ilişkili veriler ve bire çok ilişkiler için iyi çalışırken, referanslama daha büyük, sık güncellenen ilişkiler veya çoktan çoğa ilişkiler için daha iyidir.
Her yaklaşımın güçlü ve zayıf yönlerini anlayarak ve veri erişim kalıpları, belge boyutu gibi faktörleri göz önünde bulundurarak,
ve güncelleme sıklığını ayarlayarak, hem ölçeklenebilir hem de verimli bir MongoDB şeması tasarlayabilirsiniz. İlişkileri etkili bir şekilde yönetmek ve sağlam, sürdürülebilir veri modelleri oluşturmak için bu stratejileri Mongoose uygulamalarınızda uygulayın.









