মঙ্গোডিবি সম্পর্ক: এম্বেড বা রেফারেন্স?


524

আমি মঙ্গোডিবিতে নতুন - একটি সম্পর্কিত ডেটাবেস ব্যাকগ্রাউন্ড থেকে এসেছি। আমি কিছু মন্তব্য সহ একটি প্রশ্ন কাঠামো ডিজাইন করতে চাই, তবে মন্তব্যের জন্য কোন সম্পর্কটি ব্যবহার করতে হবে তা আমি জানি না: embedবা reference?

স্ট্যাকওভারফ্লোর মতো কিছু মন্তব্য সহ একটি প্রশ্নের এই জাতীয় কাঠামো থাকবে:

Question
    title = 'aaa'
    content = bbb'
    comments = ???

প্রথমে, আমি এম্বেড করা মন্তব্যগুলি ব্যবহার করতে চাই (আমার মনে embedহয় মঙ্গোডিবিতে প্রস্তাবিত), এর মতো:

Question
    title = 'aaa'
    content = 'bbb'
    comments = [ { content = 'xxx', createdAt = 'yyy'}, 
                 { content = 'xxx', createdAt = 'yyy'}, 
                 { content = 'xxx', createdAt = 'yyy'} ]

এটি পরিষ্কার, তবে আমি এই কেসটি নিয়ে চিন্তিত: আমি যদি একটি নির্দিষ্ট মন্তব্য সম্পাদনা করতে চাই , তবে আমি কীভাবে এটির বিষয়বস্তু এবং এর প্রশ্ন পাব? কোন নেই _idআমাকে এটি যাক, কিংবা question_refআমাকে তার প্রশ্ন এটি দিন। (আমি তাই নবাগত আছি, যে আমি সেখানে ছাড়া এই কাজ করতে কোন ভাবেই যদি জানি না _idএবং question_ref।)

আমাকে কি ব্যবহার করতে হবে refনা embed? তাহলে আমাকে মন্তব্যের জন্য একটি নতুন সংগ্রহ তৈরি করতে হবে?


সমস্ত ক্ষেত্রের আইটেম একটি _ আইডি দ্বারা তৈরি করা হয়, আপনি ক্ষেত্রটি তৈরি করুন বা না করুন। সুতরাং প্রযুক্তিগতভাবে প্রতিটি মন্তব্যে একটি আইডি থাকবে।
রবি গিলফোল 5

25
@RobbieGuilfoyle true-- দেখতে না stackoverflow.com/a/11263912/347455
pennstatephil

13
আমি সংশোধন করে দাঁড়িয়েছি, ধন্যবাদ @ স্পেনস্টেটেফিল :)
রবি গিলফয়েল

4
সে হয়তো এর মানে হল যে সব নকুল বস্তু যারা এই ফ্রেমওয়ার্ক ব্যবহার একটি _id সঙ্গে তৈরি করা হয় - দেখুন নকুল subdocs
লুকা Steeb

1
মঙ্গো ডিবি সম্পর্ক শেখার জন্য একটি খুব ভাল বই হ'ল "মঙ্গোডিবি অ্যাপ্লাইড ডিজাইনের প্যাটার্নস - ও'রেলি"। প্রথম অধ্যায়, এই সিদ্ধান্ত সম্পর্কে কথা বলতে, এম্বেড বা রেফারেন্স করতে?
ফিলিপ টলেডো

উত্তর:


769

এটি একটি বিজ্ঞানের চেয়েও একটি শিল্প। স্কীমাস উপর মোঙ্গো ডকুমেন্টেশন একটি ভাল রেফারেন্স, কিন্তু এখানে কিছু জিনিস বিবেচনা করতে চলেছেন:

  • যতটা সম্ভব রাখা

    একটি ডকুমেন্ট ডাটাবেসের আনন্দ হ'ল এটি প্রচুর যোগদানগুলিকে সরিয়ে দেয়। আপনার প্রথম প্রবৃত্তিটি যতটা সম্ভব একটি একক দস্তাবেজে রাখা উচিত। কারণ মোংগোডিবি নথির কাঠামো রয়েছে এবং কারণ আপনি সেই কাঠামোর মধ্যে দক্ষতার সাথে জিজ্ঞাসা করতে পারেন (এর অর্থ এটি যে নথির আপনার প্রয়োজনীয় অংশটি নিতে পারেন তাই নথির আকার আপনাকে খুব বেশি চিন্তিত করা উচিত নয়) এর মতো ডেটা স্বাভাবিক করার কোনও তাত্ক্ষণিক প্রয়োজন নেই আপনি এসকিউএল করতে হবে। বিশেষত যে কোনও ডেটা যা তার মূল দস্তাবেজ বাদে কার্যকর না হয় সেগুলি একই দস্তাবেজের অংশ হওয়া উচিত।

  • পৃথক তথ্য যা একাধিক স্থান থেকে তার নিজস্ব সংগ্রহের মধ্যে উল্লেখ করা যেতে পারে।

    এটি এতটা "স্টোরেজ স্পেস" সমস্যা নয় কারণ এটি একটি "ডেটা ধারাবাহিকতা" ইস্যু। যদি অনেকগুলি রেকর্ড একই ডেটাতে উল্লেখ করে তবে এটি একটি দক্ষ রেকর্ড আপডেট করার জন্য আরও কার্যকরী এবং কম ত্রুটিযুক্ত এবং এটি অন্য স্থানে রেফারেন্স রাখে।

  • নথি আকার বিবেচনা

    মঙ্গোডিবি একক নথিতে একটি 4MB (1.8 সহ 16MB) আকার সীমাবদ্ধ করে। জিবি ডেটা বিশ্বে এটি ছোট মনে হয় তবে এটি 30 হাজার টুইট বা 250 টিপিক্যাল স্ট্যাক ওভারফ্লো উত্তর বা 20 ফ্লিকার ফটো is অন্যদিকে, এটি একটি সাধারণ ওয়েব পৃষ্ঠায় একবারে উপস্থাপন করতে চাইতে পারে তার চেয়ে অনেক বেশি তথ্য। আপনার প্রশ্নগুলি কী আরও সহজ করে তুলবে তা প্রথমে বিবেচনা করুন। অনেক ক্ষেত্রে নথির আকারগুলির বিষয়ে উদ্বেগ অকালীন অপটিমাইজেশন হতে পারে।

  • জটিল তথ্য কাঠামো:

    মঙ্গোডিবি নির্বিচারে গভীর নেস্টেড ডেটা স্ট্রাকচার সঞ্চয় করতে পারে তবে তাদের দক্ষতার সাথে অনুসন্ধান করতে পারে না। যদি আপনার ডেটা গাছ, বন বা গ্রাফ গঠন করে তবে আপনাকে কার্যকরভাবে প্রতিটি নোড এবং এর প্রান্তগুলি একটি পৃথক নথিতে সংরক্ষণ করতে হবে। (মনে রাখবেন যে এই ধরণের ডেটাগুলির জন্য বিশেষভাবে ডিজাইন করা ডেটা স্টোর রয়েছে যা একটিরও বিবেচনা করা উচিত)

    কোনও নথিতে উপাদানগুলির একটি উপসেট ফেরানো অসম্ভবের চেয়ে এটিও চিহ্নিত করা হয়েছে । আপনার যদি প্রতিটি নথির কয়েকটি বিট বাছাই এবং চয়ন করতে হয় তবে এগুলি আলাদা করে রাখা সহজ হবে।

  • ডেটা ধারাবাহিকতা

    মঙ্গোডিবি দক্ষতা এবং ধারাবাহিকতার মধ্যে একটি বাণিজ্য বন্ধ করে দেয়। নিয়মটি হ'ল একক নথিতে পরিবর্তনগুলি সর্বদা পারমাণবিক, যখন একাধিক নথির আপডেটগুলি কখনই পরমাণু বলে ধরে নেওয়া উচিত নয়। সার্ভারে একটি রেকর্ড "লক" করার কোনও উপায় নেই (উদাহরণস্বরূপ "লক" ক্ষেত্রটি ব্যবহার করে আপনি এটি ক্লায়েন্টের যুক্তিতে তৈরি করতে পারেন)। আপনি যখন আপনার স্কিমা ডিজাইন করেন আপনি কীভাবে আপনার ডেটা সামঞ্জস্য রাখবেন তা বিবেচনা করুন। সাধারণত, আপনি কোনও নথিতে যত বেশি রাখবেন তত ভাল।

আপনি যা বর্ণনা করছেন তার জন্য, আমি মন্তব্যগুলি এম্বেড করব এবং প্রতিটি মন্তব্যকে একটি অবজেক্টআইডি দিয়ে একটি আইডি ক্ষেত্র দেব। অবজেক্টআইডিটিতে একটি সময় স্ট্যাম্প এম্বেড থাকে যাতে আপনি এটি পছন্দ না করে তৈরির পরিবর্তে এটি ব্যবহার করতে পারেন।


1
আমি ওপি প্রশ্নের সাথে যুক্ত করতে চাই: আমার মন্তব্যগুলির মডেলটিতে তার ব্যবহারকারীর নাম এবং তার অবতারের লিঙ্ক রয়েছে। কোন ব্যবহারকারী তার নাম / অবতারটি সংশোধন করতে পারে তা বিবেচনা করে সেরা পন্থাটি কী হবে?
ব্যবহারকারী1102018

4
'কমপ্লেক্স ডেটা স্ট্রাকচার' সম্পর্কিত, একত্রিতকরণ কাঠামো ব্যবহার করে দস্তাবেজের একটি উপাদানের একটি উপসেট ফেরানো সম্ভব বলে মনে হয় (চেষ্টা করুন w ​​আনইন্ডাইন্ড)।
ইয়াল রথ

3
ত্রুটি, এই কৌশলটি হয় সম্ভাব্য ছিল না বা 2012 এর শুরুতে মঙ্গোডিবিতে ব্যাপকভাবে পরিচিত ছিল না this এই প্রশ্নের জনপ্রিয়তা দেওয়া, আমি আপনাকে নিজের আপডেট হওয়া উত্তর লিখতে উত্সাহিত করব। আমি আশঙ্কা করছি যে আমি মঙ্গোডিবিতে সক্রিয় উন্নয়ন থেকে সরে এসেছি এবং আমার মূল পোস্টে আপনাকে মন্তব্য করার পক্ষে আমি ভাল অবস্থানে নেই।
জন এফ মিলার

54
16 এমবি = 30 মিলিয়ন টুইট? মেনাসে টুইটারে প্রায় 0,5 বাইট ?!
পাওলো

8
হ্যাঁ, এটি প্রদর্শিত হচ্ছে আমি 1000 এর একটি ফ্যাক্টর দ্বারা বন্ধ ছিলাম এবং কিছু লোক এটি গুরুত্বপূর্ণ মনে করেন। আমি পোস্টটি সম্পাদনা করব। টুইটারে ডাব্লুআরটি 560 বিটস, যখন আমি 2011 এ এটি রোট করেছি তখনও টুইটারটি টেক্সট বার্তাগুলিতে এবং রুবি ১.৪ স্ট্রিংয়ের সাথে আবদ্ধ ছিল; অন্য কথায় এখনও ASCII অক্ষর রয়েছে rs
জন এফ। মিলার

39

সাধারণভাবে, সত্তার মধ্যে যদি আপনার এক থেকে এক বা একের সাথে অনেকগুলি সম্পর্ক থাকে তবে এম্বেডটি ভাল, যদি আপনার একাধিক থেকে বহু সম্পর্ক থাকে তবে রেফারেন্স ভাল।


9
আপনি দয়া করে একটি রেফারেন্স লিঙ্ক যুক্ত করতে পারেন? ধন্যবাদ।
db80

একের অনেকের এই নকশার সাথে আপনি কীভাবে একটি নির্দিষ্ট মন্তব্য খুঁজে পেতে পারেন?
মৌরিসিও পাস্তোরিনি


29

আমি যদি একটি নির্দিষ্ট মন্তব্য সম্পাদনা করতে চাই তবে কীভাবে এটির বিষয়বস্তু এবং এর প্রশ্ন পাওয়া যায়?

আপনি উপ-নথি দ্বারা ক্যোয়ারী পারেন: db.question.find({'comments.content' : 'xxx'})

এটি পুরো প্রশ্ন দলিলটি ফিরিয়ে দেবে। নির্দিষ্ট মন্তব্য সম্পাদনা করতে, আপনাকে তারপরে ক্লায়েন্টের মন্তব্যটি খুঁজে পেতে হবে, সম্পাদনা করতে হবে এবং এটি ডিবিতে সংরক্ষণ করতে হবে।

সাধারণভাবে, যদি আপনার নথিতে কোনও অবজেক্টের অ্যারে থাকে, আপনি দেখতে পাবেন যে সেই সাব-অবজেক্টগুলিকে ক্লায়েন্টের দিকটি পরিবর্তন করতে হবে।


4
দুটি মন্তব্যে অভিন্ন বিষয়বস্তু থাকলে এটি কাজ করবে না। কারও যুক্তি হতে পারে যে আমরা অনুসন্ধানের ক্যোয়ারে লেখককে যুক্ত করতে পারি, যা লেখক একই বিষয়বস্তু নিয়ে দুটি অভিন্ন মন্তব্য করলে
স্টিল ব্রেন

@ স্টিলব্রেন: যদি তিনি মন্তব্য সূচকটি রাখেন, তবে ডট নোটেশন সাহায্য করতে পারে। দেখতে stackoverflow.com/a/33284416/1587329
serv-Inc

13
আমি বুঝতে পারছি না যে এই উত্তরটির 34 টি আপোভেট রয়েছে, দ্বিতীয় একাধিক লোক একই জিনিসটিকে পুরো সিস্টেমটি ভেঙে ফেলার মন্তব্য করে। এটি একেবারে ভয়ানক নকশা এবং কখনও ব্যবহার করা উচিত নয়।
@ ব্যবহারকারী

21

ঠিক আছে, আমি কিছুটা দেরি করেছি তবুও আমার স্কিমা তৈরির পদ্ধতিটি ভাগ করে নিতে চাই।

আমার কাছে এমন সমস্ত কিছুর জন্য স্কিমা রয়েছে যা কোনও শব্দ দ্বারা বর্ণিত হতে পারে, যেমন আপনি এটি ক্লাসিকাল ওওপিতে করেন।

ই জি

  • মন্তব্য
  • হিসাব
  • ব্যবহারকারী
  • ব্লগ পোস্ট
  • ...

প্রতিটি স্কিমা ডকুমেন্ট বা সাবডোকামেন্ট হিসাবে সংরক্ষণ করা যায়, তাই আমি প্রতিটি স্কিমার জন্য এটি ঘোষণা করি।

দস্তাবেজ:

  • রেফারেন্স হিসাবে ব্যবহার করা যেতে পারে। (উদাহরণস্বরূপ ব্যবহারকারী একটি মন্তব্য করেছেন -> মন্তব্যে ব্যবহারকারী দ্বারা "রেফারেন্স" দেওয়া হয়েছে)
  • আপনার আবেদনে একটি "রুট"। (যেমন ব্লগপোস্ট -> ব্লগপোস্ট সম্পর্কে একটি পৃষ্ঠা রয়েছে)

Subdocument:

  • কেবল একবার ব্যবহার করা যায় / কখনই কোনও রেফারেন্স হয় না। (যেমন মন্তব্য ব্লগপোস্টে সংরক্ষিত হয়েছে)
  • আপনার অ্যাপ্লিকেশনটিতে কখনই "রুট" হয় না। (মন্তব্যটি কেবল ব্লগপোস্ট পৃষ্ঠায় প্রদর্শিত হবে তবে পৃষ্ঠাটি এখনও ব্লগপোস্ট সম্পর্কে রয়েছে)

20

আমি নিজেই এই প্রশ্নটি গবেষণা করার সময় এই ছোট উপস্থাপনাটি জুড়ে এসেছি। আমি এটি কতটা সঠিকভাবে রেখেছি তা অবাক করেছিলাম, তথ্য এবং এর উপস্থাপনা উভয়ই।

http://openmymind.net/Multiple-Collections-Versus-Embedded-Documents

এটি সংক্ষিপ্তসার:

একটি সাধারণ নিয়ম হিসাবে, আপনার যদি অনেকগুলি [চাইল্ড ডকুমেন্ট] থাকে বা সেগুলি বড় হয় তবে একটি পৃথক সংগ্রহ সেরা হতে পারে।

ছোট এবং / বা কম ডকুমেন্ট এম্বেড করার জন্য একটি প্রাকৃতিক ফিট হয়ে থাকে।


11
কত a lot? 3? 10? 100? কি large? 1kb? 1MB? 3 ক্ষেত্র? 20 মাঠ? কি smaller/ fewer?
ট্র্যাকসো

1
এটি একটি ভাল প্রশ্ন এবং এর একটির কাছে আমার কাছে নির্দিষ্ট উত্তর নেই। একই উপস্থাপনায় একটি স্লাইড অন্তর্ভুক্ত ছিল যা বলেছিল "তার সমস্ত এমবেডড ডকুমেন্টস এবং অ্যারে সহ একটি ডকুমেন্ট ১M এমবি ছাড়িয়ে যেতে পারে না", এটি আপনার কাটফট হতে পারে, বা আপনার নির্দিষ্ট পরিস্থিতির জন্য যুক্তিসঙ্গত / আরামদায়ক বলে মনে হয় কেবল তা নিয়ে যান। আমার বর্তমান প্রকল্পে, এম্বেড করা বেশিরভাগ দলিলই 1: 1 টি সম্পর্কের জন্য বা 1: অনেকগুলি এম্বেড থাকা নথিগুলি সত্যই সহজ।
ক্রিস ব্লুম 21

@ জন-এফ-মিলার দ্বারা বর্তমান শীর্ষ মন্তব্যটি দেখুন, যেখানে একটি থ্রেশহোল্ডের জন্য নির্দিষ্ট সংখ্যা সরবরাহ না করে এমন কিছু অতিরিক্ত পয়েন্টার রয়েছে যা আপনার সিদ্ধান্তকে গাইড করতে সহায়তা করবে।
ক্রিস ব্লুম 21

16

আমি জানি এটি বেশ পুরানো তবে আপনি যদি কেবলমাত্র নির্দিষ্ট মন্তব্যটি কীভাবে প্রত্যাবর্তন করতে পারেন সে বিষয়ে ওপি-র প্রশ্নের উত্তর খুঁজছেন, আপনি এই জাতীয় query (ক্যোয়ারী) অপারেটরটি ব্যবহার করতে পারেন :

db.question.update({'comments.content': 'xxx'}, {'comments.$': true})

4
দুটি মন্তব্যে অভিন্ন বিষয়বস্তু থাকলে এটি কাজ করবে না। কারও যুক্তি হতে পারে যে আমরা অনুসন্ধানের অনুসন্ধানে লেখককে যুক্ত করতে পারি, যা লেখক একই বিষয়বস্তু নিয়ে দুটি অভিন্ন মন্তব্য করলে
স্টিল ব্রেন

1
@ স্টিলব্রেন: স্যার ভাল খেলেছে, ভাল খেলেছে।
জ্যাকস্ট্রং

12

হ্যাঁ, আমরা শুধু মত অন্য নথি পূরণ document.To রেফারেন্স ব্যবহার করতে পারেন SQL আমি joins.In মোঙ্গো ডিবি তারা আছে আত অনেক সম্পর্ক document.Instead করার ম্যাপিং এক যে আমরা ব্যবহার করতে যোগদান করে জনপূর্ণ আমাদের দৃশ্যকল্প সংসাধন ..

var mongoose = require('mongoose')
  , Schema = mongoose.Schema

var personSchema = Schema({
  _id     : Number,
  name    : String,
  age     : Number,
  stories : [{ type: Schema.Types.ObjectId, ref: 'Story' }]
});

var storySchema = Schema({
  _creator : { type: Number, ref: 'Person' },
  title    : String,
  fans     : [{ type: Number, ref: 'Person' }]
});

জনসংখ্যা হ'ল ডকুমেন্টের নির্দিষ্ট পাথগুলিকে অন্য সংগ্রহ (গুলি) থেকে নথি (গুলি) দিয়ে স্বয়ংক্রিয়ভাবে প্রতিস্থাপনের প্রক্রিয়া। আমরা একটি একক দস্তাবেজ, একাধিক নথি, প্লেইন অবজেক্ট, একাধিক প্লেইন অবজেক্টস বা সমস্ত বস্তু একটি কোয়েরি থেকে ফিরিয়ে আনতে পারি। আসুন কিছু উদাহরণ তাকান।

আরও ভাল আপনি আরও তথ্য পেতে পারেন দয়া করে এখানে যান: http://mongoosejs.com/docs/populate.html


5
মোঙ্গুজ প্রতিটি জনবহুল ক্ষেত্রের জন্য পৃথক অনুরোধ জানাবে। এটি সার্ভারে সঞ্চালিত হওয়ার সাথে সাথে এটি এসকিউএল জোনেসের থেকে আলাদা। এর মধ্যে অ্যাপ্লিকেশন সার্ভার এবং মংডোব সার্ভারের মধ্যে অতিরিক্ত ট্র্যাফিক রয়েছে। আবার আপনি যখন অনুকূলিত হন তখন আপনি এটি বিবেচনা করতে পারেন। তবুও, আপনার অ্যাঞ্জার এখনও সঠিক।
সর্বোচ্চ

6

প্রকৃতপক্ষে, আমি বেশ কৌতূহলী কেন কেউ ইউএমএল স্পেসিফিকেশন সম্পর্কে কথা বলেনি। থাম্বের একটি নিয়ম হ'ল যদি আপনার একত্রিত হয়, তবে আপনার উল্লেখগুলি ব্যবহার করা উচিত। তবে যদি এটি কোনও রচনা হয় তবে মিলনটি আরও শক্তিশালী এবং আপনার এমবেডড ডকুমেন্টগুলি ব্যবহার করা উচিত।

এবং আপনি কেন তা যুক্তিযুক্ত তাড়াতাড়ি বুঝতে পারবেন। যদি কোনও পিতামাতার স্বাধীনভাবে অস্তিত্ব থাকতে পারে তবে পিতামাতার অস্তিত্ব না থাকলেও আপনি এটি অ্যাক্সেস করতে চাইবেন। যেহেতু আপনি কেবল এটি অ-বিদ্যমান পিতামাতার মধ্যে এম্বেড করতে পারবেন না, আপনাকে এটির নিজস্ব ডেটা কাঠামোতে লাইভ করতে হবে। এবং যদি কোনও পিতামাতার উপস্থিতি থাকে তবে কেবল তাদের পিতামাতার মধ্যে অবজেক্টের একটি রেফ যোগ করে তাদেরকে যুক্ত করুন।

সত্যিই জানেন না যে দুটি সম্পর্কের মধ্যে পার্থক্য কী? এখানে তাদের ব্যাখ্যা করার জন্য একটি লিঙ্ক রয়েছে: ইউএমএলে সংঘবদ্ধ বনাম রচনা


কেন -1? দয়া করে একটি ব্যাখ্যা দিন যা কারণটি পরিষ্কার করে দেবে
Bonjour123


1

যদি আমি একটি নির্দিষ্ট মন্তব্য সম্পাদনা করতে চাই তবে আমি কীভাবে এটির বিষয়বস্তু এবং এর প্রশ্ন পাব?

আপনি যদি মন্তব্যগুলির সংখ্যা এবং যে মন্তব্যটি পরিবর্তন করতে চেয়েছিলেন তার সূচি যদি ট্র্যাক করে রাখেন তবে আপনি ডট অপারেটর ( এসও উদাহরণ ) ব্যবহার করতে পারেন ।

আপনি f.ex. করতে পারেন

db.questions.update(
    {
        "title": "aaa"       
    }, 
    { 
        "comments.0.contents": "new text"
    }
)

(প্রশ্নের ভিতরে মন্তব্যগুলি সম্পাদনা করার অন্য উপায় হিসাবে)

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.