مقدمه
در این پست بحث میکنیم که دیتابیس های NoSql چه فرقی با دیتابیسهای سنتی رابطهای و Schema Base دارند.
همچنین چند راهکار برای مدل کردن دیتابیس نوسکوئل ارائه میشود؛ دیتابیس های داکیومنت بیس بعضاً Schema Less نامیده میشوند که این عبارت نادرست میباشد. این گونه دیتابیسها به ساختارهای از پیش تعریف شده همانند آنچه در دیتابیسهای رابطهای داریم نیازی ندارند اما شما باید تعریف کنید که چگونه میخواهید دیتای خود را سازماندهی کنید.
معمولا در NoSql شما قصد دارید تا دیتای خود را به صورت تجمیع شده در اختیار داشته باشید، بنابراین میتوانید دیتای خود را به سرعت و بدون استفاده از Joinها بازیابی کنید. یک دیزاین مناسب از دیتابیس میتواند در نحوه عملکرد برنامه شما تغییرات بسیار زیادی ایجاد کند.
یک حکایت وجود دارد که اگر یک راه حل برای یک مشتری کار میکند با یک ساعت گفتگو 1000 برابر سریع تر کار خواهد کرد!
چرا NoSql
انگیزه استفاده از NoSql حجم ، سرعت و تنوع دیتاهاست .
دیتابیس رابطه ای در مقابل دیتابیس NoSql
در دیتابیس رابطهای تمام تلاش برای آن است که یک موجودیت تعریف کنیم و رابطه آن موجودیت با سایر موجودیت ها را تشریح کنیم.کوئری ها و ایندکسها بعداً اضافه شدند.با دیتابیس رابطهای شما یک طرح طبیعی ایجاد میکند که از دیتاهای زائد میکاهد، از افزونگی دیتا جلوگیری میکند و به بهبود عملکرد سیستم می افزاید.کوئری ها با Joinها دیتاها را در کنار هم قرار داده و به شما خروجی میدهند .
هرچند Join ها در هنگام خواندن یک گلوگاه سرعتی ایجاد میکنند اما این مدل نمیتواند در ابعاد بزرگ مقیاس در نظر گرفته شود.
فرایند مدلسازی دیتابیسهای NoSql
اگر با استفاده از رابطه ها و موجودیت ها شروع به تعریف کردن Schema کنید بسیار مفید خواهد بود. روابط،ویژگی ها و موجودیت ها را تعیین کنید
موجودیت ها: اشیا اصلی در برنامه شما
ویژگی ها: ویژگی های اشیا در برنامه
روابط: رابطه بین موجودیت ها : 1-1 ، یک به چند ، چند به چند
مدل ER میتواند در کوئری زدنها و دسترسی به الگوها برای تعریف مدل فیزیکی استفاده شود بنابراین دادهای که با هم خوانده میشود با هم نیز نوشته میشود.
برای طراحی یک مدل به عنوان مثال از یک شبکه اجتماعی مثل Reddit استفاده میکنیم( به یاد داشته باشید که من نمیدانم ردیت دقیقاً چگونه نوشته شده است ) ، در اینجا UseCaseها را میبینیم.
· کاربران میتوانند لینکها را با استفاده از دستهبندی (اخبار ، ورزش و ... ) پست کنند
· کاربران میتوانند زیر پست ها نظر بگذارند
بعضی از کوئریهای مورد نیاز عبارتاند از :
· نمایش پست ها بر اساس دسته بندی ها و تاریخ ( نمایش جدید ترین پست ها )
· نمایش کامنت ها بر اساس شناسه پست
· نمایش پست ها بر اساس شناسه کاربر
مثالِ مدل منطقی
این یک نمودار ER برای شبکه اجتماعی مد نظر ماست
موجودیت ها عبارت اند از :
· کاربر
· پست
· نظر
· دسته بندی
روابط عبارت اند از:
· کاربر یک پست ایجاد میکند
· یک پست تعدادی کامنت دارد
· یک پست متعلق به یک دسته بندی میباشد
مثال مدلِ رابطهای
این یک مدل رابطه ای برای شبکه اجتماعی مد نظر ماست
کاربران در جدول User ذخیره میشوند
لینک های پست شده در جدول Postذخیره میشوند به همراه یک کلید خارجی برای کاربری که پست کرده است و کلید خارجی دسته بندی.
نظرات مربوط به یک پست در جدول Comment ذخیره میشوند به همراه یک کلید خارجی که به پست اشاره میکند و یک کلید خارجی به کاربری که نظر را ارسال کرده است.
نرمال سازی
در مدل رابطه ای شما دیتا را نرمال سازی میکنید تا از افزودگی دیتا جلوگیری شود ، معمولاً اینکار را با قرار دادن اطلاعات تکراری در جدول مربوط به همان اطلاعات انجام میدهند.
در مثال زیر یک جدول سفارش داریم که یک ارتباط یک به چند بین آیتم و سفارش ایجاد میکند.جدول آیتم یک کلید خارجی به آیتمی که خرید کرده است دارد.
Denormalization
در یک دیتابیس نرمال سازی نشده شما در یک دیتابیس اطلاعاتی را قرار میدهید که که در یک دیتابیس رابطه ای میتواند چندین ایندکس باشد
دینرمال سازی میتواند یک تفکر برای جایگزین کردن به جای جوین ها باشد
عموماً با NOSQl شما دیتا را دی نرمالایز میکنید و یا دیتای تکراری را قرار میدهید بنابراین اطلاعات با هم خوانده و نوشته میشوند
Parent-Child Relationship–Embedded Entity
این یک مثال از دینرمالایز جدول sales_item که در فوق به آن اشاره شده است می باشد
{
"_id": "123",
"date": "10/10/2017",
“ship_status”:”backordered”
"orderitems": [
{
"itemid": "4348",
"price": 10.00
},
{
"itemid": "5648",
"price": 15.00
}]
}
اگر جدول شما در یک رابطه یک به چند وجود داشته باشد این امکان وجود دارد که آن را به شکل بالا فقط در یک داکیومنت ذخیره کنید.
در مثال فوق ORDER و همه موارد مربوط به آن با هم ذخیره شدند و با هم قابل خواندن هستند تنها با یک FIND روی _ID
این کار عمل خواندن و نوشتن را بسیار بیشتر از حالت JOIN اطلاعات میکند
به خاطر داشته باشید که سایز پیش فض برای ذخیره یک ردیف 32 MB و حجم مناسب بین 50 تا 100 کیلوبایت میباشد
اگر اندازه محتویات داخلی ما بسیار زیاد است میتوانید آنها را در جای دیگر ذخیره کنید یا فقط _ID آنرا ذخیره کنید ( که البته برای اینکار برنامه شما باید به آن جدول نیزا یک کوئری بزند )
Document Model Example
یک مثال برای شبکه اجتماعی مطرح شده
2 جدول در دیتابیس داکیومنت بیس را با 4 جدول در دیتابیس رابطه ای مقایسه کنید
جزییات اطلاعات کاربر در جدول USER ذخیره میشود
لینک های ارسال شده در جدول POST ذخیره میشود
کلید ردیف شامل نام کتگوری و معکوس تایم استمپ تشکیل شده است بنابرین پست ها بر اساس موضوع و آخرین پست های تشکیل شده گروه بندی میشوند
یک کلید ثانویه در جدول وجود دارد برای اینکه چه کسی پست را ایجاد کرده است
کامنت ها در پست ها به طور embeded قرار داده شده اند
Composite Row key design
کلید هر ردیف به عنوان کلید اولیه قرار دارد ، اطلاعات به طور اتوماتیک توزیع میشود با استفاده از کلید های سورت شده . شما میتوانید چندین المنت را در یک کلید ایجاد کنید که میتواند برای گروهبندی ردیف ها بر اساس رینج کلید ها قابل استفاده میباشد . برای مثال اگر میخواهید ردیف ها را بر اساس نوع و تاریخ گروهبندی کنید از SPORT_20130712 برای کلید ردیف استفاده کنید ( اگر بر اساس جدیدترین تاریخ میخواهید تاریخ را به طور بر عکس ذخیره کنید )
اگر میخواهید رستوران ها را بر اساس موقعیت پیدا کنید باید از کلدمشابه زیر استفاده کنید
TN_NASHVL_PANCAKEPANTRY
گزینه دیگر استفاده از هش میباشد برای یک توزیع مناسب در حالی که کلید دوم همچنان وجود دارد
Generic Data, Event Data, and Entity-Attribute-Value
دیتای جنریک عموما تحت ( نام ، مقدار ) یا ( موجودیت ، ویژگی ) منتشر میشود
در دیتابیس رابطه ای ارائه این کمی مشکل است چون هر جدول یک مثال مشابه از مثال های قبلی را ارائه میدهد اما JSON گوناگونی ردیف ها را به راحتی ارائه میدهد یک مثال از بیماران یک کلینیک
patientid-timestamp, Temperature , "102"
patientid-timestamp, Coughing, "True"
patientid-timestamp, Heart Rate, "98"
این مدل داکیومنت برای بیماران یک کلینیک
کلید ردیف شامل کلید بیمار + تاریخ میباشد
این متغیر ها در جفت های (نام,مقدار) ارائه میشوند
Tree, Adjacency List, Graph Data
در اینجا یک مدل از درخت بالا نمایش داده شده است (چندین راه برای نمایش درخت وجود دارد )
{
"_id": "USA",
“type”:”state”,
"children": ["TN",”FL]
"parent": null
}
{
"_id": "TN",
“type”:”state”,
"children": ["Nashville”,”Memphis”]
"parent": "USA”
}
{
"_id": "FL",
“type”:”state”,
"children": ["Miami”,”Jacksonville”]
"parent": "USA”
}
{
"_id": "Nashville",
“type”:”city”,
"children": []
"parent": "TN”
}
هر داکیومنت یک گره از درخت میباشد . با کلید ردیف برابر با شناسه نود . فیلد parent حاوی شناسه والد میباشد . فیلد children حاوی یک آرایه از فرزندان میباشد . ایندکس ثانویه به پیدا کردن سریع والدین و فرزندان کمک میکند .
Inheritance Mapping
در مدل برنامه نویسی شی گرایی مدرن انواع ابجکت ها میتوانند با هم در ارتباط باشند . برای مثال با استفاده از extend کردن یک آبجکت مشابه آبجکت فعلی .
در شی گرایی این آبجکت ها به عنوان مثال آبجکت اصلی در نظر گرفته میشوند .
برای مقایسه و محاسبه چندین آبجکت بسیار کاربردی است اگر همه اطلاعات را در یک دیتابیس قرار دهیم ، همچنین ما باید آمادگی این را داشته باشیم که هر آبجکت ویژگی های خودش را داشته باشد و اطلاعات آبجکت والد تغییر پیدا نکند . این با روش رابطه ای مچ نیست اما به راحتی در مدل داکیومنت قابل اجراست .
این یک مثال از ارث بری یک آبجکت برای یک فروشگاه میباشد
در مثال فروشگاه آنلاین ، نوع محصول به عنوان پیشوند برای کلید ردیف قرار گرفته است ، بعضی از جفت های (نام، مقدار ) ها ممکن است متفاوت باشند و همچنین ممکن است ذکر نشوند بسته به نوع محصول . این به ما این امکان را ارائه میدهد که انواع مختلف از یک محصول را در یک جدول قرار دهیم و پیدا کردن یک گروه از محصول با نوع محصول .
در این پست یادگرفتیم که چگونه مدل کردن دیتابیس های داکیومنت بیس با دیتابیس های سنتی رابطه ای متفاوت هستند .