ডেটাস্টোর সিলেকশন সময় আমাদের যে পছন্দ এবং কম্বিনেশনগুলো থাকে তা প্রমাণ করে যে আমরা আর এক-সাইজ-ফিটস-অল ডেটাস্টোর ওয়ার্ল্ডে নই।
আজ SQL ডেটাস্টোর (যেমন MySQL, PostgreSQL, Oracle বা SQLServer) এবং NoSQL ডেটাস্টোর (MongoDB, CouchDB, Neo4J ইত্যাদি) মিক্স অ্যান্ড ম্যাচ করার জন্য বিবেচনীয় কারণ রয়েছে। Oracle এখনো এন্টারপ্রাইজের জন্য পছন্দসই সিস্টেম অফ রেকর্ড হতে পারে, কিন্তু এখনো এটি একমাত্র গেম ইন টাউন নয়।
ডেভেলপাররা SQL এবং NoSQL-এর কম্বিনেশন ব্যবহার করে তাদের সমস্যা সমাধান করছেন - কখনো কখনো DBA বা IT ডিপার্টমেন্টের ইচ্ছা বতিত।
কাজের জন্য সঠিক টুল নির্বাচন
আজকের ওয়ার্ল্ডে ডেটাস্টোরের পাঁচটি বিস্তৃত ক্যাটাগরি রয়েছে: column-family, document, graph, key-value এবং relational। Polyglot persistence শাব্দিক অর্থে ডেটা স্টোর বা পিসিস্ট করার জন্য একাধিক ল্যাঙ্গুয়েজ ব্যবহার করা। আরও প্রায়োগিক অর্থে এর মানে হচ্ছে আমরা একই অ্যাপ্লিকেশনের ভিতরে থেকে Cypher, JSON, SQL বা অন্যান্য কোয়েরি ল্যাঙ্গুয়েজ ব্যবহার করে আমাদের ডেটা অ্যাক্সেস করতে পারি। ডেভেলপাররা তাদের পেসিস্টেন্স নিদের সমাধানের জন্য ভালো টুল খুঁজে পাওয়ার জন্য এই ভিন্ন ডেটাস্টোর এবং তাদের ভিন্ন ল্যাঙ্গুয়েজ ব্যবহার 점점 জনপ্রিয় হচ্ছে।
Sadalage এবং Fowler NoSQL Distilled-এ polyglot persistence-এর ضرুরত উল্লেখ করেছেন:
ভিন্ন ডাটাবেস ভিন্ন সমস্যা সমাধানের জন্য ডিজাইন করা হয়েছে। সকল প্রয়োজনের জন্য একটি ডাটাবেস ইঞ্জিন ব্যবহার করলে সাধারণত non-performant সমাধান হয়; ট্রানজ্যাকশনাল ডেটা স্টোর করা, সেশন ইনফরমেশন ক্যাশ করা, কাস্টমার এবং তাদের বন্ধুদের কেনা প্রোডাক্টের গ্রাফ ট্রাভার্স করা মূলত ভিন্ন সমস্যা।
ডেটা রিলেশনশিপের কথা ভাবুন। RDBMS সমাধান রিলেশনশিপ এনফোর্স করতে ভালো। যদি আমরা রিলেশনশIP আবিষ্কার করতে চাই, বা একই অবজেক্টের অন্তর্গত ভিন্ন টেবিল থেকে ডেটা খুঁজতে চাই, তবে RDBMS ব্যবহার করা কঠিন হয়ে যাবে।
ডেটাস্টোর চয়েস দুটি মাপদণ্ডে নির্ভর করে:
- স্টোর করা ডেটার স্ট্রাকচার
- ডেটার সাথে ইন্টারঅ্যাক্ট করার জন্য ব্যবহৃত কোয়েরি
আমরা ডেটা কীভাবে কোয়েরি করি তা ডেটা কীভাবে স্ট্রাকচার করব তা পরিবর্তন করে। Sadalage এবং Fowler উপরে বলেছেন, রিলেশনাল ডেটাস্টোর রিলেটেড এন্টিটি এনফোর্স করতে এক্সেল করে; তবে, আমাদের যখন সেসে এন্টিটির মধ্যে অন্যান্য রিলেশনশIP আবিষ্কার করতে হয় তখন সেটি বাধা তৈরি করে।
নিচে, আমি একটি ইউজ কেস, MongoDB-তে CraigsList ডেটা আর্কাইভাল, এবং কীভাবে তারা এটি অর্জন 했을 পারে সেটি অনুমান করব।
খেলোয়াড়রা: MongoDB, MySQL এবং CraigsList
MongoDB
MongoDB MySQL-এর একটি প্রিয় NoSQL বিকল্প হয়ে উঠেছে। এর অনেক সুবিধা রয়েছে যার মধ্যে স্কেলেবিলিটি, অটো-শার্ডিং এবং আজকের জনপ্রিয় প্রোগ্রামিং ল্যাঙ্গুয়েজের জন্য নেটিভ বাইন্ডিং উপলব্ধতা। MongoDB এবং রিলেশনাল ডেটাস্টোরের মধ্যে মূল পার্থক্য হলো MongoDB ডেটা কীভাবে চিন্তা করে এবং স্টোর করে। ফরেন কী কনস্ট্রেইন্ট ব্যবহার করে রিলেশনশিপ এনফোর্স করার বদলে, MongoDB-এ ডেটা ডকুমেন্টের একটি কালেকশন হিসেবে রিপ্রেজেন্ট করা হয়।
ডকুমেন্টগুলো রিলেশনাল ডেটা স্ট্রাকচারে সারি বা টাপলের সাথে অনুপাম (নন-আইডেন্টিক্যাল)। একটি ডকুমেন্ট ডেটাস্টোরের ক্যাটাগরাইজেশন এবং নোমেনক্লেচার সরাসরি ডেটা JSON ডকুমেন্ট হিসেবে স্টোর হওয়া এবং কালেকশনে গ্রুপ হওয়া থেকে এসেছে। এই ডকুমেন্টের গভীরতা অসীম এবং কোয়েরি বা ইনডেক্স দিয়ে সম্পূর্ণরূপে ইনস্পেক্ট করা যায়। সাধারণত MongoDB-এ ডেটার ভালো রিপ্রেজেন্টেশন রিলেশনাল ডাটাবেসের জন্য উপযুক্ত ডেটা ডিনরমালাইজ করে পাওয়া যায়। অবশ্য, আপনি যে নির্দিষ্ট কোয়েরি করতে চান সেটি এই প্রসেসকে গাইড করবে।
MongoDB-এর নুয়ান্স সম্পর্কে আরও জানতে MongoDB-এর ওয়েবসাইট দেখুন।
MySQL
ক্লাসিক যা সবাই জানে এবং পছন্দ করে, MySQL কম্পিউটিং টাইমস্কেলে যুগের آغاز থেকে রয়েছে এবং সহজে সবচেয়ে ব্যাপকভাবে ব্যবহৃত DBMS। এটি যা ফাংশনালিটি প্রদান করে তা অ্যাপ্লিকেশনকে প্রায় এক দশক ধরে ডেটা মডেল করতে এবং অনেক বাইজনেস উদ্দেশ্যে সিস্টেম অফ রেকর্ড হিসেবে কাজ করতে দিয়েছে। আজকাল যখন লোকরা রিলেশনাল ডাটাবেস চিন্তা করেন তবে সম্ভবত MySQL চিন্তা করেন।
MySQL আমাদের ক্লাসিক রিলেশনাল ডেটা মডেলের একটি ইমপ্লিমেন্টেশন দেয়। টাইপ থিওরি এবং সেট থিওরি ব্যবহার করে, এটি ১৯৭০ दशকে E.F. Codd দ্বারা ডেভেলপ করা হয়েছিল। প্রোগ্রামেটিক্যালি নরমালাইজ, প্ল্যান বা ইন্ট্রাসপেক্ট করা যাওয়া রিলেশনাল ডেটা সিস্টেমকে অত্যন্ত জনপ্রিয় করে। fakt, এই ডেটাস্টোরগুলো এখনও পছন্দ করা হয় কারণ সেগুলো ডেটা মডেল করার জেনারেল সমস্যা সমাধান করে।
CraigsList
একটি বিখ্যাত অনলাইন বিজনেস যারা MongoDB এবং MySQL ডেটাস্টোর দুটোই ব্যবহার করে সেটি CraigsList। তাদের দুটো ডেটাস্টোর সাইড-বাই-সাইড অ্যাডপশন একটি MongoDB Case Study-তে আউटलাইন করা আছে, কিন্তু নিচে একটি থাম্বনেল স্কেচ দেওয়া হলো।
রেগুলেটরি প্রয়োজনীয়তার কারণে, Craigslistকে তার ক্লাসিফাইডের ডিজিটাল রেকর্ড রিটেইন করতে হয়। প্রতিদিন ১ মিলিয়ন এরও বেশি নতুন ক্লাসিফাইড থাকায়, CraigsList-এর জন্য রিটেইন করার জন্য এটি একটি গুরুত্বপূর্ণ পরিমাণ ডেটা। এটি সব এক্টিভ ক্লাসিফাইড ইনফরমেশন ধারণ করতে MySQL ডেটাস্টোর ব্যবহার করে, যখন MongoDB আর্কাইভড ডেটা স্টোর করতে ব্যবহৃত হয় - সম্ভবত ৩০ দিনেরও পুরানো যেকোনো ডেটা। সাধারণ বিজনেস পরিবর্তন অংশ হিসেবে, স্টোর করা ডেটার ডেটা স্কিমা পরিবর্তন হয়। MongoDB আর্কাইভড ডেটার জন্য ব্যবহার করে, CraigsList কার্যকরভাবে তার ডেটা সেগমেন্ট করতে পারলো এবং স্কিমা মাইগ্রেশন সমস্যা মিটিগেট করতে পারলো।
একটি থৌট এক্সপেরিমেন্ট হিসেবে, আমি MongoDB এবং MySQL সাইড-বাই-সাইড ব্যবহার করার একটি সম্ভাব্য ইমপ্লিমেন্টেশন অনুমান করতে চাই CraigsList-এস্ক অ্যাপ্লিকেশনের জন্য। এটি অত্যন্ত অসম্ভব যে CraigsList আসলে কীভাবে তাদের ডেটা স্টোরেজ করছে, কিন্তু এটি একটি আকর্ষণীয় উপায় মাল্টিপল ডেটাস্টোর কীভাবে একসাথে কাজ করতে পারে একটি পরিচিত, হাইলি ট্রানজ্যাকশনাল, ওয়েবসাইটের জন্য।
কীভাবে করা হয়?
ডেভেলপার এবং ইঞ্জিনিয়ার অবশ্যই সমস্যায় পড়েন যখন তারা একটি বাল্কি SQL ডাটাবেসে স্কিমা আপডেট পারফর্ম করে। এটি এড়ানো যায় সিম্পলি স্কিমা আপডেট অ্যাপ্লাই হওয়ার পর "ফিক্স আপ" করার জন্য কম ডেটা রেখে। এই মাইগ্রেশন বা স্কিমা আপডেটের পেইন সাধারণত ডেটার পরিমাণের সাথে অনুপাতিকভাবে বাড়ে।
আমাদের উদাহরণে, চলুন অনুমান করি CraigsList একটি আইটেম বিক্রি করতে চাইলে ইউজার থেকে একটি নতুন ইনফরমেশন প্রয়োজন। কারণ স্কিমা আপডেট করতে হবে, CraigsList প্রভাবিত ডেটার সাইজ কমাতে চাবে আপডেটের পেইন মিনিমাইজ করতে।
এই আর্কাইভাল এবং মাইগ্রেশন সাইকেলের কয়েকটি রাউন্ডের পর, CraigsList একটি বড় হেটারোজেনাস ডেটা কালেকশন তৈরি করবে যেটি একটি স্কিমালেস ডেটাস্টোরে থাকা দরকার যদি সেটি একটি লোকেশনে থাকে। MongoDB এই কাজে খুব ভালো ফিট করে।
Classifieds-এর জন্য একটি উদাহরণ স্কিমা নিচের মতো দেখাবে (craigslist-clone থেকে শামলেস্লি রি-ইমপ্লিমেন্টেড):
CREATE TABLE `classifieds` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(75) COLLATE utf8_unicode_ci DEFAULT NULL,
`description` text COLLATE utf8_unicode_ci,
`location` varchar(75) COLLATE utf8_unicode_ci DEFAULT NULL,
`adtype` varchar(1) COLLATE utf8_unicode_ci DEFAULT 'O',
`email` varchar(75) COLLATE utf8_unicode_ci DEFAULT NULL,
`phone` varchar(75) COLLATE utf8_unicode_ci DEFAULT NULL,
`activation_code` varchar(40) COLLATE utf8_unicode_ci DEFAULT NULL,
`status` tinyint(4) DEFAULT '0',
`category_id` int(11) DEFAULT NULL,
`subcategory_id` int(11) DEFAULT NULL,
`city_id` int(11) DEFAULT NULL,
`permalink` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`image_file_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`image_content_type` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`image_file_size` int(11) DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
অবশ্য, CraigsList-এর সম্ভবত একটি ভিন্ন স্কিমা রয়েছে এবং কমপক্ষে তারা তাদের করেন্ট স্কিমা বেশ কয়েকটি ইটারেশনের পর আবিষ্কার করেছে। এছাড়া, তারা ভবিষ্যতে তাদের ডেটা কীভাবে অর্গানাইজ করা হয় সেটি পরিবর্তন করতে পারে এবং তাদের স্কিমা আবার পরিবর্তন করতে পারে। আমরা created_at এবং updated_at ফিল্ড ব্যবহার করব সিদ্ধান্ত নেওয়ার জন্য যে আমরা কখন MySQL-এ থাকা ডেটা আর্কাইভ করব।
চলুন অনুমান করি Craigslist-এর ক্লাসিফাইড পলিসি বলে যে একটি ক্লাসিফাইড ওয়েবসাইটে দুটি সপ্তাহ উপলব্ধ থাকবে। এই সময়ের পর, তারা চায় ক্লাসিফাইডটি এখনো উপলব্ধ থাকবে কিন্তুจำernerি হলেও এক্টিভ নয় (MySQL-এ)। এটি অর্জন করতে আমরা SQLAlchemy এবং pymongo-এর কম্বিনেশন ব্যবহার করতে পারি:
প্রথমে, আমাদের MySQL ইন্সট্যান্স থেকে ডেটা বের করতে হবে। আমরা SQLAlchemy ব্যবহার করে এটি করব এবং আমাদের স্কিমা ইন্ট্রাসপেক্ট করব (এটি এই উদ্দেশ্যে কোডকে আরও রি-ইউজেবল করে)।
import sqlalchemy.schema
m = sqlalchemy.schema.MetaData("mysql://root:I'm required why?@192.0.2.3/craigslist")
m.reflect()
print m.tables.keys()
যদি আপনি সফলভাবে আপনার ডাটাবেসে কানেক্ট করতে পারেন, তবে আপনি আপনার কী (কলাম নাম) স্ট্যান্ডার্ড পাইথন ফ্যাশনে প্রিন্ট হয়ে দেখবেন: [u'classifieds', u'cities', u'subcategories', u'categories']। আমাদের এখন এই টেবিল থেকে jednotlivে ডেটা আইটেম বের করতে হবে। শুধু দেখতে পাওয়া ही নয়, SQLAlchemy একটি ইলিগ্যান্ট ইন্টারফেসও প্রদান করে যা এটাকে অনেক সহজ করে দেয়।
এখন আমাদের ইন্ট্রাসপেকশন থেকে টেবিল ডেফিনিশন আছে। অবজেক্ট ম্যাপ তৈরি করার সময় নাকি সেই টেবিলগুলো কোয়েরি করে সেগুলো যেসব ডেটা আইটেম ধারণ করে সেগুলো বের করার সময়। নিচের কোয়েরি আমাদের ডেটাস্টোর থেকে ক্লাসিফাইডস বের করবে (অন্যান্য টেবিলগুলো রিডারের এক্সারসাইজ হিসেবে ছাড়া দেয়া হলো)।
import sqlalchemy.sql
connection = m.bind.connect()
classifieds = m.tables['classifieds']
query = classifieds.select()
result = connection.execute(query)
for row in result:
print dict(row.items())
এই স্নিপেট আমাদের MySQL কানেকশন ব্যবহার করে সকল ক্লাসিফাইডস কোয়েরি করে। এটি সহজে এক্সপ্যান্ড করা যায় সকল টেবিল হ্যান্ডেল করতে, ডেটা ডিনরমালাইজ করে MongoDB-এর ডকুমেন্ট স্টাইলকে बेटার ফিট করার জন্য। কিন্তু এই ডেমোনের উদ্দেশ্যে, আমরা শুধু classifieds টেবিলে ফোকাস করব। এই পয়েন্টে, আমরা classifieds টেবিলের প্রতিটি আইটেমকে ডিকশনারিতে কনভার্ট করেছি, যা সঠিক যা pymongo দিয়ে MongoDB-এ ইনসার্ট করার জন্য প্রয়োজন।
নিচের স্যাম্পেল দেখায় কীভাবে pymongo-তে কানেক্ট এবং ডিকশনারি ইনসার্ট করতে হয়:
import pymongo
client = pymongo.MongoClient('mongodb://192.0.2.2')
db = client['craigslist']
collection = db['classifieds']
collection.insert({'_id': 1})
এখন একমাত্র সমস্যা হলো SQLAlchemy এবং MongoDB তাদের ID কীভাবে স্পেসিফাই করে। SQLAlchemy id কী ব্যবহার করে যেখানে MongoDB _id কী ব্যবহার করে। সুতরাং, আমাদের সেই কী ট্রান্সলেট করতে হবে (খুব সিম্পল প্রসেস): classified['_id'] = classified.pop('id')।
উপসংহার
SQL এবং NoSQL ডেটাস্টোরকে প্রায়শই অল বা নথিং প্রপজিশন হিসেবে পোর্ট্রে করা হয়, কিন্তু যেগুলো একসাথে ব্যবহার করা যায় জটিল সমস্যা সমাধান করতে। এই উদাহরণের মাধ্যমে, আমরা দেখেছি যে MongoDB এবং MySQL ডেটাস্টোর উভয়ই ব্যবহার করে একটি সিস্টেমের জন্য খুব কম কোড প্রয়োজন। ফ্যাক্ট, এটি ক্রন দিয়ে ড্রাইভ করা যেতে পারে ডেমনাইজড হওয়ার বদলে।
একাধিক ডেটাস্টোর ব্যবহার করার কঠিনায়velopment of translation code or migration code-এ নয়, বরং অ্যাডিশনাল সিস্টেমের অ্যাডমিনিস্ট্রেশন কঠিনায় বাড়ায়। একটিমাত্র ডেটাস্টোর মেইনটেইন করতে ইতিমধ্যে এক্সপার্টাইজ প্রয়োজন (DBAs বা অ্যাডমিন যাদের ডেটাস্টোর নলেজ থাকে), এবং এই এক্সপার্টাইজের ডিমান্ড বাড়ে আপনি আরো ডেটাস্টোর ইন্ট্রোডিউস করলে।
বিজনেসে সিদ্ধান্ত নিতে হবে একাধিক ডেটাস্টোর রান করা কি মূল্যবান। এই চ্যালেঞ্জ মিটিগেট করতে কিছু টেকনোলজি রয়েছে।
Chef এবং Salt-এর মতো অটোমেশন টেকনোলজির পাশাপাশি, এই চ্যালেঞ্জ ObjectRocket, Rackspace-এর ম্যানেজড MongoDB সার্ভিসের মতো সার্ভিস ভেন্ডারের সুবিধা নিতে পারেন। জটিলতা বাড়লেও, যদি একটি সমস্যা একাধিক ডেটাস্টোর ব্যবহার করে সমাধান হয়, তবে অনুমান আপনাকে সেই সমাধান এক্সপ্লোর করতে বাধা দিতে দেবেন না।