SQL-এ অভ্যস্ত মাথা MongoDB-তে প্রথম যে ভুলটা করে, তা হলো টেবিলের মতো করে collection ভাগ করা - users আলাদা, orders আলাদা, তারপর প্রতিবার JOIN-এর মতো করে মেলানো। MongoDB-র দর্শন উল্টো: যেই data একসাথে পড়া হয়, সেটা একসাথে রাখুন। কারণ MongoDB-তে JOIN ব্যয়বহুল, কিন্তু একটা document পড়া খুব সস্তা।
Embed - ভিতরে রেখে দেওয়া
Order-এর ভিতরে তার items-গুলো array আকারে রেখে দিন। Order পড়তে গেলেই items সাথে আসবে, আলাদা query লাগবে না। Embed ভালো যখন: ভিতরের data বাইরে একা কখনো দরকার হয় না, সংখ্যায় সীমিত থাকে, আর মূল document-এর সাথেই বদলায়। Address, order items, blog post-এর tags - এরা embed-এর ভালো প্রার্থী।
// embed - order-এর ভিতরেই items
{
_id: "order_101",
userId: "user_7",
status: "delivered",
items: [
{ productId: "p1", name: "Chicken Biryani", qty: 2, price: 220 },
{ productId: "p2", name: "Borhani", qty: 2, price: 60 }
],
total: 560
}Reference - শুধু id রেখে দেওয়া
কিন্তু product-এর পুরো তথ্য order-এ embed করা যাবে না - product-এর দাম বদলায়, বর্ণনা বদলায়, আর সেটা হাজার order-এ ছড়িয়ে থাকলে আপডেট করা দুঃস্বপ্ন। যেই data নিজে স্বাধীন, অনেক জায়গা থেকে ব্যবহার হয়, বা সীমাহীন বাড়তে পারে (যেমন একটা post-এর comments লক্ষ ছাড়াতে পারে) - সেখানে শুধু id reference রাখুন। উপরের উদাহরণেই দেখুন, item-এর ভিতরে product-এর দামের একটা snapshot রাখা হয়েছে ইচ্ছা করেই - কারণ order-এর সময়ের দামটাই ইতিহাস, পরে দাম বদলালেও পুরনো order বদলাবে না।
সিদ্ধান্তের সহজ প্রশ্নটা এই: 'এই data-টা কি মূল জিনিসটা ছাড়া কখনো আলাদা করে দরকার হবে? আর এটা কি সীমাহীন বাড়তে পারে?' দুটোর যেকোনো একটার উত্তর হ্যাঁ হলে reference, নইলে embed।
সবাই যে ভুলটা করে
দুই চরমই ভুল: SQL-এর মতো সব ভাগ করে ফেলা (তাহলে MongoDB নেওয়ার সুবিধাই পেলেন না), আবার সবকিছু এক document-এ ঢুকিয়ে দেওয়া (document বিশাল হয়ে যায়, MongoDB-র 16MB সীমায় ধাক্কা খেতে হয়, আর একই data অনেক জায়গায় duplicate হয়ে আপডেটে গণ্ডগোল হয়)।
আজকের Practice
Khabar Dhandha-র কথা ভেবে menu আর order-এর MongoDB schema কাগজে আঁকুন। প্রতিটা সিদ্ধান্তের পাশে এক লাইনে কারণ লিখুন - কোনটা embed, কোনটা reference, কেন। তারপর schema-টা Mongoose দিয়ে কোডে নামান।
Interview-এ কীভাবে বলবেন
MongoDB-তে আমি schema design করি পড়ার ধরন দেখে - যেই data একসাথে পড়া হয়, তা embed করি; যেটা স্বাধীনভাবে বদলায় বা সীমাহীন বাড়তে পারে, তা reference রাখি। SQL-এর normalization এখানে হুবহু চলে না, কারণ এখানে JOIN ব্যয়বহুল আর document পড়া সস্তা।