GHM
5 سال پیش توسط GHM مطرح شد
7 پاسخ

ساختار جدول پست و رابطه‌ی آن

سلام. از اونجایی که دسترسی به اینترنت آزاد برای جستجو ندارم مجبورم اینجا مطرح کنم.
شما همین پستی که ایجاد کردم رو درنظر بگیرید، این پست دارای اطلاعاتی هست، مثل: تعداد کامنت‌ها، بهترین پاسخ، تعداد تشکرها و حتی بوکمارک و تعداد بازدیدها، خب مرسوم‌ترین و "بهینه‌ترین" راه برای گرفتن و نمایش این اطلاعات چیه؟

1- کوئری بزنیم بین جداول مختلف و این اطلاعات رو بیرون بکشیم؟
2- یه جدول اضافه کنیم مثلا بنام post_info و اطلاعات رو اینجا ذخیره و بیرون بکشیم؟
3- این اطلاعات رو به جدول پست اضافه کنیم؟

پ.ن: قصد دارم یک cms یا بلاگ برای خودم بنویسم cmsهای مختلف هم بررسی کردم بیشتر روش دوم و سوم رو استفاده کرده بودن


ثبت پرسش جدید
علی بیات
تخصص : توسعه دهنده ارشد وب
@ali.bayat 5 سال پیش مطرح شد
2

درود

بستگی داره بخواهید چه ساختاری برای دیتابیس در نظر بگیرید.. مثلا کجا اطلاعات رو مستقیم از یه جدول بگیرید و یا کجا از روابط استفاده کنید.

مثلا همین سیستم فروم رو که اشاره کردید. یه راه خوبش اینه که یه جدول questions یا posts داشته باشیم. یکی هم برای answers یا replies . برای favorite هم جدول خودشو...

مواقعی پیش میاد شما می‌خواهید "بهترین پاسخ" رو هم پیاده سازی کنید..

  • اگر این مفهوم (بهترین بودن) قرار فقط برای یک "پاسخ" وجود داشته باشه:
    در چنین شرایطی میشه یه فیلد به همون جدول answers اضافه کنید مثلا bestAnswerBy و user_id کابر مورد نظر رو بهش بدید.

  • اما اگر قرار باشه در جاهای بیشتری از اپلیکیشن این مفهوم "بهترین" پیاده سازی بشه ... خوب بهتره جدول خودشو داشته باشه (حتی برای استفاده از Polymorphism میتونه یه جدول اضافه هم داشته باشه»» شرایطی رو در نظر بگیرید که فرضا قرار باشه کامنت‌ها و مقالات هم بهترین داشته باشند)

تعداد تشکرها و تعداد بازدید هم دقیقا مثل بهترین پاسخ هست.. تشکرها میتونه در replies باشه و تعداد بازدید در posts
و یا جداول جداگانه..

و البته هر روش خوبی و بدی خودشو داره. مثلا اگر تعداد بازدید رو در posts بگذارید خوب برای نمایشش کوئری اضافه نباید بزنید اما اگر در جدول دیگه‌ای باشه در کنار اینکه آزادی عمل بیشتری بهتون میده اما باید یه کوئری اضافه هم بزنید ( هر چند Eager-Loading قسمت عمده‌ای از این مشکل رو حل میکنه.)


Alimotreb
تخصص : کانفیگ سرور و برنامه نویس
@Alimotreb 5 سال پیش مطرح شد
1

سلام
@GHM

از نظر من برای اینکه هر کدوم رو از جدول های مختلف کوئری بزنید و به نمایش بگذارید کد خیلی زیاد میشه و اصلا منتطقی نیست.

با گزینه دومتون موافقم.
با اسکوپ ها در لاراول از طریق مدل ها هم موافقم!

ببینیم راه حل بقیه دوستان چی هست.


علی بیات
تخصص : توسعه دهنده ارشد وب
@ali.bayat 5 سال پیش مطرح شد
2

درود

بستگی داره بخواهید چه ساختاری برای دیتابیس در نظر بگیرید.. مثلا کجا اطلاعات رو مستقیم از یه جدول بگیرید و یا کجا از روابط استفاده کنید.

مثلا همین سیستم فروم رو که اشاره کردید. یه راه خوبش اینه که یه جدول questions یا posts داشته باشیم. یکی هم برای answers یا replies . برای favorite هم جدول خودشو...

مواقعی پیش میاد شما می‌خواهید "بهترین پاسخ" رو هم پیاده سازی کنید..

  • اگر این مفهوم (بهترین بودن) قرار فقط برای یک "پاسخ" وجود داشته باشه:
    در چنین شرایطی میشه یه فیلد به همون جدول answers اضافه کنید مثلا bestAnswerBy و user_id کابر مورد نظر رو بهش بدید.

  • اما اگر قرار باشه در جاهای بیشتری از اپلیکیشن این مفهوم "بهترین" پیاده سازی بشه ... خوب بهتره جدول خودشو داشته باشه (حتی برای استفاده از Polymorphism میتونه یه جدول اضافه هم داشته باشه»» شرایطی رو در نظر بگیرید که فرضا قرار باشه کامنت‌ها و مقالات هم بهترین داشته باشند)

تعداد تشکرها و تعداد بازدید هم دقیقا مثل بهترین پاسخ هست.. تشکرها میتونه در replies باشه و تعداد بازدید در posts
و یا جداول جداگانه..

و البته هر روش خوبی و بدی خودشو داره. مثلا اگر تعداد بازدید رو در posts بگذارید خوب برای نمایشش کوئری اضافه نباید بزنید اما اگر در جدول دیگه‌ای باشه در کنار اینکه آزادی عمل بیشتری بهتون میده اما باید یه کوئری اضافه هم بزنید ( هر چند Eager-Loading قسمت عمده‌ای از این مشکل رو حل میکنه.)


GHM
تخصص : دولوپر نیمه‌استک
@GHM 5 سال پیش آپدیت شد
0

@Alimotreb خیلی ممنونم از شما متاسفانه لاراول کار نکردم الان وردپرس رو نگاه کردم جدول پست‌هاش فیلد اضافی زیاد داره و تقریبا گزینه سوم رو استفاده میکنه و مابقی هم کوئری میزنه.

@ali.bayat تشکر از نکته‌سنجی شما خیلی خوب جزئیات رو درنظر گرفتید. دارم cmsها رو هم بررسی میکنم یکی از دلایلی که در برخی موارد این cmsها خیلی سنگین میشن اینکه چند و چندین کوئری میزنن برای واکشی، البته حق دارن چون یک سیستم کلی باید ارائه بدن که مورد استفاده همه باشه اما چیزی که بنده درنظر گرفتم کاستوم هست و خیلی از امکانات اضافی cmsها مورد استفاده ما نیست، بخاطر همین هسته سبک و چالاک خواهد بود.
درخصوص favorite و بهترین پاسخ و تعداد بازدید (کلا موارد غیرمستقیم) فرمایش شما کاملا صحیح و بهتره جداول جدا درنظر گرفته بشه، ولی بنظر شما برای خواندن این اطلاعات بهتر نیست یک جدول میانی مثلا post_info درنظر گرفته بشه تا مجبور به کوئری زدن بین جداول دیگه نباشیم؟ این ساختار اگر مشکلی وجود داره راهنمایی بفرمائید.

پ.ن: یک جدول کلی برای پست‌ها داریم که با فیلد post_type تفکیک میشن (مقالات و فروم و غیره...) که تقریبا میتونم همه جا استفاده‌ش کنم (در مورد صحیح بودن این ساختار هم نظرتون رو بفرمائید). تشکر پیشاپیش


علی بیات
تخصص : توسعه دهنده ارشد وب
@ali.bayat 5 سال پیش مطرح شد
1

@GHM

ببینید در خیلی از موارد ابزار الکوئنت در لاراول ، گزینه های خوبی بهمون میده.. مثلا می‌تونید از گلوبال اسکوپ ها استفاده کنید و مثلا فیلد isFavorited رو به مدل Reply اضافه کنید.. یا حتی viewCount رو...
این جوری اطلاعات برگشتی همیشه شامل این موارد که بهش append شده هست.. به همین خاطر نیازی به جدول post_info هم نداریم.

اما شما اشاره کردید با لاراول کار نکردید... هیچ مشکلی نداره . شما میتونید از ORM (Object Relational-Mapper) لاراول که همون Eloquent هست; در پروژه های PHP که Stand-Alone هستند هم استفاده کنید.
یا حتی از Doctrine که فریم‌ورک Symfony ازش استفاده میکنه.
هر دو جز گزینه های خیلی خوب هستند.
پیشنهاد من به شما اینه که اگر دارید به طور جدی روی این CMS کار میکنید حتما از یه ORM استفاده کنید و خودتون رو از انواع دردسرهای نوشتن کوئری و SQL Injection و این ها خلاص کنید.. در کنارش یه ساختار دیتابیس رابطه ای خیلی عالی هم دارید و اگر خواستید میتونید کوئری خام هم بزنید..


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

هر گاه خودتون رو در موقعیتی میبینید که دارید یک عملیات یکسان رو روی چند جور داده انجام میدید. (لایک کردن پست ها، لایک کردن مقالات، لایک کردن جواب ها) »» ۹۰٪ مواقع نشونه این هست که باید از Polymorphism استفاده کنید


علی بیات
تخصص : توسعه دهنده ارشد وب
@ali.bayat 5 سال پیش مطرح شد
1

@GHM
اما در مورد جدول پست ها:

اگر فیلد post_type شما قراره نهایتا یکی دو نوع باشه مشکلی نیست اما با بیشتر شدن انواع دچار مشکلاتی میشید نظیر اینکه باید تمام انواع رو با condition ها چک کنید و هر وقت نوع جدیدی اضافه بشه باید برگردید و سورس کد اصلی رو ویرایش کنید.
جدای از این اگر بخواهید هر کدوم از این type ها عملکردهای خاص داشته باشند برای پیاده سازیس کارمون سخت تره و کلی جاها کد تکراری داریم. مثال زیر رو در نظر بگیرید:

if ($post instanceof Article) {
    // do this
}
else if ($post instanceof Question) {
    // do that
}
else {
    // do some other thing
}

یا اینکه مثلا لازم هست مقالات رو به شکل HTML برگردونید اما سوال ها رو به شکل jSON ..در این حالت متد render ی دارید که دوباره باید از condition ها استفاده کنه

با بهره‌گیری از شئ گرایی و رعایت کردن قانون دوم سالید SOLID (O=Open for extension but Close for modification) این مشکل حل میشه.
برای بر طرف کردنش باید: رفتارهای توسعه پذیر رو با یک اینترفیس از هم جدا کنید و بعد وابستگی‌ها رو عوض کنید.

اما باز هم اگر type های شما محدوده به روشی هم که گفتید میتونید کار کنید.


GHM
تخصص : دولوپر نیمه‌استک
@GHM 5 سال پیش مطرح شد
0

@ali.bayat

ببینید در خیلی از موارد ابزار الکوئنت در لاراول ، گزینه های خوبی بهمون میده.. مثلا می‌تونید از گلوبال اسکوپ ها استفاده کنید و مثلا فیلد isFavorited رو به مدل Reply اضافه کنید.. یا حتی viewCount رو...
این جوری اطلاعات برگشتی همیشه شامل این موارد که بهش append شده هست.. به همین خاطر نیازی به جدول post_info هم نداریم.
اما شما اشاره کردید با لاراول کار نکردید... هیچ مشکلی نداره . شما میتونید از ORM (Object Relational-Mapper) لاراول که همون Eloquent هست; در پروژه های PHP که Stand-Alone هستند هم استفاده کنید.
یا حتی از Doctrine که فریم‌ورک Symfony ازش استفاده میکنه.
هر دو جز گزینه های خیلی خوب هستند.
پیشنهاد من به شما اینه که اگر دارید به طور جدی روی این CMS کار میکنید حتما از یه ORM استفاده کنید و خودتون رو از انواع دردسرهای نوشتن کوئری و SQL Injection و این ها خلاص کنید.. در کنارش یه ساختار دیتابیس رابطه ای خیلی عالی هم دارید و اگر خواستید میتونید کوئری خام هم بزنید..
در مورد Favorites بهتره دید کلی تری داشته باشید و از روابط چندریختی استفاده کنید.. ممکنه بعد از پیاده سازی فیچر لایک کردن یک سوال بخواهید یه جواب رو هم لایک کنید... و بعدش مقالات رو ... و سال بعد بخش ویدیو هم دارید .. دوباره همون داستان..
هر گاه خودتون رو در موقعیتی میبینید که دارید یک عملیات یکسان رو روی چند جور داده انجام میدید. (لایک کردن پست ها، لایک کردن مقالات، لایک کردن جواب ها) »» ۹۰٪ مواقع نشونه این هست که باید از Polymorphism استفاده کنید

خیلی ممنون از اینکه با حوصله وقت میزارید، بله قبلا از روی خامی تجربه کردم و خیلی درگیر نوشتن یه ORM و تنظیم کوئری‌ها بودم، لاراول کار نکردم اما کدایگنایتر بله، و میخوام این پروژه رو با کدایگنایتر استارت بزنم که دارای ORM هم هست.
در مورد Favorites هم فرمایش شما کاملا صحیح و مدنظر قرار میدم سعی میکنم یه ویجیت همه‌کاره پیاده کنم تا بتونم جاهای مختلفی ازش استفاده کنم و الانم دارم دیتابیس یک ماژول معروف رو بررسی میکنم که دقیقا برای همین کار هست.

اما در مورد جدول پست ها: ...

در مورد typeها میتونم بگم محدوده و فکر نکنم بیشتر از4 - 5تا بشن، من دروپال کار میکنم امروز خیلی ساختار دیتابیسش رو بررسی کردم دقیقا به همینصورت پست‌ها رو تفکیک میکنه یه جدول داره مخصوص typeها و مابقی کار هم ماژول و هوک‌ها انجام میدن و خروجی‌ها رو تنظیم میکنن، سعی میکنم فرمایشات شما رو مدنظر قرار بدم و در کنارش هم از دروپال الگوبرداری کنم، اگر نکته دیگه‌ای هست عنایت بفرمائید ممنون میشم


علی بیات
تخصص : توسعه دهنده ارشد وب
@ali.bayat 5 سال پیش مطرح شد
0

@GHM
خواهش میکنم
پیروز باشید


برای ارسال پاسخ لازم است وارد شده یا ثبت‌نام کنید

ورود یا ثبت‌نام