محمدعلی دیبایی

SQL یا NoSQL، مسئله این است… – بخش اول

 

SQL یا NoSQL، مسئله این است…

مطالعه مختصری بر پایگاه داده هایNoSQL
بخش اول

 

چکیده :

پایگاه داده های NoSQL نقش بسیار مهمی در استفاده از  ” داده های بزرگ ” (Big Data) برای ذخیره و بازیابی مقادیر این اطلاعات ایفا میکنند. سیستم های مدیریت پایگاه داده رابطه ای (Relational Database Management Systems)  از تئوری ACID برای انسجام داه ها استفاده میکنند در حالی که پایگاه داده های NoSQL از رویکرد BASE استفاده میکنند.
RDBMS ها تنها بصورت عمودی (Vertically) افزایش می یابند، اما پایگاه داده های NoSQL هم بصورت عمودی و هم بصورت افقی ( بخش کردن ) افزایش می یابند.
انواع پایگاه داده های NoSQL عبارتند از : سند گرا (Document oriented)، زوجهای کلید-مقدار (Key-Value pairs) ، ستون گرا (Column oriented) و گراف . مدلسازی داده ها برای پایگاه داده های سندگرا مانند مدلسازی داده ها برای پایگاه داده های RDBMS  در بخش مدلسازی مفهمومی و منطقی (Conceptual and Logical modeling phases) است. اگرچه بعضی از موارد متفاوت هستند. بعنوان مثال در RDBMS چیزی که با عنوان ” کلید خارجی (Foreign key) ”  یاد می شود، در پایگاه داده های سنگرا NoSQL با عنوان ” مرجع (Reference) ” خطاب می شود.

 

پایگاه داده های NoSQL :

اگرچه سیستم های مدیریت پایگاه داده رابطه ای (RDBMS) در دهه های اخیر وجود داشته و پرکابرد بوده اند و روز بروز کاملتر می شود، اما این نوع پایگاه داده همچنان مشکل اساسی با کنترل مقدار داده های بزرگ دارد. در این حین تکنولوژی جدیدی از پایگاه های داده با نام ” NoSQL ” وجود دارد که کنترل داده های عظیم را همراه با دسترسی سریعتر به داده ها و هچنین صرفه جویی در هزینه ها بهمراه دارد.

 

فصل اول : جایگذاری کردن یا ارجاع دادن

اولین کاری که برای ساخت یک نرم افزار انجام میدهیم، ساخت مدل داده های آن است. در پایگاه داده های رابطه ای مانند MySQL این مرحله بدین صورت است که داده ها را نرمالسازی میکنند و در جداول، داده های اضافه و تکرارشونده حذف میشوند. درحالی که در مونگو دی بی (Mongo DB)  که یک پایگاه داده NoSQL است، داده ها در یک ساختار ” سندی ” قرار میگرند و نه یک ” جدول ” . برای نمونه جداول رابطه ای در تقاطع هر سطر و ستون ( سلول ها ) تنها میتوانند یک مقدار اسکالر قرار دهند. اما مونگو با استفاده از” بیسان ” (BSON) میتواند داده های پیچیده را با استفاده از آرایه ها پشتیبانی کند .( هر کدام از آرایه ها خود نیز میتوانند شامل آرایه باشند)
در ادامه به این مسئله میپردازیم که آیا بهتر است اطلاعات را بصورت جایگذاری ( embed  )  ذخیره کنیم یا آنها را با یک آی دی به یک دیگر ارجاع ( reference ) دهیم. همچنین روش مقایسه کارایی ، انعطاف پذیری و پیچیدگی آنها را نیز بررسی میکنیم.

 

مدلسازی رابطه ای داده و نرمالسازی

قبل از پرداختن به این که چگونه بین ارجاع دادن و جایگذاری کردن کدام را انتخاب کنیم، نگا ه کوتاهی به چگونگی مدل سازی پایگاه داده های رابطه ای می اندازیم. بطور معمول مدلسازی سازی رابطه ای داده ها متشکل از یک سری جدول است که شامل سطر و ستون میاشند و بطور پیوسته یک شِما برای داده ها تعریف میکند.تئوری پایگاه داده های رابطه ای چندین راه برای قرار دادن اطلاعات در جداول معرفی کرده است که به آن ها ” فرم های نرمال ” (Normal form) گفته می شود. البته این بحث بسیار گسترده میباشد و در این جا  تنها به آن اشاره خواهیم کرد. دو فرم در اینجا مورد استفاده ما قرار میگیرند : اولین فرم نرمال (1nf) و سومین فرم نرمال ( 3nf) (First Normal Form & Third Normal Form)

 

فرم نرمال چیست؟

نرمالسازی یک شما معمولا با قرار دادن داده ها بصورت 1nf آغاز می شود. تعریف دقیق 1nf از موضوع بحث خارج است اما بطور خلاصه قرار دادن داده ها در یک جدول بصورتی که در تقاطع هر سطر و ستون ( هر سلول ) تنها یک مقدار جای بگیرد را 1nf گویند. برای یادگیری بهتر ادامه بحث را در غالب یک مثال پیش میبریم. یک برنامه دفترچه تلفن بصورت زیر را در نظر بگیرید :

این جدول بصورت پیشفرض بصورت  1nf میباشد. حال فرض کنید میخواهیم برای یک فرد بیش از یک شماره تلفن در نظر بگیریم :

با توجه به جدول فوق این نحوه ذخیره اطلاعات از حالت 1nf خارج است و کار را برای خواندن اطلاعات سخت میکند.مثلا اگر بخواهیم با توجه به شماره یک شخص نام آن را بدست آوریم درخواستی که باید بنویسیم بصورت زیر است :

 

استفاده از پیشوند LIKE باعث می شود که دستور برای پیدا کردن بهترین جواب کل دیتابیس را جستجو کند که این موضوع خود باعث کنی برنامه می شود.
در نهایت راه دیگری که میتوان برای ذخیره چند تلفن استفاده کرد، ساخت چند ستون مختلف است :

در صورت استفاده از این راه نیز دستور استفاده شده طولانی و بهینه نیست :

 

همچنین در این نوع ذخیره سازی مشکلی که وجود دارد مشکل آپدیت و همچنین حذف یک داده است. برای برطرف کردن این مشکل 1nf راهی که پیشنهاد میدهد شکستن ستون ها به سطر است :

حال داده های ما بصورت 1nf در آمده اند اما با یک مشکل جدید به نام ” حشو ” یا ” اضافگی” (Redundancy) برمیخوریم. اضافگی محتمل بودن غیر همخوانی را بهمراه دارد و همچنین باعث می شود از یک فایل چندین کپی وجود داشته باشد.( این موضوع خود باعث مشکل و کار اضافی در قسمت آپدیت و حذف اطلاعات می شود). برای نرمالسازی این جدول باید آن را به دو جدول جداگانه تقسیم کنیم :

در این مرحله علاوه بر جداسازی جداول باید یک ” ستون کلیدی ” نیز در نظر بگیریم تا بتوانیم جداول را به هم متصل کنیم. در مثال بالا ” contact_id ” ستون کلیدی میباشد. در این مدلسازی مشکل اضافگی برطرف شده و راحت میتواند یک داده را بدون تغییر چنین سطر، تغییر داد و همچنین دیگر لازم نیست نگران غیر همخوانی داده ها باشیم.

 

پس مشکل کجاست ؟

نکته مثبتی که در رابطه با نرمالسازی وجود دارد این است که بعد از این کار براحتی میتوان داده ها را آپدیت کرد. اما مشکل جایی آغاز می شود که میخواهیم این داده ها را بازخوانی کنیم. مثلا فرض کنید در مثال بالا میخواهیم یک مخاطب خاص  و شماره تلفن هایش را بخوانیم :

 

نتیجه ای که از این دستور حاصل می شود بصورت زیر است :

در عمل آن چیزی که مورد نظر ما بوده است صورت پذیرفته اما مشکل اصلی در نحوه برآورده شدن این خواسته است بویژه اگر دیتابیس مورد نظر بر روی یک ” دیسک مغناطیسی چرخنده ” ذخیره شده باشد. برای درک بهتر چرایی این موضوع، باید بطور مختصر در مورد خصوصیات فیزیکی این نوع دستگاه ها بدانیم.

ویژگی دیسک های چرخنده این است که برای پیدا کردن مکان مشخصی بر روی دیسک زمان نسبتا زیادی صرف میکنند اما وقتی مکان پیدا شد میتوانند بطور پی در پی داده مورد نظر را بخوانند.بعنوان مثال پیدا کردن مکانی مشخص بر روی یک دیسک مدرن چیزی حدود 5 میلی ثانیه طول میکشد، اما وقتی دیسک مکان مورد نظر را پیدا کند میتواند اطلاعات را با نرخ 40-80مگابایت برثانیه بخواند.

99 درصد از زمان سپری شده برای پیدا کردن مکان مورد صرف خواندن سطر ها می شود. وقتی صحبت از دسترسی به دیسک می شود، پیدا کردن مکان های تصادفی بهینه و به نفع ما نیستند. نکته قابل توجه این است که پیشوند JOIN معمولا به مکان های تصادفی برای پیدا کردن اطلاعات ممورد نظر خود نیاز دارد. کد پایتون زیر را در نظر بگیرید :

 

باتوجه به این دستور برای پیدا کردن هر یک از مخاطب ها مجبوریم حداقل یک بار دیسک را جستجو کنیم. به همین خاطر استفاده از JOIN  یکی از پرهزینه ترین امکانات دیتابیس های رابطه ای است. همچنین اگر بخواهید دیتابیس خود را بر روی چند سرور گسترش دهید مجبور به استفاده از JOIN  توزیعپذیر هستید که خود بسیار پیچیده و بصورت کلی عملیات بسیار کندی است.

 

پایان بخش اول

پیام بگذارید