ورود

View Full Version : معایب گرفتن کلید ترکیبی در جداول چیست؟



veniz2008
جمعه 23 فروردین 1392, 18:52 عصر
سلام دوستان.
من یکی دو سوال در طراحی جداول برام پیش اومده.
یه سیستم ساده ثبت اطلاعات دانشجو با 3 جدول : 1. دانشجو (شماره دانشجویی کلید باشه). 2. درس(فیلد کلید کد درس) 3. اخذ درس رو در نظر بگیرید.
فرض رو بر این بگیرید که این طراحی درست باشه (که قطعا نیست و نیاز به اصلاح داره).
سوال من درباره طراحی جدول اخذ هست. کلید قاعدتا باید حداقل 4 فیلد سال تحصیلی،شماره ترم، شماره دانشجویی و کد درس رو شامل بشه. در چنین مواردی اصلا توصیه نمیشه که کلید ترکیبی که شامل 4 فیلد ذکر شده هست رو در نظر بگیریم بلکه توصیه میشه که یک فیلد identity بعنوان کلید بگیریم و 4 فیلد ذکر شده رو unique کنیم.
یکی از دلایلش میتونه بخاطر این باشه که اگر چنین کلید ترکیبی بخواد در جداول دیگه به عنوان کلید خارجی استفاده بشه قطعا فضای بیشتری رو در مقایسه با تک کلید بودن در بر خواهد گرفت.
مورد بعدی میتونه در زمان join کردن جداول chid و parent رخ بده که اگر کلید اصلی (و بالطبع کلید خارجی) رو ترکیبی بگیریم چک کردن چند فیلد بصورت همزمان زمان بیشتری رو در قیاس با تک فیلد بودن در برخواهد داشت.
مورد بعدی که به ذهنم میرسه ولی مطمئن نیستم که تا چه اندازه ای صحیح باشه اینه که :
یکی از دلایل اینکه فیلد های ترکیبی رو کلید نمیگیرن شاید بخاطر این باشه که خود sql بصورت خودکار از کلید یک Clustered INDEX میسازه و هزینه این مرتب سازی براساس چند فیلد میتونه در رکوردهای زیاد، قابل توجه باشه. آیا این دلیل درسته؟
با توجه به دلیل اول ( نامناسب بودن کلید ترکیبی که در جدول دیگه حکم کلید خارجی رو داشته باشه) یک سوال برای من بوجود اومده :
اگر یک جدول که کلید اصلی اون ترکیبی هست با جداول دیگه ارتباطی نداشته باشه (بعنوان کلید خارجی در جداول دیگه به کار نرفته باشه) آیا باز هم بهتره که کلید اصلی رو identity و اون چند فیلد رو unique کنیم؟. یا فقط زمانی unique میکنیم که جدول ما به عنوان یک parent باشه و با جداول child در ارتباط باشه؟
از دوستانی که در بحث شرکت میکنن و جواب های علمی به مساله میدن تشکر میکنم.

in_chand_nafar
شنبه 24 فروردین 1392, 21:00 عصر
دوست عزیز
من باز هم انتخاب Identity رو ترجیح می دم چون
1- معمولا در SQL Server به صورت پیش فرض PK به عنوان Clustered Index در نظر گرفته میشه و اگر شما 4 و یا چند تا فیلد رو با هم ترکیب کنی به عنوان PK معرفی کنید کلاستر ایندکس شما روی اون 4 فیلد بسته میشه. مشکل این قضیه این است که اگر تعداد رکوردهای شما خیلی زیاد باشه (در حد چندین میلیون) این موضوع باعث میشه حجم کلاسترایندکس شما در سطوح غیر برگ بالا بره که از لحاظ Performance زیاد مناسب نیست و همین طور اگر حجم رکوردهایی که به جدول اضافه میشن و یا حذف میشن زیاد باشد زمان درج رکورد طولانی میشه (خصوصا زمانی که ایندکس Fragment داشته باشه و Page Split داشته باشی) دلیل این موضوع این است که در کلاستر ایندکس ترتیب فیزیکی رکورد بر اساس کلید ایندکس است حالا رکورد شما با 4 فیلد به عنوان کلید درگیر است اون موقع است که باید جای مناسب اون در Pageهای مربوط به جدول پیدا بشه و این زمان درج و Locking جدول رو طولانی میکنه خصوصا اگر تعداد رکوردها زیاد باشد
2- اگر این 4 فیلد رو به عنوان UK معرفی کنید SQL اون رو با یک Unique NonClustered Index پشتیبانی می کنه که باید حواستون باشه اگر عملیات Insert,Update,Delete زیاد باشه Fragmentation ایندکس بالا میره و این موضوع باعث میشه ایندکس بلای جون کوئری شما بشود. برای رفع مشکل Fragmentation و Page Split بهتر از FillFactor استفاده و عملیات Reorganization و Rebuild کردن ایندکس ها را مرتب انجام دهید
3-نظر من این است که اگر جدول رکوردهایش در حد زیاد است Identity رو به عنوان PK و Clustered Index و یک Unique Key به ازای اون 4 فیلد درست کنید در ضمن تنظیم Fill Factor و Rebuild و Reorganize کردن UK خودتون رو فراموش نکنید

veniz2008
شنبه 24 فروردین 1392, 22:12 عصر
خوشحالم که سکوت این تاپیک شکسته شد.
ممنونم از شما که در بحث شرکت کردید. علاوه بر صحبت های شما سایر دوستان روبه خوندن تاپیک های مفید زیر دعوت میکنم.
نتیجه ای که از این تاپیک ها و گفته های جناب طاهری گرفتم این بود که یک کلید نماینده (Surrogate Key ) بهتر از کلید ترکیبی هست. دلایل این انتخاب رو میتونید (علاوه بر دلایل آقای طاهری) در تاپیک های زیر هم پیدا کنید:
http://stackoverflow.com/questions/4737190/composite-primary-key-or-not
http://stackoverflow.com/questions/963809/should-i-use-composite-primary-keys-or-not
http://stackoverflow.com/questions/5406037/why-are-composite-primary-keys-still-around