আপনি এবং আপনার friend একটা seminar-এ গেছেন, seminar-এ speaker-রা তাদের মতামত share করছেন। মাঝে মাঝে কিছু important কথা বলছেন। এই কথাগুলো আপনার friend note করছে, কিন্তু আপনি কিছুই note করেননি। Seminar শেষ হওয়ার পরের দিন আপনি সবকিছুই ভুলে গেছেন, আবছা আবছা মনে আছে কিন্তু সম্পূর্ণ মনে করতে পারছেন না। উপায় না পেয়ে আপনার friend-কে জিজ্ঞেস করলেন। ও সবকিছুই সুন্দর করে বলে দিলো। কারণটা নিশ্চয়ই বুঝতে পারছেন। ও কেন সবকিছু মনে রাখতে পারছে? কারণ ঐ friend সবকিছুই note করে রেখেছে বা save করে রেখেছে।
একবার একটু technological দিকে আসি, আপনি যখন Facebook বা LinkedIn-এ কাউকে message করেন তখন সেটা সরাসরি তার কাছে send হয়। Reason হচ্ছে আপনারা connected। এখানে আপনি directly message তার কাছে send করছেন; network to network। কিন্তু মজার বিষয় হচ্ছে আপনি পরে যখন disconnected তখনও message-গুলো দেখতে পারছেন। হিসেব অনুযায়ী পরে message-গুলো থাকার কথা না। তাহলে হচ্ছেটা কী?
আপনি বা অন্য কেউ যখন message send করছেন তখন সেই message-টা first-এ server-এ আসে, সেই server message-টা save করে। Save করার পর তারপর receiver-এর কাছে message-টা forward করে দেয়। সেই জন্য আপনি message-টা দেখতে পারছেন।
এখন যেখানে বা যার মাধ্যমে save করা হচ্ছে, সেটাই হচ্ছে Database।
Database কী এবং কেন?
সহজভাবে বললে database হচ্ছে data রাখার জায়গা। এখন বলতে পারেন file system-এর মাধ্যমে তো hard drive-এ data রাখা যেতেই পারে। তাহলে separate database-এর দরকার কী? এই question একদম valid। মজার ব্যাপার হচ্ছে database behind the scene-এ এই file system use করেই data store করে। এই শুনে আপনার মনে হতে পারে তাহলে direct file system use করলেই তো হয়।
আসলে file system-এ data রাখাই যায়, কিন্তু problem হয় যখন search করা হয়। 1 million data থেকে একটা specific data খোঁজার জন্য file system প্রত্যেকটা file check করে তারপর আনতে হবে। তাহলে কতটা time লাগবে বুঝতে পারছেন? এত time লাগলে আপনার use কী থাকবে?
এবার database কীভাবে কাজ করে এবং এই problem-টা solve করে সেটা জানার try করি। Database মূলত file system-এর ওপরে একটা layer তৈরি করে। এখানে শুধু file store করা ছাড়া আরও অনেকগুলো কাজ করা হয়ে থাকে। For example, database-এ indexing নামে একটা feature আছে। ওপরে যে 1 million data-এর ভেতরে searching করার যেই বিষয়টা বললাম, indexing করার পরে এই operation-এ time direct file system-এর থেকে 10x-20x কম লাগবে। কীভাবে লাগবে সেটা নিচে একটা section আছে ওখানে বুঝতে পারবেন।
Hopefully database সম্পর্কে idea হয়ে গেছে।
Relational Database কী?
একটা simple question করি? আপনার পিতা-মাতা ছাড়া logically আপনার কি কোনো অস্তিত্ব থাকবে? আপনার তো জন্মই হবে না। এর মানে আপনি তাদের ওপর dependable। তারা যদি history-তে exist না করে আপনিও করবেন না। এরকম অনেক রকম জিনিস আছে, আপনার ভাই বোন, দাদা দাদি।
এখানে একটা জিনিস খেয়াল করেন, ২টা আলাদা type-এর জিনিসের মধ্যে একটা relation থাকছে। এখানে relation-গুলো কিন্তু একেকটা একেকরকম, কিন্তু কিছু limit বা কিছু জিনিস বাদ দিয়ে দিলে, কয়েকটা relationship থেকে যাবে।
আসলে relational database-গুলো অনেকটা এভাবেই connected। এখানে প্রত্যেকটা entity-এর জন্য একটা করে table থাকে, table-এ column থাকে এবং row wise database add হয়। এই column-এই কিছু data রাখা হয় যাতে relation create করা যায়। For example, parent & children table আছে। এখন children table-এ row add করার সময়, একটা extra field add করবো, for example parent। এই parent-এর value দিয়ে determine হবে ঐ children-এর parent কে বা কারা।
আসলে database একটা long long topic। এর syllabus অনেক long। অনেকটা সমুদ্রের মতন। আমি just একটা ধারণা দিয়েছি। নিচে অনেক অনেক topic নিয়ে আলোচনা করা হয়েছে। সেগুলো পড়লে অনেক কিছু শিখতে পারবেন hopefully।
ACID: Four Pillars of Database
একটা জিনিস চিন্তা করেন, যখন কোনো কিছু standard হয়ে যায়, তখন তার required characteristics set করা হয়। যাতে same way-তে alternative নিয়ে আসা যায়। এরকমভাবে relational database-এর required characteristics হচ্ছে ACID। ACID মূলত ৪টা word-এর সংক্ষিপ্ত form: Atomicity, Consistency, Isolation & Durability। একটা relational database-কে এই ৪টা জিনিস provide করতে হবে। নিচে এগুলো নিয়ে একটু আলোচনা করলে বুঝতে পারবেন।
**Atomicity**
একটা ছোট্ট গল্প বলি, তাহলে relate করতে easy হবে। ছোটবেলায় আমার আম্মা আমাকে টাকা দিয়ে দোকানে পাঠাতো এবং বলতো এই জিনিসটা নিয়ে আসবি আর বাকি টাকা দিয়ে cake কিনে খাবি। এটাও বলতো যদি ঐ জিনিস দোকানে না থাকে তাহলে পুরো টাকা ফেরত নিয়ে চলে আসবি, cake কিন্তু কিনবি না। এখন একটা জিনিস লক্ষ্য করুন। হয়তো ২টা কাজই হবে, না হলে একটাও হবে না।
Relational database-এর ক্ষেত্রে যখন কোনো transaction-এর (এটা নিয়ে এখন bother হওয়ার দরকার নেই) ভেতরে either সবগুলো operation successful হবে or কোনো operation-ই হবে না। যদি fail করে, তাহলে তা automatic rollback হওয়ার feature থাকতে হবে। এই behavior-টাই হলো Atomicity।
**Consistency**
কিছু কিছু public আছে যাদের mind খুব দ্রুত swing হয়। একবার এই তো আরেকবার অন্যটা। এরকমটা যদি আপনার store করা information-এর ওপর হয় তাহলে কী হতে পারে একটু চিন্তা করুন। Suppose, আপনার system-এ কেউ একজন একটা payment initiate করেছে। এই data-র status swing হচ্ছে, একবার failed, একবার success, কখনো pending। এমন হলে আপনি কি বলতে পারবেন, যে আসলে payment-টা হয়েছে কি না? বলা possible না। এই জন্য database-এ যে value store করেছি সেটা always সেই value provide করতে হবে। এটাই Consistency। সব সময় correct value provide করবে।
**Isolation**
একটা জিনিস চিন্তা করুন, আপনার application-এ same time-এ ২-৩ জন user payment start করলো। Normal ভাবেই এগুলো transaction-এর মধ্যে দিতে হবে। কারণটা তো বুঝতেই পারছেন। এখন ১ জন user-এর একটা problem হওয়ায় একটা operation fail করলো। এই কারণে বাকি user-দের payment-ও fail করলো। এখন আপনার কাছে question, এটা কি ঠিক হলো?
না, ঠিক হয়নি, তারা তো single user না, তারা আলাদা, সবকিছু আলাদা। তার problem শুধু তার payment-টা failed দেখাবে, বাকিগুলো নিজের মতো চলবে। এটাই তো হওয়া উচিত, তাই নয় কি? এই concept-টাই হচ্ছে Isolation। Isolation প্রত্যেকটা transaction-কে isolate করে রাখে। কেউ কাউকে interfere করতে পারবে না।
**Durability**
একটা scenario চিন্তা করুন, আপনার application-এর একটা user একটা data add করলো। প্রথম ২-৩ দিন সেই data দেখালো কিন্তু ৪ দিনের মাথায় যেয়ে সেই data আর নেই। তাহলে এখন সেই user কি আপনার system use করবে? এখন মজার বিষয় হচ্ছে, এই data কেউ delete করেনি। System থেকে automatic হারিয়ে গেছে। অনেকটা RAM-এর মতো behavior। Power চলে গেলেই সব ভুলে যাওয়ার মতো অবস্থা। এখানে solution কী হতে পারে? যাই হয়ে যাক, user-এর data database-এ store থাকতে হবে। এই জিনিসটাই হচ্ছে Durability।
এই topic-গুলো Relational Database-এর জন্য খুবই important। আমি just একটু idea দেয়ার try করেছি, আপনার mental model-টা create করার try করেছি। আপনার যদি ইচ্ছা হয় তাহলে আপনি পড়তে পারেন। তবে এটুকু বলতে পারি এগুলো আপনাকে ফেলে চলে যাবে না।
PostgreSQL কীভাবে Data Store করে?
PostgreSQL data রাখে pages (8KB block) হিসেবে। প্রতিটা table-এর data এই pages-এ থাকে। একটা row যদি multiple pages-এ ছড়িয়ে পড়ে, PostgreSQL সেটা handle করে TOAST mechanism দিয়ে।
Index: ডেটাবেসের সূচিপত্র
indexing-এর ব্যবহার তো একটু আগে একবার বলেছি। indexing জিনিসটা আসলে কী সেটা বোঝার try করি চলেন।
মনে করুন আপনার library আছে, সেখানে হাজার ২-এর মতো বই আছে। এখন আপনার প্রতিনিয়তই কোনো না কোনো বই লাগে। সেই বই খুঁজতে আপনার অর্ধেক time চলে যায়। তো এই problem-এর solution-এর জন্য আপনি চমৎকার কাজ করলেন। আপনি book-এর নামের শব্দের ওপর base করে সাজিয়ে রাখলেন। For example, প্রথম A দিয়ে start হওয়া বইগুলো, then B, then C, এভাবে। এতে সুবিধা কী হবে? যখন আপনার কোনো বই দরকার হবে তখন, আপনি just সেই বইয়ের letter-এর কাছে চলে যাবেন। ব্যাস আপনার ২৬ ভাগের ২৫ ভাগ কাজ কমে গেলো।
ঠিক same concept-টা database indexing করার সময় use করে। একটা range তৈরি করে নেয় (for example)। যখন কোনো data insert করা হয় তখন ঐ indexing করা field-টা কোন range-এর ভেতরে যাবে সেটা select করে, ঐ range-এর ভেতরে push করা হয়। এখন ঐ field দিয়ে যখন কোনো query run করা হবে তখন তো সে ঐ range-এর ভেতরে যেয়ে খুঁজে আনবে।
PostgreSQL indexing-এর জন্য, B-Tree data structure use করে থাকে। এর search complexity অনেকটা binary search-এর মতো।
CREATE INDEX idx_users_email ON users(email);
এখানে users table-এর email field-এ indexing করা হয়েছে। এখন email দিয়ে query অনেক কম সময় নিবে।
আপাতত এই পর্যন্তই কারণ database indexing নিয়ে একটা dedicated article আসবে।
EXPLAIN ANALYZE
মনে করুন একটা system আছে যেখানে ৩-৪ রকমের আলাদা আলাদা system একসাথে মিলে কাজ করছে। এখন কোনো কারণে আপনার application slow হয়ে গেলো। তাহলে বুঝবেন কীভাবে? testing করে। আপনি সবকিছুই check করে দেখলেন, সব ঠিকঠাক। তারপরেও slow। আপনি কি আপনার SQL check করেছেন? আপনার SQL query-তে problem নেই সেটা আপনি sure? এখন হয়তো বলবেন এই তো, sure না।
এই জিনিসটা বোঝার জন্য default একটা feature থাকে, EXPLAIN ANALYZE। এটার মাধ্যমে আপনার query কোথায়, কীভাবে, কতক্ষণ run হয়েছে তা আপনাকে in-details দিয়ে দিবে। তখন easily determine করতে পারবেন, আসলে SQL-এ problem আছে কি না। নিচে একটা example দেয়া হলো।
EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'test@example.com';
এটা run করলে বুঝতে পারবেন email-এর জন্য আসলে indexing use হয়েছে কি না।
Connection Pool
আপনি যখন কোনো application develop করবেন তখন, backend থেকে database-কে connect করে database থেকে data fetch করবেন। Normal-ভাবে, যখন কোনো data fetch করতে হয় তখন প্রথমেই database connect করতে হয়, then needed operation-গুলো করা হয়। At last connection close করতে হয়। Close না করলে আপনার database server এই connection-গুলো memory-তে store করবে, একসময় যেয়ে দেখা যাবে memory শেষ হয়ে গেছে। আর তখন server crash করবে। এখানে আরেকটা বিষয় আছে, এখন প্রতিবার connect-disconnect করার কারণে কিছু latency create হচ্ছে। এই latency যদি কমানো যায় তাহলে user experience increase হবে।
Connection pool-টা হলো এই দুইটার মাঝামাঝি একটা solution। Connection pool জিনিসটা active connection যা always database-এর সাথে connected হয়ে থাকবে। যখন দরকার তখন এই pool use করে data fetch করবে। এই হচ্ছে connection pool-এর basic concept। একটা example দিলে বুঝতে পারবেন।
মনে করুন আপনি ৫টা connection pool create করেছেন। এর বাইরে database connection-এর আর way নাই (for now)। এখন ৬ জন user একসাথেই request করলো, তখন এই ৫টা connection pool ৫টা user-এর request handle করবে, যখন এই ৫টা user-এর মধ্যে কারো কাজ শেষ হয়ে যাবে তখন ঐ connection pool-টা release হয়ে যাবে। Release হওয়ার সাথে সাথে ৬ নম্বর user-এর request-এ এই connection pool-টা use হয়ে যাবে। আর যদি কোনো request না থাকে তখন connection pool idle হয়ে থাকবে।
সহজভাবে বললে, connection pool হচ্ছে active database connection, যা always connect হয়ে থাকে। আর database query-এর জন্য এগুলো reuse হয়।
এখন বলতে পারেন তাহলে connection pool size একটা বড় number দিয়ে দিলে বেশি ভালো হবে? No, it's not like that। বেশি connection দিলে তো 1st situation-এর মতো memory শেষ হয়ে যেতে পারে। এই pool size-টা depend করে আপনার application-এর active user, আপনার database server এর memory + cpu, server এর read/write অপারেশন ইত্যাদি-এর ওপর। তাই pool size ঠিক করার আগে একটু calculation করা প্রয়োজন।
বটম লাইন
Database related concept প্রত্যেকটা developer-এর জানা উচিত। কারণ আপনি যত ভালোভাবে আপনার data-কে সাজিয়ে গুছিয়ে securely রাখতে পারবেন + সেগুলো efficiently serve করতে পারবেন, ততই আপনার application বা system-এর performance + longevity বাড়বে।
যদি আপনি Database নিয়ে আরও বিস্তারিত পড়তে চান তাহলে পরামর্শ হচ্ছে এই বই গুলো পড়ার, ১। Database Management System ২। Database Internals
একটা মজার কোথা বলি, প্রথম দিকে এই গুলো পড়তে আমার খুবই বোরিং লাগত, কিন্তু যখন একবার এর বেসিক এবং কোর বিষয় গুলো আয়ত্তে করে ফেলবেন তখন তখন আসল মজা টা পাবেন।
**Database is the center point of backend system.**
আপনার সবচেয়ে কঠিন database debugging experience কী ছিল? কমেন্টে শেয়ার করুন! 👇