سلامی مجدد استاد .
ادامه ی پست قبلی (بی زحمت ، مطالب زیر را برای درست بودنش ، چک میکنید) :
ارتباطات جداول در sql :
ارتباطات جداول در sql ، سه نوع هستن :
1- ارتباطات یک به یک :
وقتی
به ازای هر سطر از یک جدول ، نیاز باشه که داده ای را فقط یه سطر از یه جدول دیگه ذخیره کنیم (یا کلا باهاش ارتباط برقرار کنیم) ، به این ارتباط ،
ارتباط یک به یک در دو جدول میگن .
در این ارتباط ،
داده هایی که در هر رکورد از ستون (صفت) از هر دو جدول قرار میگیره ، به هیچ عنوان نباید مشترک باشن (و فقط باید منحصر به فرد باشن) وگرنه نوع ارتباط شون ، "یک به n" یا "n به n" میشه .
در عکس زیر :
نوع رابطه را در نمودار ER ، درون لوزی رسم میکنن .
همچنین در عکس زیر :
رابطه ی جدول (در واقع موجودیت) "استاد" و جدول "درس" در دو عکسِ بالا ،
زمانی "رابطه ی یک به یک" هست که فقط به ازای هر رکورد از استاد ، یک رکورد از درس (که هر دوشون نباید مشترک باشن) ، ثبت بشه .
یعنی تا زمانی رابطه ی "یک به یک" هست که اگه دو رکورد در جدول "استاد" داریم (رکورد با مقدار ID های شماره های 1 و 2 در جدول "استاد" داریم . مثلا ستون "نام" ، برای رکورد 1 ، مقدار "حسن" و برای رکورد 2 هم مقدار "قاسم" باشه) ، و همچنین دو رکورد در جدول "درس" داریم (برای این هم ، رکورد با مقدار ID های شماره های 1 و 2 در جدول "درس" داریم . مثلا ستون "عنوان" ، برای رکورد 1 ، مقدار "ریاضی" و برای رکورد 2 هم مقدار "فیزیک" باشه) ، اولا ، استادی بنام "حسن" ، فقط میتونه یه درس را بگیره (فرضا فقط میتونه درس "فیزیک" را بگیره) و دوما در صورتی که این درس "فیزیک" را قبلا ، استادِ دیگه ای نگرفته باشه (یعنی در صورتی میتونه "فیزیک" را بگیره که قبلا استادی بنام "قاسم" ، نگرفته باشه) .
همچنین یک درس هم فقط توسط یک استاد میتونه گرفته بشه . یعنی درس "فیزیک" ، فقط توسط یک استاد (مثلا استادی بنام "حسن") گرفته بشه .
یعنی در هیچ ارتباطی از رکوردهای دو جدول ، مشترک نشن .
وگرنه اگه مشترک بشن ، رابطه شون ، حداقل ، به "یک به n" (یا "n به n") تغییر پیدا میکنه .
- دوما ،
نکته ی مهم در این نوع ارتباطِ یک به یک ، اینه که
کلید خارجی را در کدوم یک از این جدول ها بذاریم (در واقع تعیین اینکه کدوم جدول ، جدول فرزند بشه) :
اطمینان 100 درصد ندارم اما تا جایی که تا حالا متوجه شدم ، اول باید ببینیم جدول اصلی مون کدوم هست .
جدول اصلی مون هم احتمالا اون جدولی میشه که میخوایم بر پایه ی اون ، جستجو انجام بدیم .
یعنی فرضا اگه در اینجا بخوایم بر اساس نام (یا id و کلا بر اساس جدولِ) استاد ، جستجو مون را انجام بدیم ،
پس جدول "استاد" ، جدول اصلی مون یا همون جدول والد مون میشه . بنابراین جدول مقابل ، یعنی جدول درس ، جدول فرزندمون میشه و چون جدول فرزند هم جدولی هست که ستون (صفت) با کلید خارجی درون اون جدول تعریف میشه ، پس اگه در شکل بالا ، بخوایم بر اساس جدول "استاد" جستجو کنیم (که در این صورت ، این جدول ، جدول والدمون میشه) ، پس
کلید خارجیِ این جدول را درون جدول "درس" قرار میدیم .
یعنی مثل عکس بالا ، یه ستون (یا صفت ای) فرضا بنام "ProfessorID" یا بنام "MasterID" (فیلد قرمز در عکس دوم در بالا) را درون جدول درس قرار میدیم که این ستون ، به ستونِ ID در جدول "استاد" اشاره کنه و این ستون (قرمز رنگ) ، کلید خارجی هم هست .
-
یا اینکه اگه میخوایم بدونیم که ستون (صفتی) که کلید خارجی داره را درون کدوم جدول قرار بدیم ،
توسط مدل سازیِ شی گرا اش عمل میکنیم .
در این مدل سازی ،
یک کلاس "استاد" و یک کلاس "درس" میسازیم . چون کلاس استاد ، عضوی از نوع کلاس "درس" را توی خودش داره (و این عضو در کلاس استاد ، به شی ای از کلاس "درس" اشاره میکنه) ، پس در مدل سازیِ دیتابیس اش هم همونطور که در بالا توضیح دادیم میشه . یعنی ستون "MasterID" ، به عنوان کلید خارجی ، در جدول "درس" قرار میگیره تا مثل مدل سازیِ شی گرا اش ، ستونِ ID در جدول "استاد" ، به ستون "MasterID" در جدول "درس" که کلید خارجی هست ، اشاره کنه (
کلید اصلی هم که همیشه به کلید خارجی اشاره میکنه . البته در صورت وجود داشتن کلید خارجی در یک جدول دیگه) .
و کدش هم بصورت زیر میشه :
SQL:
SELECT Name, Family, Title
FROM tblMaster inner join tblLesson
ON tblMaster.ID = tblLesson.MasterID
- و اگه برعکس اش را بخوایم ، یعنی بخوایم طبق جدول "درس" ، جستجومون را انجام بدیم ، در این صورت ، ستونی به عنوان کلید خارجی ای در جدول "استاد" میذاریم که ID ئه جدول "درس" ، بهش اشاره کنه .
و البته شاید بشه که در هر دو جدول ، کلید خارجیِ جدول دیگه را قرار بدیم (نمیدونم) .
2 - ارتباطات یک به n (یا همون یک به چند) :
یعنی به ازای هر رکورد در یک فیلد ، یک یا چند رکورد در فیلدی دیگه بتونیم ذخیره کنیم . و در این نوع ارتباطات ، ستون و فیلدی که چندین مقدار را ممکنه به ازاش ثبت بشه را در جدولی مجزا منتقل میکنیم .
اولا وقتی از این نوع ارتباطات نام میبریم ، ممکنه به ازای هر رکورد ، فقط یک رکورد در فیلد و ستون متناظرش ثبت بشه (اما امکان این هست که چندین مقدار ثبت بشه) . مثل آرایه ها که ممکنه یک آیتم داشته باشن اما ممکنه چندین آیتم هم داشته باشن .
- نکته ای که بسیار مهم هست اینه که در این نوع ارتباطات ، کلید خارجی ، در سمت جدولی قرار میگیره که رابطه ی "n" داره . و به این ترتیب ، اون جدول ، جدول فرزند میشه .
یعنی اگه در شکل اول در این پست ، رابطه بصورت "1 : n" بود ، یعنی بصورت شکل زیر بود :
- اولا در شکل بالا ، یعنی به ازای یک "استاد" (یا همون به ازای یک رکورد از "استاد") ، بشه یک یا چند رکورد از "درس" را ثبت کرد . یا به عبارتی دیگه ، هر استاد بتونه چند تا درس را بگیره (مثلا استادی بنام "حسن" ، بتونه یک ، یا چند درسِ "ریاضی" و "فیزیک" و ... را بگیره) .
اما نکته ای که بسیار مهم در این رابطه هست اینه که هر درس ، فقط توسط یک استاد خاص ارائه بشه . یعنی یک درسی مثل فیزیک را چند تا استاد نتونن ارائه کنن (چون در این صورت ، رابطه ، "n به m" میشه) :
تصویر بالا ، رابطه ی یک به چند (یک به n) هست . چون هر استاد ، میتونه چند تا درس (که مشترک نباشن) را انتخاب کنه) .
اما تصویر بالا ، رابطه ی
یک به چند
نیست (رابطه ی یک به n نیست) .
بلکه رابطه ی
چند به چند (یا n به m)
هست . چون هر درس ، توسط چندین استاد (اون هم بصورت مشترک) انتخاب شده و همچنین برعکس (یعنی هر استاد ، چندین درس را گرفته اون هم بصورت مشترک) .
- و دوما ، کلید خارجی در اینجا (در 3 شکل بالاتر یا همون شکل شماره ی 3 در این پست) ، در جدولی که سمتِ n هست ، میذاریم . یعنی در عکس بالا ، ستونی به عنوان کلید خارجی را در جدول "درس" میذاریم و بنابراین جدولی که سمتِ n هست (در اینجا ، جدول "درس") ، در این نوع رابطه ، همیشه جدول فرزند میشه (یعنی مثل عکس دومی میشه که ستونی بنام "ID ئه استاد" یا همون "MasterID" را داشت) .
3 - ارتباطات n به m (یا چند به چند یا همون n به n) :
یعنی به ازای یک رکورد ، بتونیم چندین رکورد (در جدول دیگه) ، ذخیره کنیم و همچنین برعکس . اینکه اشتراکی هم بین شون بوجود بیاد ، اصلا مهم نیست .
یعنی هر استاد میتونه ، هر درسی را انتخاب کنه (هر چند تا که باشن) و هر درسی هم میتونه توسط هر استادی انتخاب بشن (هر چند تا که باشن) .
دقیقا مثل شکل بالا .
- نکته ی بسیار مهمی که هست اینه که در این نوع ارتباطات ، هیچ کلید خارجی ای درون یکی از این دو جدول قرار داده نمیشه (منظورم کلید خارجی ای هست که قرار باشه ارتباطات این دو جدول را مشخص کنه ها) .
بلکه ستونِ مربوط به کلید خارجی (در این نوع رابطه) ، در جدولِ مجزایِ دیگه که بهش میگن جدول فصل مشترک ، قرار داده میشه :
در شکل بالا ، چون رابطه ی دو جدولِ "استاد" و "درس" ، رابطه ای n به n هست ، پس ستونِ کلیدِ خارجیِ مربوط به هر دو جدول ، درون جدولی دیگه قرار میگیره که در مثال بالا ، اسم این جدول ، "سکشن" نامیده شد .
و طبق شکل بالا ، دو ستونِ
کلید خارجی ، در جدول "سکشن" قرار داره که ستونِ ID ئه دو جدول های "استاد" و "درس" ، بهشون اشاره میکنه (ستون های قرمز رنگ در جدول "سکشن" ، کلیدهای خارجی هستند) .
- در شکل بالا (در این نوع ارتباطات) ،
برای ارتباط برقرار کردن بین جدول "استاد" و جدول "درس" ، چون جدول "استاد" ، با جدولِ "سکشن" ارتباط داره ، پس یک join ای بین این دو جدول مینویسیم و نتیجه اش را مجددا با join ای بین جدول "درس" و جدول "سکشن" خاتمه میدیم چون جدول "درس" هم با جدول "سکشن" ارتباط داره .
(اگه بعدش هم جدول دیگه ای هم خواستیم join کنیم ، بعد از اون میکنیم) .
در واقع برای این نوع ارتباطات (مثل شکل بالا) ، کافی هه از خودمون بپرسیم که بین کدوم جدول ها رابطه هست و نتیجه شون را با هم join کنیم .
یعنی برای ارتباط بین "استاد" و "درس" ، چه رابطه ی مشترکی بین شون قرار داره؟
یکی رابطه ی "استاد" و "سکشن" وجود داره . پس بین شون join میکنیم .
یکی دیگه هم رابطه ی "درس" و "سکشن" وجود داره . پس نتیجه ی قبلی را با این یکی join میکنیم .
و از اونجایی هم که inner join (بر خلاف left یا right join) ، فقط رکوردهای مشترک را بین دو جدول انتخاب میکنه ، اهمیتی نداره که کدوم جدول را برای join ، اول یا آخر بنویسیم . یعنی تقدم و تاخر برای inner join ، معنا نداره .
یعنی کد این نوع رابطه ، بصورت زیر میشه :
SQL:
SELECT Name, Family, Title
FROM tblMaster inner join tblSection ON tblMaster.ID = tblSection.MasterID
inner join tbLesson ON tblLesson.ID = tblSection.LessonID
این مطالب (که اغلب اش توسط اون کتاب و مخصوصا اون آموزش که بهش اشاره کردم گفته شد و همچنین درک من از این مطالب هست) ، درست هستن؟
سئوال را در پست بعدی میپرسم .
خیلی ممنون استاد .
ببخشید که خیلی طولانی شد .