50٪ تخفیف روی تمام دوره‌ها!
پایان تخفیف تا:
مشاهده دوره‌ها
0

جستجوی سلسله مراتبی (درختی) درون دیتابیس

سلام به همه ی دوستان عزیز.

من یه Table ساختم که به صورت تصویر زیر است:

سلام به همه ی دوستان عزیز.
من یه Table ساختم که به صورت تصویر زیر است:

||http://tosinso.com/files/get/2a10f666-8dc1-4dcb-bfc6-5bc5d2fb549b||

اگه دقت کنید میبینید که هر رکورد میتونه به رکوردهای دیگه وابسته باشه , وابسته بودن به صورت درخت و ریشه میخوام در نظر گرفته برای مثال به تصویر زیر دقت کنید.

در اینجا اگه owner_id برابر با منفی یک (-1) باشه یعنی یه رکورد به هیچ شاخه یا ریشه ای متصل نیست. اما اگه owner_id مقداری غیر عدد منفی یک داشته باشه شاخه در نظر گرفته میشه.
من میخوام که اگه ایدی (id) یک رکورد رو جستجو کردم کل درختی که این رکورد عضوی از اون هست بهم داده بشه. مثلا من در اینجا اگه id=2 رو وارد کنم کل درختی که همچین رکوردی توشه بهم داده بشه. 
رابطه فرزند بودن با استفاده از owner_id مشخص میشه. میخوام یه تابع به زبان PHP یا کوئری sql باشه که اگه ایدی یه عضو از درخت رو دادم بتونه کل درخت رو بهم برگردونه

اگه دقت کنید میبینید که هر رکورد میتونه به رکوردهای دیگه وابسته باشه , وابسته بودن به صورت درخت و ریشه میخوام در نظر گرفته برای مثال به تصویر زیر دقت کنید.

در اینجا اگه ownerid برابر با منفی یک (-1) باشه یعنی یه رکورد به هیچ شاخه یا ریشه ای متصل نیست. اما اگه ownerid مقداری غیر عدد منفی یک داشته باشه شاخه در نظر گرفته میشه.

من میخوام که اگه ایدی (id) یک رکورد رو جستجو کردم کل درختی که این رکورد عضوی از اون هست بهم داده بشه. مثلا من در اینجا اگه id=2 رو وارد کنم کل درختی که همچین رکوردی توشه بهم داده بشه.

رابطه فرزند بودن با استفاده از owner_id مشخص میشه. میخوام یه تابع به زبان PHP یا کوئری sql باشه که اگه ایدی یه عضو از درخت رو دادم بتونه کل درخت رو بهم برگردونه

پرسیده شده در 1394/11/27 توسط

14 پاسخ

0

اول اینکه owner-id اصلا موقعیت قطعی یک نود توی درخت رو مشخص نمیکنه. مثلا با owner-id برابر با 5 به شما بگن نود رو روی درخت مشخص کنید می تونید مشخص کنید؟ به نظرم این جدول یه نقصی داره و نمیتونه بیانگر یک درخت باشه.

و دوم اینکه گفتین کل درخت رو برگردونه ، یعنی شما توی جدول دیتابیستون بیش از یک درخت رو می خواین ذخیره کنید یا نه منظورتون این بوده که کل درختچه ای که نود ریشه اش همان نود ورودی x باشه رو می خواین پیداا کنید؟

پاسخ در 1394/11/27 توسط
0

دوست گرامی من نیاز به ایجاد root-id ندارم چون میتونم به راحتی root رو حرکت کنم. کافیه که تا موقعی که به null برسم همش بگم والد این child چیه مثلا من الگوریتم زیر رو دیروز نوشتم :

		public function postRootId($postid){
			$this->show_class_byID($postid);
			$post_data=$this->database->fetchAll();
			if(empty($post_data[0])){
				//post not found-->node not found
				return '-4';
			}
			//change index
			$post_data=$post_data[0];
			$owner_id=$post_data['owner_id'];
			while($owner_id!=='-1'){

				$this->show_class_byID($owner_id);
				$post_data=$this->database->fetchAll();
				if(empty($post_data[0])){
					//post not found-->head node not found
					return '-3';
				}
				//change index
				$post_data=$post_data[0];
				$owner_id=$post_data['owner_id'];
				//head id
				$root_id=$post_data['id'];
			}

			return $root_id;

		}

شما ذهن خودتون رو درگیر پیدا کردن root نکنید. فقط میخوام بدونم اگه یه root رو بهتون بدم چجوری تمامی گره های زیر مجموعه ی این root رو میشه لیست کرد؟ دقت کنید که هر گره خودش باز ممکنه زیر گره داشته باشه و میخوام اون زیرگره ها لیست بشن تا به اخر (خود زیر گره ها باز زیر گره دارند و... همه لیست بشن)

پاسخ در 1394/11/28 توسط
0

حالا این شمایی که خوب دقت نمیکنید به حرفی که من چند بار تکرار کردم بابا من دارم میگم یه فیلد جدول دیتابیس رو بذار root-id شما میگی درگیر پیدا کردن root نکن خوب حرفم با حرف شما متفاوته حس کردم متوجه منظورم نشدید واسه همین چند بار پرسیدم. :)

خودتون رو ناراحت نکنید دوست عزیز من می تونم کل اون چیزی که میخواین رو بدون root-id هم براتون بنویسم اما کدش زیاد میشه واسه همین گفتم اول بهترین راه رو پیشنهاد کنم.

باز هم اگه رو حرف خودتون اصرار دارید برای پیدا کردن child ها دو حلقه تودرتو نیاز هست چون به گفته خودتون هر والد چند child می تونه داشته باشه بنابراین نتیجه ای که کوئری یافتن child بر می گردونه شامل یک یا بیش از یک رکورد خواهد بود و شما باید یک while داخلی برای fetch کردن تک تک رکوردها داشته باشید.

ببخشید اگه کدش زیاد نبود براتون کامل می نوشتم.

پاسخ در 1394/11/28 توسط
0

شما برای ساختن قسمت کامنت ها (نظرات) به طوری که به هر نظر بشه جواب داد و این جواب دادن به هر نظر بتونه تا عمق بی نهایت ادامه داشته باشه چیکار میکنید؟ داده ها رو به چه صورت ذخیره میکنید؟ من از ownerid استفاده میکنم. هر نظری که ownerid داشته باشه به معنی این هست که پاسخ به نظر دیگه ای هست. امیدوارم متوجه شده باشید.

پاسخ در 1394/11/27 توسط
0

این یک child رو نشون میده! حالا خود child ممکنه child های دیگه ای داشته باشه!!!

پاسخ در 1394/11/28 توسط
1

سلام. ownerid موقعیت یک نود رو مشخص نمیکنه بلکه مشخص میکنه یک نود شاخه ی کدام نود دیگر است. به من بگن نود 5 رو مشخص کنید من این کار رو بر اساس id انجام میدم. میبینم کدوم رکوردها ownerid برابر با 5 دارن و لیست میکنم و همچنین در این لیست باز باید شاخه ها بررسی بشن (به صورت بازگشتی).

برای اینکه بهتر متوجه بشید اینجا رو ببینید

همینجوری عکساشم نگاه کنید متوجه میشید منظورم چیه. مشکلی در Table و تعداد فیلدهای بنده وجود نداره.

پاسخ در 1394/11/27 توسط
0

نه منظورم اینه که اگه root-id به عنوان یک فیلد به ازای هر رکورد تکمیل بشه اونوقت برای پیدا کردن کل درخت کافیه یه دستور کوئری ساده بزنیم و دیگه به حلقه عقبگرد و جلوگرد نیاز نداریم. کوئری میشه این:

$q='select * from `table-name` where `root-id`in (select `root-id` from `table-name` where `id`="'.$id.'") ';
$result=mysql_query($q);

نه منظورم اینه که اگه root-id به عنوان یک فیلد به ازای هر رکورد تکمیل بشه اونوقت برای پیدا کردن کل درخت کافیه یه دستور کوئری ساده بزنیم و دیگه به حلقه عقبگرد و جلوگرد نیاز نداریم. کوئری میشه این:
<php>
$q='select * from `table-name` where `root-id`in (select `root-id` from `table-name` where `id`='.$id.') ';
$result=mysql_query($q);
<php>

||http://web.tosinso.com/files/get/49d86cfe-0169-4c5b-81eb-e524954b99bd||
پاسخ در 1394/11/28 توسط
0

میشه با یه حلقه انقد به عقب رفت که root رو پیدا کرد و بعدش از root حرکت کرد و اجداد رو لیست کرد. من حلقه ی حرکت به root رو خودم نوشتم . فقط میخوام که هر id که دادم اجدادش لیست بشن. حالا به هر صورتی که هست مهم نیست. با sql اگه باشه بهتره اما با php هم مشکلی نداره.

پاسخ در 1394/11/28 توسط
0

خیر parent رو نشون میده . خوب عزیز باید بذاری اینو توی حلقه دیگه. شما خودتون گفتید حلقه رو نوشتید

جواب سوال منو ندادید با روش 3 موافق نیستید یا متوجه منظورم نشدید؟

پاسخ در 1394/11/28 توسط
0

اقا من این الگوریتم رو خودم نوشتم. اما یه مسئله ی دیگه باقی مونده. چجوری میشه تمام child های یه درخت رو لیست کرد؟ یه الگوریتم میخوام.

مثلا من الان گره ی mahdi رو که میدم یه ارایه بهم بده بگه گره های ali ,hossein ,sadegh ,askhan توی درختی که اگه ریشه mahdi باشه وجود داره.

پاسخ در 1394/11/28 توسط
0

بله حق باشماست خوب دقت نکردم .

خوب حالا اگه میخواین کلا در mysql به جواب برسین فکر می کنم چاره ای جز نوشتن procedure ندارید

اما اگه میخواین توی کد برنامه تون به درخت دست پیدا کنید باید دو حلقه هر بار یک query ساده رو فراخوانی کنید که حلقه اول برای یافتن اجداد باشه و حلقه دوم برای یافتن نسل آینده

یه راه دیگه هم هست که به نظرم منطقی و خوب هست و اون اینه که یک فیلد root-id هم به جدول اضافه کنید تا مشخص بشه کدوم رکوردها مال یک درخت هستند . در نگاه منطقی هم برای مثالی که زدید یک بحث که پشت سرش چند تا نظر یا پاسخ میاد کلا می تونه به عنوان یک موجودیت در نظر گرفته بشه مثلا موجودیت بحث یا موجودیت سوال و بنابراین root-id بهش اختصاص داده بشه.

پاسخ در 1394/11/27 توسط
0

از راه سوم نمیخواید استفاده کنید؟

روش استفاده از حلقه یا نوشتن یک procedure توی mysql مرتبه زمانی بیشتری نسبت به روش سوم داره و در عوض روش سومی که گفتم مرتبه زمانی پائینی داره ولی مرتبه مکانی بالاتری داره (یعنی زمان پردازش خیلی پائین میاد ولی خوب به دلیل ذخیره یک فیلد بیشتر به ازای هر رکورد ، فضای بیشتری از حافظه رو اشغال میکنه)

برای همین به نظر من که روش سوم آسوده خاطر تر هست حالا باز هم هر جور صلاح می دونید

دستور query که در کد php توی حلقه باید اجرا کنید تا Id والد هر گره از بانک واکشی بشه به صورت زیر هست:

دقت کنید که متغیر $id همان آی دی والدی هست که در مرحله قبل حلقه واکشی شده

$result=mysql_query('select `owner-id` from `table-name` where `id`="'.$id.'"');
پاسخ در 1394/11/28 توسط
0

خودم با استفاده از پشته و درخت هیپ پیاده سازیش کردم تموم شد :-D بازم مرسی

پاسخ در 1394/11/28 توسط

پاسخ شما