تا این قسمت در مورد انواع روابط بین داده ای صحبت کرده ایم و حالا من می خواهم یک پروژه ساده را نیز پیاده سازی کنیم (پایگاه داده یک وبلاگ). من اطلاعات اولیه این پروژه را به شما می دهم و انتظار دارم که بتوانید ساختار یا schema را برای پایگاه داده طراحی کنید. پروژه ما بدین شکل است:
ما برنامه ای خواهیم داشت (چه یک وب سایت چه یک برنامه موبایلی و هر چیز دیگر) که در آن کاربر می تواند چند عمل اصلی را انجام دهد:
ما در این پروژه هیچ کد PHP یا Node.js یا زبان های برنامه نویسی دیگر را نمی نویسیم و فقط با shell کار می کنیم. هدف اصلی ما تعریف schema برای پایگاه داده است. تصویر خلاصه ای که بالاتر به شما داده ام برای این است که نحوه اجرای یک برنامه واقعی را درک کنید. یعنی در یک پروژه واقعی سروری خواهیم داشت (این سرورِ اصلی و فیزیکی شما است و با سرور MongoDB فرق دارد) که حامل کد های شما است (PHP یا Node.js یا هر زبان دیگری) و این کد ها از یک درایور استفاده خواهند کرد تا بتوانند با MongoDB تعامل داشته باشند. در نهایت تعاملات و کوئری های برنامه شما، به سرور MongoDB ارسال می شود.
نکته: برای حل این مسئله انواع و اقسام روش ها وجود دارد و ممکن است روش من با شما فرق داشته باشد و این مسئله بدین معنی نیست که روش شما غلط است.
در مرحله اول باید مشخص کنیم که چه دسته بند هایی برای داده ها داریم:
در مرحله دوم باید مشخص کنیم که هر کدام از این دسته بندی ها، چه نوع داده هایی را درون خود نگه می دارند. من انواع داده را در سه مرحله جدا برای هر کدام از این سه دستی بندی مشخص می کنم. توجه کنید که اطلاعات ذکر شده بر اساس سلیقه من است. مثلا ممکن است شما نخواهید سن کاربر را دریافت کنید اما من می خواهم این کار را انجام بدهم بنابراین پاسخ من را به عنوان یکی از پاسخ های صحیح در نظر بگیرید.
برای user یا کاربران:
برای post یا پست های ما:
برای comment یا کامنت های کاربران:
سوال سوم اینجاست که این داده ها چطور به یکدیگر مرتبط می شوند؟ می توان گفت:
این روابط اصلی ما هستند و روابط دیگری وجود ندارد (مثلا از نظر فنی هر پست نمی تواند توسط چند کاربر نوشته شود و در نهایت یک حساب کاربری است که پست را آپلود می کند). حالا برای مدل سازی چندین راه حل وجود دارد که من دو مورد از آن ها را بررسی می کنم.
راه حل اول: یک راه حل اینطور است که فقط یک collection به نام posts داشته باشیم. در این collection که نگهدارنده پست های ما است، یک فیلد اضافی به نام user خواهیم داشت که خودش یک embedded document است و اطلاعات کاربر را درون خود نگه می دارد. سپس فیلد دیگری به نام comments خواهیم داشت که آرایه ای تو در تو باشد و هر عضو آن یکی از کامنت های آن پست باشد.
نقد راه حل اول: آیا این مدل سازی صحیح است؟ قسمتی از آن بله اما قسمتی از آن صحیح نیست. من مشکلی با embed کردن کامنت ها درون post ندارم چرا که کامنت ها و پست ها رابطه «یک به چند» دارند (یک پست چندین کامنت دارد اما هر کامنت فقط برای یک پست خواهد بود). همچنین در اکثر اوقات یک پست را به همراه کامنت های آن نشان می دهیم و نیازی به جداسازی و دریافت جداگانه آن ها نیست. با این حال nest کردن کاربران (user) کار صحیحی نیست. اگر ما کاربری را درون post بگذاریم (embed شود) با مشکل بزرگی مواجه می شویم. هر کاربر می تواند ده ها یا صد ها پست بگذارد و در همین ابتدا data duplication خواهیم داشت. همچنین اگر کاربر اطلاعات خود را تغییر دهد (مثلا ایمیل خود را عوض کند) ما باید آن را در صد ها پست مختلف ویرایش کنیم تا اطلاعات نویسنده سایت ما بر اساس آخرین نسخه موجود نمایش داده شود (نمی شود که اطلاعات یک نویسنده در صفحات مختلف وب سایت فرق داشته باشد). به همین دلیل نظر من این است که دو collection داشته باشیم.
راه حل دوم: راه حل بهتر این است که یک collection برای کاربران (user) و یک collection برای پست ها (post) داشته باشیم و کامنت (comment) ها را درون post به صورت تو در تو قرار بدهیم. در قسمت بعد شروع به کار خواهیم کرد.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.