প্রসঙ্গ
আমি একটি ডেটাবেস ডিজাইন করছি (PostgreSQL 9.6 এ) যা বিতরণকৃত অ্যাপ্লিকেশন থেকে ডেটা সঞ্চয় করবে। অ্যাপ্লিকেশনটির বিতরণ প্রকৃতির SERIAL
কারণে, সম্ভাব্য জাতি-শর্তের কারণে আমি অটো-ইনক্রিমেন্ট ইন্টিজারগুলি ( ) আমার প্রাথমিক কী হিসাবে ব্যবহার করতে পারি না ।
প্রাকৃতিক সমাধান হ'ল একটি ইউআইডি, বা বিশ্বব্যাপী অনন্য শনাক্তকারী use পোস্টগ্রিস একটি অন্তর্নির্মিত UUID
টাইপের সাথে আসে , যা একটি উপযুক্ত ফিট।
ইউইউডি-র আমার যে সমস্যাটি রয়েছে তা ডিবাগিংয়ের সাথে সম্পর্কিত: এটি একটি মানবেতর-বান্ধব স্ট্রিং। শনাক্তকারী ff53e96d-5fd7-4450-bc99-111b91875ec5
আমাকে কিছুই বলেনা ACC-f8kJd9xKCd
, যদিও অনন্য হওয়ার গ্যারান্টিযুক্ত না হলেও আমাকে বলে যে আমি কোনও ACC
বস্তুর সাথে কাজ করছি ।
প্রোগ্রামিং দৃষ্টিকোণ থেকে, বেশ কয়েকটি পৃথক অবজেক্ট সম্পর্কিত অ্যাপ্লিকেশন প্রশ্নগুলি ডিবাগ করা সাধারণ common ধরুন প্রোগ্রামার ভুলভাবে (অর্ডার) টেবিলে কোনও ACC
(অ্যাকাউন্ট) অবজেক্টের জন্য অনুসন্ধান করে ORD
। একজন মানব-পঠনযোগ্য শনাক্তকারী সহ, প্রোগ্রামারটি তাত্ক্ষণিকভাবে সমস্যাটি সনাক্ত করে, ইউআইডি ব্যবহার করার সময় তিনি কী ভুল ছিল তা নির্ধারণ করতে কিছু সময় ব্যয় করতেন।
আমার ইউইউডিগুলির "গ্যারান্টিযুক্ত" স্বতন্ত্রতার প্রয়োজন নেই; আমি কি দ্বন্দ্ব ছাড়া কী জেনারেট করার জন্য কিছু রুম প্রয়োজন, কিন্তু UUID Overkill হয়। এছাড়াও, সবচেয়ে খারাপ পরিস্থিতি, সংঘর্ষের ঘটনা ঘটলে এটি বিশ্বের শেষ হবে না (ডাটাবেস এটি প্রত্যাখ্যান করে এবং অ্যাপ্লিকেশনটি পুনরুদ্ধার করতে পারে)। সুতরাং, ট্রেড-অফগুলি বিবেচিত, একটি ছোট তবে মানব-বান্ধব শনাক্তকারী আমার ব্যবহারের ক্ষেত্রে আদর্শ সমাধান হবে be
অ্যাপ্লিকেশন অবজেক্টগুলি সনাক্ত করা
আমি যে শনাক্তকারীর সাথে এসেছি তার মধ্যে নিম্নলিখিত ফর্ম্যাট রয়েছে: {domain}-{string}
যেখানে {domain}
অবজেক্ট ডোমেন (অ্যাকাউন্ট, অর্ডার, পণ্য) দিয়ে প্রতিস্থাপন করা হয়েছে এবং {string}
এলোমেলোভাবে উত্পন্ন স্ট্রিং। কিছু ক্ষেত্রে, {sub-domain}
এলোমেলো স্ট্রিংয়ের আগে একটি প্রবেশ করানো এমনকি বুদ্ধিমান হতে পারে । স্বতন্ত্রতার গ্যারান্টি দেওয়ার উদ্দেশ্যে {domain}
এবং এর দৈর্ঘ্যটিকে উপেক্ষা করা যাক {string}
।
যদি সূচীকরণ / অনুসন্ধানের পারফরম্যান্সে সহায়তা করে তবে ফর্ম্যাটটিতে একটি নির্দিষ্ট আকার থাকতে পারে।
সমস্যাটি
জানে যে:
- আমি পছন্দ মতো একটি প্রাথমিক বিন্যাস চাই
ACC-f8kJd9xKCd
। - এই প্রাথমিক কীগুলি বেশ কয়েকটি টেবিলের অংশ হবে।
- এই সমস্ত কীগুলি 6NF ডাটাবেসে বেশ কয়েকটি যোগ / সম্পর্কের ক্ষেত্রে ব্যবহার করা হবে।
- বেশিরভাগ টেবিলের মাঝারি থেকে বড়-ইশ আকারের আকার হবে (গড়ে ~ 1M সারি; সর্বাধিক with 100 এম সারি)।
পারফরম্যান্স সম্পর্কে, এই কীটি সঞ্চয় করার সর্বোত্তম উপায় কী?
নীচে চারটি সম্ভাব্য সমাধান রয়েছে, তবে যেহেতু ডাটাবেসের সাথে আমার খুব কম অভিজ্ঞতা আছে আমি নিশ্চিত না যে কোনটি (যদি থাকে) সেরা।
সমাধান হিসাবে বিবেচিত
স্ট্রিং হিসাবে স্টোর ( VARCHAR
)
(পোস্টগ্রিস CHAR(n)
এবং এর মধ্যে কোনও পার্থক্য রাখে না VARCHAR(n)
, তাই আমি উপেক্ষা করছি CHAR
)।
কিছু গবেষণার পরে, আমি খুঁজে পেয়েছি যে স্ট্রিং তুলনা VARCHAR
, বিশেষত জয়েন অপারেশনগুলির সাথে, ব্যবহারের চেয়ে ধীর INTEGER
। এটি বোধগম্য হয়, তবে এই স্কেল সম্পর্কে আমার কী চিন্তা করা উচিত?
2. বাইনারি হিসাবে স্টোর ( bytea
)
পোস্টগ্র্রেসের বিপরীতে, মাইএসকিউএল এর নেটিভ UUID
টাইপ নেই। BINARY
36-বাইটের পরিবর্তে 16-বাইট ক্ষেত্র ব্যবহার করে কোনও ইউআইডি কীভাবে সংরক্ষণ করবেন তা ব্যাখ্যা করার জন্য বেশ কয়েকটি পোস্ট রয়েছে VARCHAR
। এই পোস্টগুলি আমাকে কীটি বাইনারি হিসাবে সংরক্ষণ করার ধারণা দিয়েছে ( bytea
পোস্টগ্রিসে)।
এটি আকার বাঁচায়, তবে আমি অভিনয় নিয়ে আরও উদ্বিগ্ন concerned কোন তুলনাটি আরও দ্রুত: বাইনারি বা স্ট্রিংগুলি এমন একটি ব্যাখ্যা খুঁজতে আমার খুব ভাগ্য হয়েছিল। আমি বিশ্বাস করি বাইনারি তুলনা দ্রুত হয়। যদি সেগুলি হয়, তবে bytea
সম্ভবত VARCHAR
প্রোগ্রামারকে এখনই প্রতিটি সময় ডেটা এনকোড / ডিকোড করতে হয়, তার চেয়ে সম্ভবত আরও ভাল ।
আমি ভুল হতে পারি, তবে আমি উভয়ই মনে করি bytea
এবং VARCHAR
বাই (বা চরিত্র অনুসারে) বাইট বাই বা সমতা (তুলনা) করব। এই ধাপে ধাপে তুলনা এবং "সম্পূর্ণ জিনিস" কেবল তুলনা করার কোনও উপায় আছে? (আমি এটি মনে করি না, তবে এটি চেক করতে ব্যয় করে না)।
আমি মনে করি হিসাবে সংরক্ষণ করা bytea
সর্বোত্তম সমাধান, তবে আমি অবাক হচ্ছি যে অন্য কোনও বিকল্প আছে যা আমি উপেক্ষা করছি। এছাড়াও, সমাধান 1-এ আমি যে উদ্বেগ প্রকাশ করেছি ঠিক তা ধরে রেখেছে: তুলনা করার ক্ষেত্রে ওভারহেড কি যথেষ্ট যে আমাকে চিন্তিত করা উচিত?
"ক্রিয়েটিভ" সমাধান
আমি দুটি অত্যন্ত "সৃজনশীল" সমাধান নিয়ে কাজ করতে পেরেছি, আমি ঠিক জানি না কতটা পরিমাণে (অর্থাত্ যদি আমি এগুলিকে কোনও টেবিলে কয়েক হাজার সারিও বেশি করে স্কেল করতে সমস্যা করি)।
৩. UUID
তবে এটির সাথে যুক্ত "লেবেল" থাকলেও সংরক্ষণ করুন
ইউআইডিগুলি ব্যবহার না করার মূল কারণটি যাতে প্রোগ্রামাররা অ্যাপ্লিকেশনটিকে আরও ভালভাবে ডিবাগ করতে পারে। তবে যদি আমরা উভয়ই ব্যবহার করতে পারি তবে কী হবে: ডাটাবেসগুলি সমস্ত কীগুলিকে UUID
কেবলমাত্র হিসাবে সংরক্ষণ করে , তবে এটি অনুসন্ধানগুলি করার আগে / পরে বস্তুটি আবৃত করে।
উদাহরণস্বরূপ, প্রোগ্রামার এর জন্য জিজ্ঞাসা করে ACC-{UUID}
, ডাটাবেস ACC-
অংশটি উপেক্ষা করে , ফলাফলগুলি এনে দেয় এবং সেগুলি সমস্ত হিসাবে ফিরিয়ে দেয় {domain}-{UUID}
।
সঞ্চিত পদ্ধতি বা ফাংশনগুলির সাথে কিছু হ্যাকারির মাধ্যমে এটি সম্ভব হবে তবে কিছু প্রশ্ন মাথায় আসে:
- এটি (প্রতিটি ক্যোয়ারীতে ডোমেন অপসারণ / যুক্ত করা) কি যথেষ্ট ওভারহেড?
- এটা কি সম্ভব?
আমি এর আগে কখনও সঞ্চিত পদ্ধতি বা ফাংশন ব্যবহার করি নি, তাই এটি এমনকি সম্ভব কিনা তাও আমি নিশ্চিত নই। কেউ কি কিছু আলোকপাত করতে পারে? যদি আমি প্রোগ্রামার এবং সঞ্চিত ডেটার মধ্যে একটি স্বচ্ছ স্তর যোগ করতে পারি তবে এটি একটি নিখুঁত সমাধান বলে মনে হচ্ছে।
4. (আমার প্রিয়) আইপিভি 6 হিসাবে স্টোর cidr
হ্যাঁ, আপনি এটি ঠিক পড়েছেন। দেখা যাচ্ছে যে IPv6 ঠিকানার ফর্ম্যাটটি আমার সমস্যাটিকে পুরোপুরি সমাধান করে ।
- আমি প্রথম কয়েকটি অক্টেটে ডোমেন এবং সাব-ডোমেন যুক্ত করতে পারি এবং বাকিগুলি এলোমেলো স্ট্রিং হিসাবে ব্যবহার করতে পারি।
- সংঘর্ষের মতভেদ ঠিক আছ। (যদিও আমি 2 ^ 128 ব্যবহার করব না তবে এটি এখনও ঠিক আছে)
- সমতার তুলনাগুলি (আশাকরি) অপ্টিমাইজ করা হয়েছে, সুতরাং আমি কেবল ব্যবহারের চেয়ে ভাল পারফরম্যান্স পেতে পারি
bytea
। - আমি
contains
কীভাবে ডোমেন এবং তাদের শ্রেণিবিন্যাসকে প্রতিনিধিত্ব করে তার উপর নির্ভর করে কিছু আকর্ষণীয় তুলনা করতে পারি ।
উদাহরণস্বরূপ, ধরুন আমি 0000
"পণ্য" ডোমেন উপস্থাপনের জন্য কোড ব্যবহার করি । কী 0000:0db8:85a3:0000:0000:8a2e:0370:7334
পণ্যটির প্রতিনিধিত্ব করবে 0db8:85a3:0000:0000:8a2e:0370:7334
।
এখানে মূল প্রশ্নটি: এর সাথে তুলনা করে bytea
, cidr
ডেটা টাইপ ব্যবহারের কোনও প্রধান সুবিধা বা অসুবিধা আছে কি?
varchar
অন্য অনেক সমস্যার মধ্যে থাকবে। আমি পিজির ডোমেনগুলি সম্পর্কে জানতাম না, যা সম্পর্কে জেনে রাখা দুর্দান্ত। আমি দেখছি যে প্রদত্ত ক্যোয়ারীটি সঠিক অবজেক্টটি ব্যবহার করছে যদি ডোমেনগুলি যাচাই করতে ব্যবহৃত হয় তবে এটি এখনও একটি পূর্ণসংখ্যার সূচক না থাকার উপর নির্ভর করবে। serial
এখানে ব্যবহারের কোনও "সুরক্ষিত" উপায় আছে কিনা তা নিশ্চিত নয় (একটি লক স্টেপ ছাড়াই)।
varchar
। এটিকে একটি FK
integer
প্রকার বানানোর কথা বিবেচনা করুন এবং এর জন্য একটি সারণী যুক্ত করুন। এইভাবে আপনার উভয়ই মানব পাঠযোগ্যতা থাকতে পারে এবং আপনি আপনার যৌগিকটিকে PK
সন্নিবেশ / আপডেটের অসঙ্গতিগুলি (অস্তিত্বহীন ডোমেন স্থাপন) থেকে সুরক্ষা পাবেন।
text
বাঞ্ছনীয় শেষ হয়ে গেছে varchar
। এ depesz.com/2010/03/02/charx-vs-varcharx-vs-varchar-vs-text এবং postgresql.org/docs/current/static/datatype-character.html
ACC-f8kJd9xKCd
। "← এটি ভাল পুরানো সংমিশ্রণ মূল কী জন্য একটি কাজ বলে মনে হয় ।