নকল মোঙ্গো অবজেক্টআইডির দুটি পৃথক সংকলনে নকল হওয়ার সম্ভাবনা?


187

দু'টি পৃথক সংকলনে কোনও একই দস্তাবেজের জন্য একই সঠিক মঙ্গো অবজেক্টআইডি তৈরি করা সম্ভব? আমি বুঝতে পারি যে এটি অবশ্যই খুব অসম্ভব, তবে এটি কি সম্ভব?

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

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

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

আমি বিষয়টিকে সহজতর করার জন্য কেবলমাত্র নতুন নির্বাচিত অফিসার অবজেক্টআইড হিসাবে নতুন ব্যবহারকারীর অবজেক্টআইডকে নির্দিষ্ট করে বিবেচনা করছি কিন্তু এটি নিশ্চিত করতে চেয়েছিলাম যে কোনও বিদ্যমান ব্যবহারকারীর সাথে সংঘর্ষ হওয়া সম্ভব নয়।

আপনার অন্তর্দৃষ্টি জন্য ধন্যবাদ।

সম্পাদনা: এই প্রশ্নটি পোস্ট করার অল্প সময়ের পরে, আমি বুঝতে পারি যে আমার প্রস্তাবিত সমাধান খুব ভাল ধারণা নয় n't কেবলমাত্র আমাদের বর্তমান স্কিমাটি ঠিক রাখা এবং ব্যবহারকারীর নথিতে নির্বাচিত কর্মকর্তা '_আইডির' সাথে লিঙ্ক করা ভাল।



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

1
2 বাইট প্রসেস আইডি হ'ল অবজেক্টআইডি তৈরির প্রক্রিয়াটির পিড। উদাহরণ হিসাবে, পাইমোঙ্গো কোডটি এখানে অবজেক্টআইডি তৈরি করতে ব্যবহার করে: github.com/mongodb/mongo-python-driver/blob/master/bson/…
mstearn

আমি যে দৌড়ে গেলাম তা ব্যাচ সন্নিবেশ করানো। আমি 10 কে ডকুমেন্টের ব্যাচগুলি তৈরি করছিলাম এবং প্রতিবার সংঘর্ষ করছিলাম কারণ প্রতিবারের মতো পাল্টা অংশটি ঘূর্ণিত হয়েছিল।
22-25

আমি জানি এটি কিছুক্ষন হয়ে গেছে, তবে 10 কে ডকুমেন্টগুলি কাউন্টারে ঘুরবে না। কাউন্টার অংশটি তিন অঙ্ক নয়, তিনটি বাইট is এটি 16 মিলিয়নেরও বেশি।
অস্যা কামস্কি

উত্তর:


318

সংক্ষিপ্ত উত্তর

কেবলমাত্র আপনার প্রাথমিক প্রশ্নের সরাসরি প্রতিক্রিয়া যুক্ত করার জন্য: হ্যাঁ, আপনি যদি BSON অবজেক্ট আইডি জেনারেশন ব্যবহার করেন তবে বেশিরভাগ ড্রাইভারের জন্য আইডিগুলি অবশ্যই সংগ্রহের মধ্যে অনন্য হয়ে উঠবে। "প্রায় অবশ্যই" অর্থ কি জন্য নীচে দেখুন।

দীর্ঘ উত্তর

মোঙ্গো ডিবি চালকদের দ্বারা উত্পাদিত BSON অবজেক্ট আইডি সংগ্রহের ক্ষেত্রে অনন্য হওয়ার সম্ভাবনা রয়েছে। এটি মূলত আইডিটির শেষ 3 বাইটের কারণে, যা বেশিরভাগ ড্রাইভারের জন্য একটি স্ট্যাটিক ইনক্রিমেন্টিং কাউন্টারের মাধ্যমে তৈরি করা হয়। যে কাউন্টারটি সংগ্রহ-স্বতন্ত্র; এটি বিশ্বব্যাপী উদাহরণস্বরূপ, জাভা ড্রাইভার একটি এলোমেলোভাবে সূচনাযুক্ত, স্ট্যাটিক অ্যাটমিকআইন্টিজার ব্যবহার করে।

তাহলে কেন, মঙ্গো ডক্সে, তারা কী বলে যে আইডিগুলি অনন্য হতে পারে, একেবারে বলার পরিবর্তে যে তারা অনন্য হবে? তিনটি সম্ভাবনা দেখা দিতে পারে যেখানে আপনি কোনও অনন্য আইডি পাবেন না (দয়া করে আরও কিছু আছে কিনা তা আমাকে জানান):

এই আলোচনার আগে, মনে করুন যে BSON অবজেক্ট আইডিটি রয়েছে:

[যুগের পর থেকে 4 বাইট সেকেন্ড, 3 বাইট মেশিন হ্যাশ, 2 বাইট প্রক্রিয়া আইডি, 3 বাইট কাউন্টার]

এখানে তিনটি সম্ভাবনা রয়েছে, সুতরাং আপনি নিজেরাই বিচার করুন যে ডুপু পাওয়ার সম্ভাবনা কতটা:

1) কাউন্টার ওভারফ্লো: কাউন্টারে 3 বাইট রয়েছে। আপনি যদি একই প্রক্রিয়াতে একই মেশিনে এক সেকেন্ডে 16,777,216 (2 ^ 24) এর বেশি নথি সন্নিবেশ করানোর ক্ষেত্রে ঘটে থাকেন তবে আপনি বর্ধনকারী কাউন্টার বাইটগুলি উপরি প্রবাহিত করতে পারেন এবং একই সময়ে, মেশিনকে ভাগ করে নেওয়া দুটি অবজেক্ট আইডি দিয়ে শেষ করতে পারেন , প্রক্রিয়া এবং কাউন্টার মানগুলি।

২) কাউন্টার অ-ইনক্রিমেন্টিং: কিছু মোঙ্গো ড্রাইভার কাউন্টার বাইটের জন্য নম্বর বাড়ানোর পরিবর্তে এলোমেলো সংখ্যা ব্যবহার করে। এই ক্ষেত্রে, একটি অ-অনন্য আইডি তৈরির সম্ভাবনা রয়েছে 1 / 16,777,216, তবে কেবলমাত্র যদি এই দুটি আইডি একই সেকেন্ডে উত্পন্ন হয় (যেমন পরবর্তী আইডিতে আপডেটের সময় বিভাগের আগে), একই মেশিন, একই প্রক্রিয়াতে।

3) একই মানগুলিতে মেশিন এবং প্রক্রিয়া হ্যাশ। মেশিন আইডি এবং প্রসেস আইডি মানগুলি কিছু খুব সম্ভাবনাময় দৃশ্যে দুটি ভিন্ন মেশিনের জন্য একই মানগুলিতে মানচিত্র করতে পারে। যদি এটি ঘটে থাকে এবং একই সময়ে দুটি আলাদা মেশিনের দুটি কাউন্টার একই একই দ্বিতীয় সময়ে একই মান উত্পন্ন করে, তবে আপনি একটি নকল আইডি দিয়ে শেষ করবেন।

এই তিনটি পরিস্থিতি জন্য নজর রাখা হয়। পরিস্থিতি 1 এবং 3 অত্যন্ত অসম্ভব বলে মনে হচ্ছে এবং আপনি যদি সঠিক ড্রাইভার ব্যবহার করেন তবে দৃশ্য 2 সম্পূর্ণরূপে এড়ানো যায়। নিশ্চিতভাবে জানতে আপনাকে ড্রাইভারের উত্স পরীক্ষা করতে হবে।


3 বাইটের কাউন্টারটি মেশিনের প্রতি প্রক্রিয়াতে প্রতি সেকেন্ডে সেকেন্ডে 2 ^ 24 = 16777216 সংখ্যক নথি সন্নিবেশ করার ক্ষমতাটি প্রতিনিধিত্ব করে না?
ফরেস্ট ইয়ে

আপনি একেবারে ঠিক বলেছেন, আমি দুর্ঘটনাক্রমে বিটের সংখ্যা অর্ধেক করে রেখেছি - উত্তরটি সংশোধন করা হয়েছে।
রাজ অ্যাডওয়ানি

যেহেতু আমি কেবল এটিতে পা রেখেছি, আমাকে যুক্ত করুন যে কিছু ড্রাইভার (উদাঃ সি) যদিও ইনক্রিমেন্ট ব্যবহার করে তবে পরমাণুভাবে বৃদ্ধি করে না, তাই সময় সময় এটি রেসের অবস্থার কারণে একই
অ্যাসিড

39
আপনি সম্পূর্ণরূপে এড়িয়ে ObjectIdগেছেন যে 136 বছরে আপনি মেশিনের হ্যাশ, প্রসেস আইডি, এবং কাউন্টারের
যতক্ষণ না পেরেছিলে

25
@ জামিলাক আমরা যখন জরুরি হয়ে উঠি তখন আমরা এই সমস্যাটির যত্ন নেব (যারা Y০ এর দশকে ওয়াইওয়াইএমডিডি তারিখের ফর্ম্যাটকে মানক করেছেন)
ফিলিপ

14

অবজেক্টআইডগুলি ইউআইডি-র মতো একই উপায়ে ক্লায়েন্ট-সাইড উত্পন্ন হয় তবে কোনও ডাটাবেসে সঞ্চয় করার জন্য কিছু ভাল বৈশিষ্ট্য যেমন মোটামুটি ক্রম বাড়ানো এবং বিনামূল্যে তাদের তৈরির সময় এনকোড করা। আপনার ব্যবহারের ক্ষেত্রে মূল বিষয়টি হ'ল তারা বিভিন্ন মেশিনে উত্পন্ন হলেও এমনকি উচ্চতর সম্ভাবনার স্বতন্ত্রতার গ্যারান্টি দেওয়ার জন্য এটি ডিজাইন করা হয়েছে।

এখন আপনি যদি _id ক্ষেত্রটি সাধারণভাবে উল্লেখ করছেন তবে আমাদের সংগ্রহের মধ্যে স্বতন্ত্রতার প্রয়োজন নেই তাই পুরাতন _id পুনরায় ব্যবহার করা নিরাপদ। একটি কংক্রিট উদাহরণ হিসাবে, যদি আপনার দুটি সংগ্রহ থাকে colorsএবং fruits, উভয়ের একই সাথে একটি বস্তু থাকতে পারে {_id: 'orange'}

যদি আপনি কিভাবে ObjectIds নির্মিত সম্পর্কে আরো জানতে চান, তাহলে এখানে বৈশিষ্ট হল: http://www.mongodb.org/display/DOCS/Object+IDs#ObjectIDs-BSONObjectIDSpecification


11

যদি কারও সদৃশ মঙ্গো অবজেক্টআইডিগুলিতে সমস্যা হয়, আপনার জানা উচিত যে মঙ্গোতে নিজেই দ্বিধাগ্রস্থ হওয়ার সম্ভাবনা থাকা সত্ত্বেও, মোংগোতে পিএইচপি দিয়ে নকল _আইডি তৈরি করা সম্ভব।

আমার ক্ষেত্রে নিয়মিততার সাথে এটি যে ব্যবহারের ঘটনা ঘটেছে তা হ'ল আমি যখন কোনও ডেটাসেটের সাহায্যে লুপ করছি এবং কোনও সংকলনে ডেটা ইনজেক্ট করার চেষ্টা করছি।

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

এর তিনটি সমাধান রয়েছে:

  1. আপনি unset()অ্যারে থেকে _id ক্ষেত্রটি করতে পারেন
  2. array()প্রতিবার আপনি যখন আপনার ডেটাসেটের মাধ্যমে লুপ করবেন তখন আপনি পুরো অ্যারেটিকে পুনরায় নতুন করে দিতে পারেন
  3. আপনি স্পষ্টভাবে _ আইডি মানটি নিজেকে সংজ্ঞায়িত করতে পারেন (এটি এমনভাবে সংজ্ঞায়িত করার জন্য যত্ন নিচ্ছেন যাতে আপনি নিজেই ডুপস তৈরি করবেন না)।

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


এখানে দেখুন: php.net/manual/en/mongocollection.insert.php : "দ্রষ্টব্য: যদি প্যারামিটারটিতে _id কী বা সম্পত্তি না থাকে তবে একটি নতুন মঙ্গোআইড উদাহরণ তৈরি করা হবে এবং এতে বরাদ্দ করা হবে This এই বিশেষ আচরণের অর্থ এই নয় প্যারামিটারটি রেফারেন্স দিয়ে চলে গেছে। ", এটি একটি বৈশিষ্ট্য, কোনও বাগ নয়, এটি সেভাবে বোঝানো হয়েছিল
অলিভার কোনিগ

1
আপনি এখানে যে দৃশ্যের বর্ণনা দিচ্ছেন তা আমি বুঝতে পারি না; সম্ভবত আপনি কিছু কোড প্রদর্শন করতে পারেন যা বাগটি প্রদর্শন করে?
মার্ক অ্যামেরি

-7

সংগ্রহের মধ্যে ObjectId স্বতন্ত্রতা সম্পর্কে কোনও গ্যারান্টি নেই। এমনকি যদি এটি সম্ভাব্যতার পক্ষে খুব সম্ভাবনা নাও থাকে তবে এটি খুব খারাপ অ্যাপ্লিকেশন ডিজাইন যা পুরো সংগ্রহ জুড়ে _id স্বতন্ত্রতার উপর নির্ভর করে।

মঙ্গো শেলের মধ্যে সহজেই এটি পরীক্ষা করা যায়:

MongoDB shell version: 1.6.5
connecting to: test
> db.foo.insert({_id: 'abc'})
> db.bar.insert({_id: 'abc'})
> db.foo.find({_id: 'abc'})
{ "_id" : "abc" }
> db.bar.find({_id: 'abc'})
{ "_id" : "abc" }
> db.foo.insert({_id: 'abc', data:'xyz'})
E11000 duplicate key error index: test.foo.$_id_  dup key: { : "abc" }

সুতরাং, সম্পূর্ণরূপে _id এর অনন্য হয়ে ওঠার উপর নির্ভর করবেন না এবং যেহেতু আপনি ObjectId প্রজন্মের ফাংশনটি নিয়ন্ত্রণ করেন না, তাই এটির উপর নির্ভর করবেন না।

ইউয়েডের মতো আরও কিছু তৈরি করা সম্ভব এবং আপনি যদি ম্যানুয়ালি এটি করেন তবে আপনার স্বতন্ত্রতার আরও ভাল গ্যারান্টি থাকতে পারে।

মনে রাখবেন যে আপনি একই সংগ্রহের মধ্যে বিভিন্ন "প্রকারের" বস্তু রাখতে পারেন, তবে কেন কেবল আপনার দুটি "টেবিল" একই সংগ্রহের মধ্যে রাখবেন না। তারা একই _id স্থান ভাগ করবে এবং এইভাবে, অনন্যরূপে গ্যারান্টিযুক্ত হবে। "সম্ভাব্য" থেকে "নিবন্ধিত" এ স্যুইচ করা কোনও ক্ষেত্রের সরল ফ্লিপিং হবে ...


1
আমি মনে করি আপনি সাধারণত _id ক্ষেত্রটিকে অবজেক্টআইডি টাইপের সাথে বিভ্রান্ত করছেন। অবজেক্টআইডি টাইপটি বিশেষত লক্ষ্যটির সাথে স্বতন্ত্রতার জন্য তৈরি করা হয়েছিল যে এটি কোনও ইউইউডি-র মতো আচরণ করা যেতে পারে। তবে _id ক্ষেত্রটি যে কোনও প্রকারের হতে পারে এবং যদি আপনি কীটির জন্য অন্যান্য ধরণের যেমন আপনার উদাহরণের স্ট্রিং ব্যবহার করেন তবে কেবলমাত্র একক সংগ্রহের মধ্যে স্বতন্ত্রতার গ্যারান্টি দেয়।
মিশরীয়

@ এমস্টেরন (নিতপিক) একটি ইউআইডি সহজাত অনন্য যে ধারণাটি ত্রুটিযুক্ত। একটি ভাল ইউইউডি / সিকোয়েন্স জেনারেশন কৌশল সংঘর্ষটিকে অসম্ভব করে তুলতে পারে তবে জেনারেটরের মধ্যে নিখুঁত স্বাতন্ত্র্যের গ্যারান্টি দেওয়ার জন্য অ্যাকাউন্টে অনন্য জেনারেটর (যেমন অনন্য অবস্থান) নেওয়া প্রয়োজন । মঞ্জুর, বেশিরভাগের পক্ষে সম্ভাবনা এত কম যে এটি কোনও প্রযোজ্য উদ্বেগের নয় :-) জিইউইডি । যদিও একটি ইস্যু উঠে আসে তা হ'ল নতুন প্রজন্মের পরিবর্তে আইডিগুলির অনুলিপি / অনুলিপি করা।

1
@ পিএসটি: মঙ্গোডিবিএস অবজেক্টআইডিগুলিতে হোস্টনামের একটি হ্যাশের উপর ভিত্তি করে উত্পাদক প্রক্রিয়ার পিড এবং কিছু বাইট উভয়ই অন্তর্ভুক্ত রয়েছে। এগুলি টাইমস্ট্যাম্প এবং ইনক্রিমেন্টিং কাউন্টারের সাথে মিলিত হওয়ার ফলে এটি অত্যন্ত সম্ভাবনাময় হয় যে কোনও দুটি পৃথকভাবে উত্পাদিত অবজেক্টআইডি বিশ্বব্যাপী / সর্বজনীনভাবে অনন্য হয়ে উঠবে। অবশ্যই আপনি বলেছেন যে কেবল সদ্য উত্পন্ন অবজেক্টআইডিগুলিতে প্রযোজ্য।
মিসেটার্ন

1
আমি অবজেক্টআইডি টাইপটি উল্লেখ করছি। '_Id' এর জন্য একটি স্ট্রিং মান নির্দিষ্ট করে না। অবশ্যই যদি তারা ম্যানুয়ালি ঠিক একই স্ট্রিংয়ের কাছে সেট করে তবে অবশ্যই তারা একই এবং সংঘাত হতে চলেছে।
অ্যান্টনি জ্যাক

হ্যাঁ, আমি আমার পোস্টে বিষয়গুলি পরিষ্কার করে দিয়েছি। _আইডি অবশ্যই অনন্য নয়, এবং যেহেতু আপনি ObjectId প্রজন্মের ফাংশনটি নিয়ন্ত্রণ করেন না, সম্ভবত এটির উপর নির্ভর করা খারাপ ধারণা।
ত্রুটি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.