PDA

View Full Version : خروجی اطلاعات کشورها و استانها توسط رابطه بین مدل ها



rahahost
جمعه 28 آبان 1395, 11:32 صبح
سلام دوستان ، وقت همگی بخیر .

من یه مدل برای کشورها ، استانها دارم به اسم :
Tourlocation

یه مدل هم دارم برای معرفی تورها ( Tour ) اون کشورها و استانها که به رابطشون به این شکله :
رابطه کشور و استانها : یک به چند
رابطه استان به کشور : یک به یک
رابطه کشور به تور : چند به چند
رابطه استان به تور : چند به چند


هر تور میتونه به تنهایی برای یک کشور باشه و همچنین میتونه شامل استانهای زیادی هم بشه ( مثلا تور های ترکیبی که میتونه شامل چندین استان و کشور بشه )



حالا مسئله اینجاست :
وقتی میخوام تورهای یک کشور رو با تورهای استانهای اون کشور بگیرم ، مشکل دارم و در دو مرحله باید انجام بشه :

اینطوری تورهای اون کشور رو میگیرم :
$country->tours

اینطوری هم تورهای استانهای اون کشور رو ببینم :
$country->province->tours


تو این حالت اگر یک تور درون یک کشور و یکی از استانهای اون کشور ثبت شده باشه ، یکبار درون تورهای اون کشور و یکبار درون تورهای استانهای اون کشور نمایش داده میشه

با groupBy هم نتونستم خروجی رو یونیک کنم




$country = \App\Tourlocation::where('slug' , '=' , $slug)->where('type', '=', 1)->with(['tours', 'province.tours' => function($query){
$query->orderBy('tours.id' , 'DESC')->groupBy('id');
} ])->first();




دقیقا قاعده دسته ها ، زیر دسته ها و پست ها رو ایجاد دارم که هر پست میتونه درون یک دسته و زیر دسته های همون دسته قرار بگیره و از طرف دیگه میتونه یک دسته زیر دسته نداشته باشه و پست به تنهایی درون دسته والد قرار بگیره

plague
جمعه 28 آبان 1395, 19:20 عصر
من نمیتونم زیاد کمکی بکنم چون ساختار دیتابیس رو نزاشتی

ولی فرض کن داری با یه آدم حرف میزنی بجای دیتبایس
بهش میگی برو تور های کشور ایران رو بیار همچنین تور های استانهای کشور ایران رو بیار
اونوقت اون آدمه بهت میگه این منطقی نیست چون تور های کشور ایران شامل استانهاش هم میشه مگه اینکه یه ساختار خیلی اشتباه داشته باشی برای ذخیره کردن داده ها



همچنین groupby وقتی جواب میده که بخای داده های تکراری رو گروه بندی کنی فیلد id توی تیبل که مقدار تکراری نداره که بخای گروه بندی کنی چیزی رو باهاش !

خلاصه کوئریهات اشتباه و احتمالا ساختار دیتابیست هم اشتباهات فاحشی داره مشخصا تیبل تور ها

همچنین من زیاد با ORM لاراول ور نرفتم و نمیدونم این first که گزاشتی ته کوئری جواب میده یا نه ولی معمولا کوئری که 1 ردیف داره خروجی رو با کوئری که چندین ردیف خروجی داره کسی جوین نمیکنه چون بهینه و منطقی نیست و 2 تا کوئری جدا مینویسن براش (بگزریم که معلوم نیست Tourlocation چیه اصلا !! )

rahahost
شنبه 29 آبان 1395, 20:03 عصر
اون مورد حل شد ولی جواب سوالتون :
برای اینکه ساختار دیتابیسم به چندین دلیل طوریه که کشور ها و استانها درون یک جدول هستن ، مجبورم اینطوری شرط رو تعریف کنم .

درسته ، از groupBy برای دسته بندی تکراری ها استفاده میشه منم تکراری دارم دیگه :
مثلا یک تور هم میتونه برای کشور ایران باشه و هم یکی از استانهای ایران ( تورهای ترکیبی )

اصلا این صورت مسئله رو بزاریم کنار ، قضیه دسته و زیر دسته هم دقیقا همین قاعده رو داره
فرض کنی شما یک پست دارید که میتونه تو دسته والد هم قرار بگیره و همزمان شامل دسته زیر مجموعه اون والد هم باشه ، درسته ؟


اون first هم میگه با اون شرطی که گذاشتم ، اولین رکورد رو بگیر ، حالا با اون with دارم رابطه هامو فراخوانی میکنم ( مفهوم یک به چند )

جدول tourlocations هم برای نگهداری اطلاعات کشورها و استانها هستش

plague
یک شنبه 30 آبان 1395, 21:17 عصر
اون مورد حل شد ولی جواب سوالتون :
برای اینکه ساختار دیتابیسم به چندین دلیل طوریه که کشور ها و استانها درون یک جدول هستن ، مجبورم اینطوری شرط رو تعریف کنم .

اول اینکه میتونید اصلاح کنی و جدا کنید کشور و استانها رو
دوم اینکه ربطی به این نداره تو تیبل تور ها فیلد country_id , province_id بزار و آیدی استان و کشور رو جدا ذخیره کن برای هر تور
توی کوئریت دیگه اصلا نیاز نیست اسم از استانها بیاری بر اساس country_id بخونشون همه تور های استانها هم میاد

الان با ساب کوئری ها 4 تا کوئری اجرا میشه برای گرفتن تور ها که منطقی نیست و میتونید بهینه کنید با تغییرات تو ساختار دیتبایس این رو



درسته ، از groupBy برای دسته بندی تکراری ها استفاده میشه منم تکراری دارم دیگه :
مثلا یک تور هم میتونه برای کشور ایران باشه و هم یکی از استانهای ایران ( تورهای ترکیبی )



ببین شما داری از یه سری تیبل میخونی داده ها رو که کار نداریم چین و بر اساس فیلد id داری گروپ میکنی
فیلد آیدی یکتا هستش مشخصا و مقدار تکراری نمیگیریه هیچوقت
بنا بر این عملا گروپ شما بود و نبودش فرقی نداره و هیچ کار خاصی نمیکنه
من مشکلی با گروپ کردن ندارم میگم فکر میکنم فیلدتون اشتباه باشه
حتی اگه جوین بکنید (که فکر میکنم لاراول از ساب کوئری استفاده میکنه ) من فکر میکنم شما داری رویprovince.id گروپ میکنی

راه سادش اینه که کوئری رو چاپ کنی تا متوجه بشی دقیقا چه کوئری اجرا شده





اون first هم میگه با اون شرطی که گذاشتم ، اولین رکورد رو بگیر ، حالا با اون with دارم رابطه هامو فراخوانی میکنم ( مفهوم یک به چند )
بله منم میدونم first چیه و عرض کردم که یک به چند رو توی یک کوئری نمیگیرین معمولا بلکه 2 تا کوئری مینویسن



اصلا این صورت مسئله رو بزاریم کنار ، قضیه دسته و زیر دسته هم دقیقا همین قاعده رو داره
فرض کنی شما یک پست دارید که میتونه تو دسته والد هم قرار بگیره و همزمان شامل دسته زیر مجموعه اون والد هم باشه ، درسته ؟
اگه 1 دسته و 1 زیر دسته باشه برای هر پست 2 فیلد دسته و زیر دسته قرار میدن که مشخص میکنه این پست ماله کدوم دسته و کدوم زیر دستست
اینجا از رابطه استفاده نمیکنن برای همچین سناریویی
چون باعث میشه کوئری ها سنگین و غیر بهینه بشن که در تعداد خیلی بالا باعث کند شدن سایت میشه

اگرم چندین تا دسته و زیر دسته باشه که نرمال سازی میکنن که بحثش جداست