সূচীগুলি সমস্ত ডেটাবেসের জন্য সঠিক ডেটা মডেলিংয়ের একটি গুরুত্বপূর্ণ অংশ, এবং DynamoDB এর ব্যতিক্রম নয়। DynamoDB এর সেকেন্ডারি ইনডেক্সগুলি আপনার ডেটার জন্য নতুন অ্যাক্সেস প্যাটার্ন সক্ষম করার জন্য একটি শক্তিশালী হাতিয়ার।
এই পোস্টে, আমরা DynamoDB সেকেন্ডারি ইনডেক্সগুলি দেখব। প্রথমত, আমরা ডায়নামোডিবি এবং সেকেন্ডারি ইনডেক্সগুলি যে সমস্যাগুলি সমাধান করে সেগুলি সম্পর্কে কীভাবে চিন্তা করতে হয় সে সম্পর্কে কিছু ধারণাগত পয়েন্ট দিয়ে শুরু করব। তারপর, আমরা সেকেন্ডারি ইনডেক্সগুলি কার্যকরভাবে ব্যবহার করার জন্য কিছু ব্যবহারিক টিপস দেখব। অবশেষে, আপনার কখন সেকেন্ডারি ইনডেক্স ব্যবহার করা উচিত এবং কখন আপনার অন্যান্য সমাধানগুলি সন্ধান করা উচিত সে সম্পর্কে আমরা কিছু চিন্তাভাবনা করে শেষ করব।
চল শুরু করি.
সেকেন্ডারি ইনডেক্সের ক্ষেত্রে ব্যবহার এবং সর্বোত্তম অনুশীলনে যাওয়ার আগে, আমাদের প্রথমে বুঝতে হবে DynamoDB সেকেন্ডারি ইনডেক্স কী। এবং এটি করার জন্য, ডায়নামোডিবি কীভাবে কাজ করে সে সম্পর্কে আমাদের কিছুটা বোঝা উচিত।
এটি DynamoDB এর কিছু মৌলিক বোঝার অনুমান করে। সেকেন্ডারি ইনডেক্স বোঝার জন্য আপনাকে যে প্রাথমিক পয়েন্টগুলি জানা দরকার আমরা তা কভার করব, কিন্তু আপনি যদি DynamoDB-তে নতুন হয়ে থাকেন, তাহলে আপনি আরও প্রাথমিক ভূমিকা দিয়ে শুরু করতে চাইতে পারেন।
DynamoDB একটি অনন্য ডাটাবেস। এটি OLTP ওয়ার্কলোডের জন্য ডিজাইন করা হয়েছে, যার অর্থ এটি একটি উচ্চ ভলিউম ছোট ক্রিয়াকলাপ পরিচালনা করার জন্য দুর্দান্ত - একটি শপিং কার্টে একটি আইটেম যুক্ত করা, একটি ভিডিও পছন্দ করা, বা Reddit এ একটি মন্তব্য যোগ করার মতো বিষয়গুলি নিয়ে ভাবুন৷ এইভাবে, এটি MySQL, PostgreSQL, MongoDB , বা Cassandra এর মতো আপনার ব্যবহার করা অন্যান্য ডাটাবেসের মতো অনুরূপ অ্যাপ্লিকেশনগুলি পরিচালনা করতে পারে।
DynamoDB এর মূল প্রতিশ্রুতি হল যে কোনো স্কেলে ধারাবাহিক কর্মক্ষমতার গ্যারান্টি। আপনার টেবিলে 1 মেগাবাইট ডেটা বা 1 পেটাবাইট ডেটা থাকুক না কেন, DynamoDB আপনার OLTP-এর মতো অনুরোধগুলির জন্য একই লেটেন্সি রাখতে চায়৷ এটি একটি বড় ব্যাপার -- আপনি ডেটার পরিমাণ বা একযোগে অনুরোধের সংখ্যা বাড়ালে অনেক ডেটাবেস কম কর্মক্ষমতা দেখতে পাবে। যাইহোক, এই গ্যারান্টি প্রদানের জন্য কিছু ট্রেডঅফের প্রয়োজন, এবং DynamoDB এর কিছু অনন্য বৈশিষ্ট্য রয়েছে যা কার্যকরভাবে ব্যবহার করার জন্য আপনাকে বুঝতে হবে।
প্রথমে, DynamoDB হুডের নীচে একাধিক পার্টিশনে আপনার ডেটা ছড়িয়ে দিয়ে আপনার ডেটাবেসগুলিকে অনুভূমিকভাবে স্কেল করে। এই পার্টিশনগুলি ব্যবহারকারী হিসাবে আপনার কাছে দৃশ্যমান নয়, তবে তারা কীভাবে DynamoDB কাজ করে তার মূলে রয়েছে। আপনি আপনার টেবিলের জন্য একটি প্রাথমিক কী নির্দিষ্ট করবেন (হয় একটি একক উপাদান, যাকে 'পার্টিশন কী' বলা হয়, অথবা একটি পার্টিশন কী এবং একটি সাজানোর কী এর সংমিশ্রণ), এবং আপনার ডেটা কোন পার্টিশনে থাকে তা নির্ধারণ করতে DynamoDB সেই প্রাথমিক কী ব্যবহার করবে . আপনার করা যেকোনো অনুরোধ একটি অনুরোধ রাউটারের মাধ্যমে যাবে যা নির্ধারণ করবে কোন পার্টিশনটি অনুরোধটি পরিচালনা করবে। এই পার্টিশনগুলি ছোট -- সাধারণত 10GB বা তার কম -- তাই এগুলি সরানো, বিভক্ত, প্রতিলিপি করা এবং অন্যথায় স্বাধীনভাবে পরিচালনা করা যায়।
শার্ডিংয়ের মাধ্যমে অনুভূমিক স্কেলেবিলিটি আকর্ষণীয় তবে এটি কোনভাবেই DynamoDB এর জন্য অনন্য নয়। অন্যান্য অনেক ডেটাবেস -- রিলেশনাল এবং অ রিলেশনাল -- অনুভূমিকভাবে স্কেল করার জন্য শার্ডিং ব্যবহার করে। যাইহোক, DynamoDB এর জন্য অনন্য যা এটি আপনাকে কীভাবে আপনার ডেটা অ্যাক্সেস করতে আপনার প্রাথমিক কী ব্যবহার করতে বাধ্য করে। একটি ক্যোয়ারী প্ল্যানার ব্যবহার করার পরিবর্তে যা আপনার অনুরোধগুলিকে একাধিক প্রশ্নের মধ্যে অনুবাদ করে, DynamoDB আপনাকে আপনার ডেটা অ্যাক্সেস করতে আপনার প্রাথমিক কী ব্যবহার করতে বাধ্য করে । আপনি মূলত আপনার ডেটার জন্য একটি সরাসরি ঠিকানাযোগ্য সূচক পাচ্ছেন।
DynamoDB এর জন্য API এটি প্রতিফলিত করে। পৃথক আইটেমগুলিতে ( GetItem
, PutItem
, UpdateItem
, DeleteItem
) অপারেশনগুলির একটি সিরিজ রয়েছে যা আপনাকে পৃথক আইটেমগুলি পড়তে, লিখতে এবং মুছতে দেয়৷ উপরন্তু, একটি Query
অপারেশন আছে যা আপনাকে একই পার্টিশন কী দিয়ে একাধিক আইটেম পুনরুদ্ধার করতে দেয়। আপনার যদি একটি যৌগিক প্রাথমিক কী সহ একটি টেবিল থাকে, একই পার্টিশন কী সহ আইটেমগুলি একই পার্টিশনে একসাথে গোষ্ঠীভুক্ত করা হবে। সেগুলিকে সাজানোর কী অনুসারে অর্ডার করা হবে, যা আপনাকে "একটি ব্যবহারকারীর জন্য সাম্প্রতিকতম আদেশগুলি আনুন" বা "আইওটি ডিভাইসের জন্য শেষ 10টি সেন্সর রিডিংগুলি আনুন" এর মতো প্যাটার্নগুলি পরিচালনা করার অনুমতি দেয়৷
উদাহরণ স্বরূপ, আসুন একটি SaaS অ্যাপ্লিকেশন কল্পনা করি যেখানে ব্যবহারকারীদের একটি টেবিল রয়েছে। সমস্ত ব্যবহারকারী একটি একক সংস্থার অন্তর্গত। আমাদের একটি টেবিল থাকতে পারে যা দেখতে নিম্নরূপ:
আমরা 'অর্গানাইজেশন'-এর পার্টিশন কী এবং 'ইউজারনেম'-এর একটি সাজানোর কী সহ একটি যৌগিক প্রাথমিক কী ব্যবহার করছি। এটি আমাদের একটি স্বতন্ত্র ব্যবহারকারীকে তাদের সংস্থা এবং ব্যবহারকারীর নাম প্রদান করে আনয়ন বা আপডেট করার জন্য অপারেশন করতে দেয়। আমরা একটি Query
অপারেশনে শুধুমাত্র সংস্থা প্রদান করে একটি একক সংস্থার জন্য সমস্ত ব্যবহারকারীকে আনতে পারি।
কিছু মৌলিক বিষয় মাথায় রেখে, আসুন এখন সেকেন্ডারি ইনডেক্সের দিকে তাকাই। সেকেন্ডারি ইনডেক্সের প্রয়োজনীয়তা বোঝার সর্বোত্তম উপায় হল তারা যে সমস্যার সমাধান করে তা বোঝা। আমরা দেখেছি যে কীভাবে DynamoDB আপনার প্রাথমিক কী অনুযায়ী আপনার ডেটা পার্টিশন করে এবং কীভাবে এটি আপনাকে আপনার ডেটা অ্যাক্সেস করতে প্রাথমিক কী ব্যবহার করতে চাপ দেয়। কিছু অ্যাক্সেস প্যাটার্নের জন্য এটি সবই ভাল এবং ভাল, তবে আপনার যদি অন্য উপায়ে আপনার ডেটা অ্যাক্সেস করার প্রয়োজন হয় তবে কী হবে?
আমাদের উপরের উদাহরণে, আমাদের কাছে ব্যবহারকারীদের একটি টেবিল ছিল যা আমরা তাদের সংস্থা এবং ব্যবহারকারীর নাম দ্বারা অ্যাক্সেস করেছি। যাইহোক, আমাদের একজন একক ব্যবহারকারীকে তাদের ইমেল ঠিকানার মাধ্যমে আনতে হতে পারে। এই প্যাটার্নটি প্রাথমিক কী অ্যাক্সেস প্যাটার্নের সাথে খাপ খায় না যা DynamoDB আমাদের দিকে ঠেলে দেয়। যেহেতু আমাদের টেবিলটি বিভিন্ন বৈশিষ্ট্য দ্বারা বিভক্ত করা হয়েছে, আমরা যেভাবে চাই সেভাবে আমাদের ডেটা অ্যাক্সেস করার একটি পরিষ্কার উপায় নেই। আমরা একটি সম্পূর্ণ টেবিল স্ক্যান করতে পারি, কিন্তু এটি ধীর এবং অদক্ষ। আমরা একটি পৃথক প্রাথমিক কী দিয়ে আমাদের ডেটা একটি পৃথক টেবিলে নকল করতে পারি, তবে এটি জটিলতা যোগ করে।
এখানেই সেকেন্ডারি ইনডেক্স আসে। একটি সেকেন্ডারি ইনডেক্স হল মূলত একটি ভিন্ন প্রাইমারি কী সহ আপনার ডেটার সম্পূর্ণভাবে পরিচালিত কপি। আপনি সূচকের জন্য প্রাথমিক কী ঘোষণা করে আপনার টেবিলে একটি গৌণ সূচক নির্দিষ্ট করবেন। লেখাগুলি আপনার টেবিলে আসে, DynamoDB স্বয়ংক্রিয়ভাবে আপনার সেকেন্ডারি সূচকে ডেটা প্রতিলিপি করবে।
দ্রষ্টব্য *: এই বিভাগের সবকিছুই বিশ্বব্যাপী গৌণ সূচকে প্রযোজ্য। DynamoDB স্থানীয় মাধ্যমিক সূচকগুলিও সরবরাহ করে, যা একটু ভিন্ন। প্রায় সব ক্ষেত্রেই, আপনি একটি গ্লোবাল সেকেন্ডারি ইনডেক্স চাইবেন। পার্থক্য সম্পর্কে আরও বিশদ বিবরণের জন্য, একটি বিশ্বব্যাপী বা স্থানীয় মাধ্যমিক সূচক নির্বাচন করার বিষয়ে এই নিবন্ধটি দেখুন।*
এই ক্ষেত্রে, আমরা "ইমেল" এর একটি পার্টিশন কী সহ আমাদের টেবিলে একটি সেকেন্ডারি সূচক যুক্ত করব। সেকেন্ডারি ইনডেক্স নিচের মত দেখাবে:
লক্ষ্য করুন যে এটি একই ডেটা, এটি একটি ভিন্ন প্রাথমিক কী দিয়ে পুনর্গঠিত হয়েছে। এখন, আমরা দক্ষতার সাথে একজন ব্যবহারকারীকে তাদের ইমেল ঠিকানা দিয়ে দেখতে পারি।
কিছু উপায়ে, এটি অন্যান্য ডাটাবেসের একটি সূচকের অনুরূপ। উভয়ই একটি ডেটা স্ট্রাকচার প্রদান করে যা একটি নির্দিষ্ট অ্যাট্রিবিউটে লুকআপের জন্য অপ্টিমাইজ করা হয়। কিন্তু DynamoDB-এর সেকেন্ডারি ইনডেক্সগুলি কয়েকটি মূল উপায়ে আলাদা।
প্রথমত, এবং সবচেয়ে গুরুত্বপূর্ণ, DynamoDB-এর সূচীগুলি আপনার প্রধান টেবিলের থেকে সম্পূর্ণ ভিন্ন পার্টিশনে বাস করে। DynamoDB প্রতিটি লুকআপকে দক্ষ এবং অনুমানযোগ্য করতে চায় এবং এটি রৈখিক অনুভূমিক স্কেলিং প্রদান করতে চায়। এটি করার জন্য, আপনি এটিকে অনুসন্ধান করতে ব্যবহার করবেন এমন বৈশিষ্ট্যগুলির দ্বারা আপনার ডেটা পুনরায় ভাগ করতে হবে৷
অন্যান্য বিতরণ করা ডেটাবেসে, তারা সাধারণত সেকেন্ডারি সূচকের জন্য আপনার ডেটা পুনরায় ভাগ করে না। তারা সাধারণত শার্ডের সমস্ত ডেটার জন্য সেকেন্ডারি সূচক বজায় রাখে। যাইহোক, যদি আপনার সূচীগুলি শার্ড কী ব্যবহার না করে, তাহলে আপনি শার্ড কী ছাড়াই একটি ক্যোয়ারী হিসাবে আপনার ডেটা অনুভূমিকভাবে স্কেল করার কিছু সুবিধা হারাচ্ছেন, আপনার ডেটা খুঁজে পেতে সমস্ত শার্ড জুড়ে স্ক্যাটার-গেদার অপারেশন করতে হবে খুঁজছি।
DynamoDB-এর সেকেন্ডারি ইনডেক্স আলাদা হওয়ার দ্বিতীয় উপায় হল তারা (প্রায়শই) পুরো আইটেমটিকে সেকেন্ডারি ইনডেক্সে কপি করে। রিলেশনাল ডাটাবেসের ইনডেক্সের জন্য, ইনডেক্সে প্রায়ই সূচীকৃত আইটেমের প্রাথমিক কীটির একটি পয়েন্টার থাকে। সূচীতে একটি প্রাসঙ্গিক রেকর্ড সনাক্ত করার পরে, ডাটাবেসটিকে সম্পূর্ণ আইটেমটি আনতে যেতে হবে। যেহেতু DynamoDB-এর সেকেন্ডারি ইনডেক্সগুলি মূল টেবিলের থেকে ভিন্ন নোডে রয়েছে, তাই তারা মূল আইটেমে ফিরে একটি নেটওয়ার্ক হপ এড়াতে চায়। পরিবর্তে, আপনি আপনার পঠন পরিচালনা করতে সেকেন্ডারি ইনডেক্সে যতটা প্রয়োজন ততটা ডেটা কপি করবেন।
DynamoDB-তে সেকেন্ডারি ইনডেক্স শক্তিশালী, কিন্তু তাদের কিছু সীমাবদ্ধতা রয়েছে। প্রথমত, সেগুলি শুধুমাত্র পঠনযোগ্য -- আপনি সরাসরি একটি গৌণ সূচকে লিখতে পারবেন না। বরং, আপনি আপনার প্রধান টেবিলে লিখবেন, এবং DynamoDB আপনার সেকেন্ডারি সূচকের প্রতিলিপি পরিচালনা করবে। দ্বিতীয়ত, আপনার সেকেন্ডারি ইনডেক্সে লেখার ক্রিয়াকলাপের জন্য আপনাকে চার্জ করা হবে। এইভাবে, আপনার টেবিলে একটি গৌণ সূচক যোগ করলে প্রায়ই আপনার টেবিলের মোট লেখার খরচ দ্বিগুণ হয়ে যায়।
এখন যেহেতু আমরা বুঝতে পারি সেকেন্ডারি ইনডেক্সগুলি কী এবং সেগুলি কীভাবে কাজ করে, আসুন কীভাবে সেগুলি কার্যকরভাবে ব্যবহার করা যায় সে সম্পর্কে কথা বলি৷ সেকেন্ডারি ইনডেক্স একটি শক্তিশালী টুল, কিন্তু তাদের অপব্যবহার করা যেতে পারে। সেকেন্ডারি ইনডেক্সগুলি কার্যকরভাবে ব্যবহার করার জন্য এখানে কিছু টিপস রয়েছে৷
প্রথম টিপটি সুস্পষ্ট বলে মনে হচ্ছে -- সেকেন্ডারি ইনডেক্স শুধুমাত্র পড়ার জন্য ব্যবহার করা যেতে পারে, তাই আপনার সেকেন্ডারি ইনডেক্সে শুধুমাত্র পঠনযোগ্য প্যাটার্ন থাকা উচিত! এবং এখনও, আমি এই ভুল সব সময় দেখতে. বিকাশকারীরা প্রথমে একটি সেকেন্ডারি ইনডেক্স থেকে পড়বে, তারপর মূল টেবিলে লিখবে। এর ফলে অতিরিক্ত খরচ এবং অতিরিক্ত বিলম্ব হয় এবং আপনি প্রায়শই কিছু আগাম পরিকল্পনা করে এটি এড়াতে পারেন।
আপনি যদি DynamoDB ডেটা মডেলিং সম্পর্কে কিছু পড়ে থাকেন তবে আপনি সম্ভবত জানেন যে আপনার প্রথমে আপনার অ্যাক্সেসের ধরণগুলি সম্পর্কে চিন্তা করা উচিত। এটি একটি রিলেশনাল ডাটাবেসের মতো নয় যেখানে আপনি প্রথমে নরমালাইজড টেবিল ডিজাইন করেন এবং তারপরে তাদের একসাথে যোগ দেওয়ার জন্য প্রশ্নগুলি লিখুন। DynamoDB-তে, আপনার অ্যাপ্লিকেশান যে পদক্ষেপগুলি নেবে সে সম্পর্কে আপনার চিন্তা করা উচিত এবং তারপরে সেই ক্রিয়াগুলিকে সমর্থন করার জন্য আপনার টেবিল এবং সূচীগুলি ডিজাইন করা উচিত।
আমার টেবিল ডিজাইন করার সময়, আমি প্রথমে লেখা-ভিত্তিক অ্যাক্সেস প্যাটার্ন দিয়ে শুরু করতে চাই। আমার লেখার সাথে, আমি প্রায়শই কিছু ধরণের সীমাবদ্ধতা বজায় রাখি -- একটি ব্যবহারকারীর নাম বা একটি গ্রুপে সর্বাধিক সংখ্যক সদস্যের অনন্যতা। আমি আমার টেবিলটিকে এমনভাবে ডিজাইন করতে চাই যা এটিকে সহজ করে তোলে, আদর্শভাবে DynamoDB লেনদেন ব্যবহার না করে বা রিড-মডিফাই-রাইট প্যাটার্ন ব্যবহার না করে যা রেসের অবস্থার সাপেক্ষে হতে পারে।
আপনি যখন এইগুলির মাধ্যমে কাজ করবেন, আপনি সাধারণত দেখতে পাবেন যে আপনার আইটেমটি সনাক্ত করার একটি 'প্রাথমিক' উপায় রয়েছে যা আপনার লেখার ধরণগুলির সাথে মেলে। এটি আপনার প্রাথমিক কী হবে। তারপরে, অতিরিক্ত, সেকেন্ডারি পঠিত প্যাটার্ন যোগ করা সেকেন্ডারি ইনডেক্সের সাথে সহজ।
আগে আমাদের ব্যবহারকারীদের উদাহরণে, প্রতিটি ব্যবহারকারীর অনুরোধে সম্ভবত সংগঠন এবং ব্যবহারকারীর নাম অন্তর্ভুক্ত থাকবে। এটি আমাকে স্বতন্ত্র ব্যবহারকারীর রেকর্ড দেখতে এবং সেইসাথে ব্যবহারকারীর দ্বারা নির্দিষ্ট ক্রিয়াকলাপ অনুমোদন করার অনুমতি দেবে। ইমেল ঠিকানা লুকআপ কম বিশিষ্ট অ্যাক্সেস প্যাটার্নের জন্য হতে পারে, যেমন 'পাসওয়ার্ড ভুলে গেছে' প্রবাহ বা 'ব্যবহারকারীর জন্য অনুসন্ধান' প্রবাহ। এইগুলি শুধুমাত্র পঠনযোগ্য নিদর্শন, এবং এগুলি একটি সেকেন্ডারি সূচকের সাথে ভালভাবে ফিট করে৷
সেকেন্ডারি ইনডেক্স ব্যবহার করার জন্য একটি দ্বিতীয় টিপ হল আপনার অ্যাক্সেস প্যাটার্নে পরিবর্তনযোগ্য মানগুলির জন্য সেগুলি ব্যবহার করা। আসুন প্রথমে এর পিছনে যুক্তিটি বুঝতে পারি এবং তারপরে এটি প্রযোজ্য পরিস্থিতিতে তাকান।
DynamoDB আপনাকে UpdateItem
অপারেশন সহ একটি বিদ্যমান আইটেম আপডেট করতে দেয়। যাইহোক, আপনি একটি আপডেটে একটি আইটেমের প্রাথমিক কী পরিবর্তন করতে পারবেন না । প্রাথমিক কী একটি আইটেমের অনন্য শনাক্তকারী, এবং প্রাথমিক কী পরিবর্তন করা মূলত একটি নতুন আইটেম তৈরি করছে। আপনি যদি একটি বিদ্যমান আইটেমের প্রাথমিক কী পরিবর্তন করতে চান তবে আপনাকে পুরানো আইটেমটি মুছে ফেলতে হবে এবং একটি নতুন তৈরি করতে হবে৷ এই দ্বি-পদক্ষেপ প্রক্রিয়া ধীর এবং ব্যয়বহুল। প্রায়শই আপনাকে প্রথমে আসল আইটেমটি পড়তে হবে, তারপরে মূল আইটেমটি মুছে ফেলার জন্য একটি লেনদেন ব্যবহার করুন এবং একই অনুরোধে একটি নতুন তৈরি করুন৷
অন্যদিকে, যদি আপনার একটি সেকেন্ডারি ইনডেক্সের প্রাথমিক কীতে এই পরিবর্তনযোগ্য মান থাকে, তাহলে DynamoDB প্রতিলিপি করার সময় আপনার জন্য এই মুছে ফেলা + তৈরি প্রক্রিয়াটি পরিচালনা করবে। আপনি মান পরিবর্তন করার জন্য একটি সাধারণ UpdateItem
অনুরোধ ইস্যু করতে পারেন, এবং DynamoDB বাকিগুলি পরিচালনা করবে।
আমি এই প্যাটার্ন দুটি প্রধান পরিস্থিতিতে আসা দেখতে. প্রথম, এবং সবচেয়ে সাধারণ, যখন আপনার একটি পরিবর্তনযোগ্য বৈশিষ্ট্য থাকে যা আপনি সাজাতে চান। এখানে ক্যানোনিকাল উদাহরণগুলি এমন একটি গেমের জন্য একটি লিডারবোর্ড যেখানে লোকেরা ক্রমাগত পয়েন্ট বাড়াচ্ছে, বা আইটেমগুলির ক্রমাগত আপডেট করার তালিকার জন্য যেখানে আপনি সবচেয়ে সাম্প্রতিক আপডেট করা আইটেমগুলি প্রথমে প্রদর্শন করতে চান৷ Google ড্রাইভের মত কিছু চিন্তা করুন, যেখানে আপনি আপনার ফাইলগুলিকে 'শেষ পরিবর্তিত' অনুসারে সাজাতে পারেন৷
একটি দ্বিতীয় প্যাটার্ন যেখানে এটি আসে যখন আপনার একটি পরিবর্তনযোগ্য বৈশিষ্ট্য থাকে যা আপনি ফিল্টার করতে চান। এখানে, আপনি একজন ব্যবহারকারীর জন্য অর্ডারের ইতিহাস সহ একটি ইকমার্স স্টোরের কথা ভাবতে পারেন। আপনি ব্যবহারকারীকে তাদের অর্ডারগুলি স্ট্যাটাস দ্বারা ফিল্টার করার অনুমতি দিতে চাইতে পারেন -- আমাকে আমার সমস্ত অর্ডার দেখান যা 'শিপড' বা 'ডেলিভারি' করা হয়েছে। আপনি এটিকে আপনার পার্টিশন কী বা আপনার সাজানোর কী-এর শুরুতে তৈরি করতে পারেন যাতে সঠিক-মিল ফিল্টারিং করা যায়। আইটেম স্থিতি পরিবর্তন করার সাথে সাথে, আপনি স্ট্যাটাস অ্যাট্রিবিউট আপডেট করতে পারেন এবং আপনার সেকেন্ডারি ইনডেক্সে আইটেমগুলিকে সঠিকভাবে গোষ্ঠীভুক্ত করতে DynamoDB-তে ঝুঁকতে পারেন।
এই উভয় পরিস্থিতিতে, এই পরিবর্তনযোগ্য বৈশিষ্ট্যটিকে আপনার সেকেন্ডারি সূচকে স্থানান্তর করা আপনার সময় এবং অর্থ সাশ্রয় করবে। আপনি পঠন-সংশোধন-লেখা প্যাটার্ন এড়িয়ে সময় বাঁচাবেন, এবং লেনদেনের অতিরিক্ত লেখার খরচ এড়িয়ে আপনি অর্থ সাশ্রয় করবেন।
উপরন্তু, নোট করুন যে এই প্যাটার্নটি আগের টিপের সাথে ভালভাবে ফিট করে। এটি অসম্ভাব্য যে আপনি পরিবর্তনযোগ্য বৈশিষ্ট্যের উপর ভিত্তি করে লেখার জন্য একটি আইটেম সনাক্ত করবেন যেমন তাদের পূর্ববর্তী স্কোর, তাদের পূর্ববর্তী স্থিতি, বা শেষবার আপডেট করা হয়েছিল। বরং, আপনি ব্যবহারকারীর আইডি, অর্ডার আইডি বা ফাইলের আইডির মতো আরও স্থায়ী মান দ্বারা আপডেট করবেন। তারপর, আপনি পরিবর্তনযোগ্য বৈশিষ্ট্যের উপর ভিত্তি করে বাছাই এবং ফিল্টার করতে সেকেন্ডারি ইনডেক্স ব্যবহার করবেন।
আমরা উপরে দেখেছি যে DynamoDB প্রাথমিক কী-এর উপর ভিত্তি করে আপনার ডেটাকে পার্টিশনে ভাগ করে। DynamoDB-এর লক্ষ্য এই পার্টিশনগুলিকে ছোট রাখা -- 10GB বা তার কম -- এবং আপনার লক্ষ্য হওয়া উচিত আপনার পার্টিশন জুড়ে অনুরোধ ছড়িয়ে দেওয়া যাতে DynamoDB-এর স্কেলেবিলিটির সুবিধা পাওয়া যায়।
এর মানে সাধারণত আপনার পার্টিশন কী-তে একটি উচ্চ-কার্ডিনালিটি মান ব্যবহার করা উচিত। একটি ব্যবহারকারীর নাম, একটি অর্ডার আইডি, বা একটি সেন্সর আইডি মত কিছু চিন্তা করুন. এই বৈশিষ্ট্যগুলির জন্য প্রচুর সংখ্যক মান রয়েছে এবং DynamoDB আপনার পার্টিশন জুড়ে ট্র্যাফিক ছড়িয়ে দিতে পারে।
প্রায়শই, আমি দেখতে পাই যে লোকেরা তাদের মূল টেবিলে এই নীতিটি বোঝে, কিন্তু তারপরে তাদের সেকেন্ডারি ইনডেক্সে এটি সম্পূর্ণভাবে ভুলে যায়। প্রায়শই, তারা একটি ধরণের আইটেমের জন্য পুরো টেবিল জুড়ে অর্ডার করতে চায়। যদি তারা ব্যবহারকারীদের বর্ণানুক্রমিকভাবে পুনরুদ্ধার করতে চায়, তারা একটি গৌণ সূচক ব্যবহার করবে যেখানে সমস্ত ব্যবহারকারীদের পার্টিশন কী হিসাবে USERS
এবং সাজানোর কী হিসাবে ব্যবহারকারীর নাম রয়েছে। অথবা, যদি তারা একটি ইকমার্স স্টোরে অতি সাম্প্রতিক অর্ডারের অর্ডার করতে চায়, তাহলে তারা একটি সেকেন্ডারি ইনডেক্স ব্যবহার করবে যেখানে সমস্ত অর্ডারে পার্টিশন কী হিসাবে ORDERS
এবং সাজানোর কী হিসাবে টাইমস্ট্যাম্প রয়েছে৷
এই প্যাটার্নটি ছোট-ট্র্যাফিক অ্যাপ্লিকেশনগুলির জন্য কাজ করতে পারে যেখানে আপনি DynamoDB পার্টিশন থ্রুপুট সীমার কাছাকাছি আসবেন না, তবে এটি একটি উচ্চ-ট্রাফিক অ্যাপ্লিকেশনের জন্য একটি বিপজ্জনক প্যাটার্ন। আপনার সমস্ত ট্র্যাফিক একটি একক শারীরিক পার্টিশনে ফানেল হতে পারে এবং আপনি সেই পার্টিশনের জন্য দ্রুত থ্রুপুট সীমাতে আঘাত করতে পারেন।
আরও, এবং সবচেয়ে বিপজ্জনকভাবে, এটি আপনার প্রধান টেবিলের জন্য সমস্যা সৃষ্টি করতে পারে। যদি আপনার সেকেন্ডারি ইনডেক্স প্রতিলিপি করার সময় রাইট থ্রোটল হয়ে যায়, তাহলে প্রতিলিপি সারি ব্যাক আপ হবে। যদি এই সারিটি খুব বেশি ব্যাক আপ করে, DynamoDB আপনার প্রধান টেবিলে লেখাগুলি প্রত্যাখ্যান করা শুরু করবে।
এটি আপনাকে সাহায্য করার জন্য ডিজাইন করা হয়েছে -- DynamoDB আপনার সেকেন্ডারি সূচকের স্থবিরতা সীমিত করতে চায়, তাই এটি আপনাকে প্রচুর পরিমাণে ব্যবধান সহ একটি সেকেন্ডারি সূচক থেকে বাধা দেবে। যাইহোক, এটি একটি আশ্চর্যজনক পরিস্থিতি হতে পারে যা পপ আপ হয় যখন আপনি এটি অন্তত আশা করছেন।
লোকেরা প্রায়শই একটি নতুন প্রাথমিক কী দিয়ে তাদের সমস্ত ডেটা প্রতিলিপি করার উপায় হিসাবে সেকেন্ডারি সূচকগুলিকে মনে করে। যাইহোক, একটি গৌণ সূচকে শেষ করার জন্য আপনার সমস্ত ডেটার প্রয়োজন নেই৷ যদি আপনার কাছে এমন একটি আইটেম থাকে যা সূচকের কী স্কিমার সাথে মেলে না, তবে এটি সূচকে প্রতিলিপি করা হবে না।
এটি আপনার ডেটাতে একটি বিশ্বব্যাপী ফিল্টার প্রদানের জন্য সত্যিই কার্যকর হতে পারে। এর জন্য আমি যে আদর্শ উদাহরণটি ব্যবহার করি তা হল একটি বার্তা ইনবক্স। আপনার প্রধান টেবিলে, আপনি একটি নির্দিষ্ট ব্যবহারকারীর জন্য সমস্ত বার্তা সংরক্ষণ করতে পারেন যেগুলি তৈরি হওয়ার সময় অনুসারে অর্ডার করা হয়েছে৷
কিন্তু আপনি যদি আমার মত হন, আপনার ইনবক্সে অনেক বার্তা আছে। এছাড়াও, আপনি অপঠিত বার্তাগুলিকে একটি 'টুডো' তালিকা হিসাবে বিবেচনা করতে পারেন, যেমন কারো কাছে ফিরে যাওয়ার জন্য সামান্য অনুস্মারক। সেই অনুযায়ী, আমি সাধারণত আমার ইনবক্সে অপঠিত বার্তাগুলি দেখতে চাই৷
আপনি এই বিশ্বব্যাপী ফিল্টার প্রদান করতে আপনার সেকেন্ডারি ইনডেক্স ব্যবহার করতে পারেন যেখানে unread == true
। সম্ভবত আপনার সেকেন্ডারি ইনডেক্স পার্টিশন কী ${userId}#UNREAD
এর মতো কিছু, এবং বাছাই কী বার্তাটির টাইমস্ট্যাম্প। আপনি যখন প্রাথমিকভাবে বার্তাটি তৈরি করেন, এতে সেকেন্ডারি ইনডেক্স পার্টিশন কী মান অন্তর্ভুক্ত থাকবে এবং এইভাবে অপঠিত বার্তা সেকেন্ডারি ইনডেক্সে প্রতিলিপি করা হবে। পরে, যখন একজন ব্যবহারকারী বার্তাটি পড়েন, আপনি status
READ
এ পরিবর্তন করতে পারেন এবং সেকেন্ডারি ইনডেক্স পার্টিশন কী মানটি মুছে ফেলতে পারেন। DynamoDB তারপর এটি আপনার সেকেন্ডারি সূচক থেকে মুছে ফেলবে।
আমি এই কৌশলটি সর্বদা ব্যবহার করি এবং এটি অসাধারণভাবে কার্যকর। আরও, একটি স্পার্স ইনডেক্স আপনার অর্থ সাশ্রয় করবে। বার্তা পড়ার জন্য যেকোনো আপডেট সেকেন্ডারি ইনডেক্সে প্রতিলিপি করা হবে না এবং আপনি লেখার খরচ বাঁচাতে পারবেন।
আমাদের শেষ পরামর্শের জন্য, আসুন আগের পয়েন্টটি একটু এগিয়ে নেওয়া যাক। আমরা এইমাত্র দেখেছি যে আইটেমটিতে সূচকের জন্য প্রাথমিক মূল উপাদানগুলি না থাকলে DynamoDB আপনার সেকেন্ডারি সূচকে একটি আইটেম অন্তর্ভুক্ত করবে না। এই কৌশলটি শুধুমাত্র প্রাথমিক মূল উপাদানগুলির জন্যই নয় কিন্তু ডেটাতে নন-কী বৈশিষ্ট্যগুলির জন্যও ব্যবহার করা যেতে পারে!
যখন আপনি একটি সেকেন্ডারি ইনডেক্স তৈরি করবেন, আপনি সেকেন্ডারি ইনডেক্সে আপনি প্রধান টেবিল থেকে কোন বৈশিষ্ট্যগুলিকে অন্তর্ভুক্ত করতে চান তা নির্দিষ্ট করতে পারেন। একে বলে সূচকের অভিক্ষেপ । আপনি প্রধান টেবিল থেকে সমস্ত বৈশিষ্ট্য অন্তর্ভুক্ত করতে বেছে নিতে পারেন, শুধুমাত্র প্রাথমিক কী বৈশিষ্ট্য বা বৈশিষ্ট্যগুলির একটি উপসেট।
যদিও এটি আপনার সেকেন্ডারি সূচকে সমস্ত বৈশিষ্ট্য অন্তর্ভুক্ত করার জন্য প্রলুব্ধ হয়, এটি একটি ব্যয়বহুল ভুল হতে পারে। মনে রাখবেন যে আপনার মূল টেবিলের প্রতিটি লেখা যা একটি প্রজেক্টেড অ্যাট্রিবিউটের মান পরিবর্তন করে তা আপনার সেকেন্ডারি ইনডেক্সে প্রতিলিপি করা হবে। সম্পূর্ণ অভিক্ষেপ সহ একটি একক মাধ্যমিক সূচক কার্যকরভাবে আপনার টেবিলের জন্য লেখার খরচ দ্বিগুণ করে। প্রতিটি অতিরিক্ত সেকেন্ডারি ইনডেক্স আপনার লেখার খরচ 1/N + 1
বাড়িয়ে দেয়, যেখানে N
হল নতুনের আগে সেকেন্ডারি ইনডেক্সের সংখ্যা।
উপরন্তু, আপনার লেখার খরচ আপনার আইটেমের আকারের উপর ভিত্তি করে গণনা করা হয়। আপনার টেবিলে লেখা প্রতিটি 1KB ডেটা একটি WCU ব্যবহার করে। আপনি যদি আপনার সেকেন্ডারি ইনডেক্সে একটি 4KB আইটেম কপি করে থাকেন, তাহলে আপনি আপনার প্রধান টেবিল এবং আপনার সেকেন্ডারি ইনডেক্স উভয়েই সম্পূর্ণ 4টি WCU-এর অর্থ প্রদান করবেন।
সুতরাং, আপনার সেকেন্ডারি ইনডেক্স অনুমান সংকুচিত করে আপনি অর্থ সঞ্চয় করতে পারেন এমন দুটি উপায় রয়েছে। প্রথমত, আপনি কিছু লেখা সম্পূর্ণভাবে এড়াতে পারেন। আপনার যদি এমন কোনো আপডেট অপারেশন থাকে যা আপনার সেকেন্ডারি ইনডেক্স প্রজেকশনে কোনো অ্যাট্রিবিউট স্পর্শ না করে, DynamoDB আপনার সেকেন্ডারি ইনডেক্সে লেখাটি এড়িয়ে যাবে। দ্বিতীয়ত, আপনার সেকেন্ডারি ইনডেক্সে প্রতিলিপি করে এমন লেখাগুলির জন্য, আপনি প্রতিলিপি করা আইটেমের আকার কমিয়ে অর্থ সাশ্রয় করতে পারেন।
এটি সঠিক পেতে একটি চতুর ভারসাম্য হতে পারে। সূচক তৈরি হওয়ার পরে সেকেন্ডারি সূচকের অনুমানগুলি পরিবর্তনযোগ্য নয়। আপনি যদি খুঁজে পান যে আপনার সেকেন্ডারি সূচকে আপনার অতিরিক্ত বৈশিষ্ট্যের প্রয়োজন, তাহলে আপনাকে নতুন অভিক্ষেপের সাথে একটি নতুন সূচক তৈরি করতে হবে এবং তারপরে পুরানো সূচকটি মুছে ফেলতে হবে।
এখন যেহেতু আমরা সেকেন্ডারি ইনডেক্সের আশেপাশে কিছু ব্যবহারিক পরামর্শ অন্বেষণ করেছি, আসুন একধাপ পিছিয়ে যাই এবং আরও একটি মৌলিক প্রশ্ন জিজ্ঞাসা করি -- আপনার কি আদৌ সেকেন্ডারি সূচক ব্যবহার করা উচিত?
যেমনটি আমরা দেখেছি, সেকেন্ডারি ইনডেক্স আপনাকে আপনার ডেটাকে ভিন্নভাবে অ্যাক্সেস করতে সাহায্য করে। যাইহোক, এটি অতিরিক্ত লেখার খরচে আসে। সুতরাং, মাধ্যমিক সূচকগুলির জন্য আমার থাম্বের নিয়ম হল:
সেকেন্ডারি ইনডেক্স ব্যবহার করুন যখন কম পড়া খরচ বর্ধিত লেখার খরচের চেয়ে বেশি।
আপনি যখন এটি বলেন তখন এটি সুস্পষ্ট বলে মনে হয়, তবে আপনি মডেলিং করার সময় এটি বিপরীতমুখী হতে পারে। অন্যান্য পন্থা সম্পর্কে চিন্তা না করে "একটি গৌণ সূচকে এটি নিক্ষেপ" বলা এত সহজ বলে মনে হচ্ছে।
এই বাড়িতে আনতে, আসুন দুটি পরিস্থিতিতে তাকান যেখানে সেকেন্ডারি সূচকগুলি অর্থহীন হতে পারে।
DynamoDB এর সাথে, আপনি সাধারণত আপনার প্রাথমিক কীগুলি আপনার জন্য আপনার ফিল্টারিং করতে চান৷ যখনই আমি DynamoDB তে একটি কোয়েরি ব্যবহার করি তখন এটি আমাকে একটু বিরক্ত করে কিন্তু তারপরে আমার অ্যাপ্লিকেশনে আমার নিজস্ব ফিল্টারিং সঞ্চালন করে -- কেন আমি এটিকে প্রাথমিক কীতে তৈরি করতে পারিনি?
আমার ভিসারাল প্রতিক্রিয়া সত্ত্বেও, এমন কিছু পরিস্থিতি রয়েছে যেখানে আপনি আপনার ডেটা অতিরিক্ত পড়তে এবং তারপরে আপনার অ্যাপ্লিকেশনটিতে ফিল্টার করতে চাইতে পারেন।
আপনি যখন আপনার ব্যবহারকারীদের জন্য আপনার ডেটাতে অনেকগুলি বিভিন্ন ফিল্টার প্রদান করতে চান তখন আপনি এটি দেখতে পাবেন এমন সবচেয়ে সাধারণ জায়গা, কিন্তু প্রাসঙ্গিক ডেটা সেটটি আবদ্ধ।
একটি ওয়ার্কআউট ট্র্যাকার চিন্তা করুন. আপনি ব্যবহারকারীদের অনেক বৈশিষ্ট্য যেমন ওয়ার্কআউটের ধরন, তীব্রতা, সময়কাল, তারিখ ইত্যাদিতে ফিল্টার করার অনুমতি দিতে চাইতে পারেন। যাইহোক, একজন ব্যবহারকারীর ওয়ার্কআউটের সংখ্যা পরিচালনাযোগ্য হতে চলেছে -- এমনকি একজন পাওয়ার ব্যবহারকারী 1000 ওয়ার্কআউট অতিক্রম করতে কিছুটা সময় নেবে। এই সমস্ত বৈশিষ্ট্যগুলিতে সূচী স্থাপন করার পরিবর্তে, আপনি কেবল ব্যবহারকারীর সমস্ত ওয়ার্কআউট আনতে পারেন এবং তারপরে আপনার অ্যাপ্লিকেশনটিতে ফিল্টার করতে পারেন।
এখানেই আমি গণিত করার পরামর্শ দিই। DynamoDB এই দুটি বিকল্পের গণনা করা সহজ করে তোলে এবং কোনটি আপনার অ্যাপ্লিকেশনের জন্য আরও ভাল কাজ করবে তা বোঝা যায়।
আসুন আমাদের পরিস্থিতি কিছুটা পরিবর্তন করি -- যদি আমাদের আইটেম সংগ্রহ বড় হয়? যদি আমরা একটি জিমের জন্য একটি ওয়ার্কআউট ট্র্যাকার তৈরি করি, এবং আমরা জিমের মালিককে জিমের সমস্ত ব্যবহারকারীদের জন্য উপরে উল্লিখিত সমস্ত বৈশিষ্ট্যগুলি ফিল্টার করার অনুমতি দিতে চাই?
এটি পরিস্থিতি পরিবর্তন করে। এখন আমরা শত শত বা এমনকি হাজার হাজার ব্যবহারকারীর কথা বলছি, প্রতিটি শত শত বা হাজার হাজার ওয়ার্কআউট সহ। সম্পূর্ণ আইটেম সংগ্রহের অতিরিক্ত পড়া এবং ফলাফলগুলিতে পোস্ট-হক ফিল্টারিং করার অর্থ হবে না।
কিন্তু সেকেন্ডারি ইনডেক্স সত্যিই এখানে অর্থপূর্ণ না. সেকেন্ডারি ইনডেক্সগুলি পরিচিত অ্যাক্সেস প্যাটার্নগুলির জন্য ভাল যেখানে আপনি উপস্থিত থাকা প্রাসঙ্গিক ফিল্টারগুলির উপর নির্ভর করতে পারেন। যদি আমরা চাই যে আমাদের জিমের মালিক বিভিন্ন বৈশিষ্ট্যে ফিল্টার করতে সক্ষম হন, যার সবকটিই ঐচ্ছিক, তাহলে এই কাজটি করার জন্য আমাদের প্রচুর সংখ্যক সূচক তৈরি করতে হবে।
আমরা আগে ক্যোয়ারী প্ল্যানারদের সম্ভাব্য ডাউনসাইড সম্পর্কে কথা বলেছি, কিন্তু ক্যোয়ারী প্ল্যানারদেরও একটি উল্টো দিক আছে। আরও নমনীয় প্রশ্নের জন্য অনুমতি দেওয়ার পাশাপাশি, তারা এই প্রশ্নগুলি রচনা করার ক্ষেত্রে একাধিক সূচী থেকে আংশিক ফলাফল দেখার জন্য সূচক ছেদ করার মতো জিনিসগুলিও করতে পারে। আপনি DynamoDB এর সাথে একই জিনিস করতে পারেন, কিন্তু এটি আপনার অ্যাপ্লিকেশনের সাথে অনেক পিছনে এবং এটি বের করার জন্য কিছু জটিল অ্যাপ্লিকেশন যুক্তি সহ ফলাফল করতে যাচ্ছে।
যখন আমার এই ধরনের সমস্যা হয়, আমি সাধারণত এই ব্যবহারের ক্ষেত্রে আরও উপযুক্ত একটি টুল খুঁজি। আপনার ডেটাসেট জুড়ে নমনীয়, সেকেন্ডারি-ইনডেক্স-এর মতো ফিল্টারিং প্রদানের জন্য রকসেট এবং ইলাস্টিকসার্চ হল আমার কাছে যাওয়ার সুপারিশ।
এই পোস্টে, আমরা DynamoDB সেকেন্ডারি ইনডেক্স সম্পর্কে শিখেছি। প্রথমত, আমরা ডায়নামোডিবি কীভাবে কাজ করে এবং কেন সেকেন্ডারি ইনডেক্সের প্রয়োজন তা বোঝার জন্য কিছু ধারণাগত বিট দেখেছি। তারপরে, আমরা সেকেন্ডারি ইনডেক্সগুলিকে কীভাবে কার্যকরভাবে ব্যবহার করতে হয় এবং তাদের নির্দিষ্ট বৈশিষ্ট্যগুলি শিখতে হয় তা বোঝার জন্য কিছু ব্যবহারিক টিপস পর্যালোচনা করেছি। পরিশেষে, আমরা দেখলাম কিভাবে সেকেন্ডারি ইনডেক্স নিয়ে ভাবতে হয় তা দেখতে কখন আপনার অন্যান্য পন্থা ব্যবহার করা উচিত।
সেকেন্ডারি ইনডেক্সগুলি আপনার DynamoDB টুলবক্সে একটি শক্তিশালী টুল, কিন্তু সেগুলি সিলভার বুলেট নয়। সমস্ত DynamoDB ডেটা মডেলিংয়ের মতো, নিশ্চিত করুন যে আপনি আপনার অ্যাক্সেসের ধরণগুলি সাবধানে বিবেচনা করুন এবং আপনি প্রবেশ করার আগে খরচ গণনা করুন।
Alex DeBrie-এর ব্লগ DynamoDB ফিল্টারিং এবং রকসেটে SQL ব্যবহার করে একত্রিতকরণ প্রশ্নে সেকেন্ডারি-ইনডেক্স-এর মতো ফিল্টারিংয়ের জন্য আপনি কীভাবে রকসেট ব্যবহার করতে পারেন সে সম্পর্কে আরও জানুন।