PDA

View Full Version : سوال: رابطه ها در دیتابیس به چه دردی می خورند؟



hamid1988
چهارشنبه 16 تیر 1389, 11:00 صبح
با سلام
دوستان سوالی که خیلی وقته ذهنم رو به خودش مشغول کرده اینه که مزیت برقراری رابطه بین جداول در دیتابیس چیه؟
در برخی پروژه ها دیدم که جداول با هم رابطه دارند در حالی که اگر رابطه نداشتند باز هم هیچ فرقی نمی کرد!
البته در کتابهای زیادی خوندم که رابطه ی بین جداول باعث کاهش فیلدهای جداول میشه و...
اگه لطف کنید و با یک مثال ساده دو حالت (با رابطه و بدون آن) رو با هم مقایسه کنید ممنون میشم.
با تشکر

sia_2007
چهارشنبه 16 تیر 1389, 11:40 صبح
روابط در طراحی؛ خودش مسئله ای بزرگه؛ از حفظ سوابق؛ تا کمتر کردن یا از بین بردن افزونگی اطلاعات.
موقع اجرا هم برای ساخت Map برای OR/Mapper ها و حفظ Integrity اطلاعات است.
بعدا هم با نگاه به دیاگرام میشه درک سریعتری از ساختار دیتابیس پیدا کرد.

sia_2007
چهارشنبه 16 تیر 1389, 21:31 عصر
دوست عزیز؛ فرض کن بین جدول فاکتور و جدول ردیف فاکتور؛ رابطه وجود داره.
شما با این که چرا این دو تا رابطه دارن؛ مشکل داری یا اون خطی که مثلا تو SQL Server میکشیم ؟

hamid1988
چهارشنبه 16 تیر 1389, 22:00 عصر
دوست عزیز؛ فرض کن بین جدول فاکتور و جدول ردیف فاکتور؛ رابطه وجود داره.

این دوتا میتونن توی یک جدول باشن چه نیازی به جدول جداگانه و ایجاد رابطه هست؟!

فرض کنید یک جدول گروه خبری داریم و یک جدول خبر اکثرآَ بین این دوتا رابطه برقرار می کنند، حالا فرض کنید برنامه ای نوشته ایم که کارش درج خبر هست، وقتی می خواهیم خبری رو درج کنیم آی دی مربوط به گروه خبری رو در فیلدی با عنوان CategoryID که در جدول News داریم درج می کنیم و تموم میشه وقتی هم میخواهیم تمام اخبار یک گروه رو نمایش بدیم در قسمت Where آی دی گروه خبری رو قرار میدیم و یا هنگام حذف، آپدیت و.. هم کاری مشابه انجام میدیم.
در مثال بالا کارهایی که گفتم کاری با رابطه ندارن حالا این ارتباط بین دو جدول کی به کارمون میآد؟
ممنون از توجهتون

yassi_60
پنج شنبه 17 تیر 1389, 17:46 عصر
سلام.
یه مثال می زنم:
فرض کنید تو یه انبار چند قلم جنس وجود داره که مرتب از انبار خارج میشه و به محض اینکه موجودی تمام شد دوباره خریداری شده و به انبار اضافه میشه.
خوب حالا اگه شما نخواهید از رابطه ها استفاده کنید: یک جدول میسازید شبیه این :
کد کالا------ نام کالا-------- مشخصه فنی------- ساخت------- تارخ رسید انبار------- تعداد----------- و ....
---1 -----------میز ------------20*60 --------------ایران -----------1389/01/01 --------5
---1 -----------میز ------------20*60 --------------ایران -----------1389/01/09 --------8
با این جدول هر وقت که دوباره این کالارو خریداری کردید باید دوباره نام کالا و مشخصه فنی و در کل اطلاعات پایه محصول رو واد دیتا بیست کنی.
اما اگه از رابطه ها استفاده کنی اونوقت دوتا جدول داری یکی اطلاعات پایه کالا و دیگری تاریخ رسید انبار و تعداد و غیره که هر چند وقت یک بار اتفاق می افته پس دیگه لازم نیست که هربار اطلاعات محصول رو دوباره وارد کنی

hamid1988
پنج شنبه 17 تیر 1389, 18:29 عصر
با این جدول هر وقت که دوباره این کالارو خریداری کردید باید دوباره نام کالا و مشخصه فنی و در کل اطلاعات پایه محصول رو واد دیتا بیست کنی.
اما اگه از رابطه ها استفاده کنی اونوقت دوتا جدول داری یکی اطلاعات پایه کالا و دیگری تاریخ رسید انبار و تعداد و غیره که هر چند وقت یک بار اتفاق می افته پس دیگه لازم نیست که هربار اطلاعات محصول رو دوباره وارد کنیوقتی کالایی در انبار تموم شد پاک نمیشه فقط تعدادش صفر میشه، وقتی هم که دوباره خریداری بشه فقط فیلد تعداد آپدیت میشه، رابطه ها در این سناریو نقشی ندارن!


شما لطف کن جدولی رو که میگی رو این جا بنویس تا به هم نقدش کنیم.


http://barnamenevis.org/forum/attachment.php?attachmentid=52535&stc=1&d=1278599788

yassi_60
پنج شنبه 17 تیر 1389, 18:46 عصر
معمولا در انبار داری وقتی کالایی خارج شد باید تاریخ خروج بخوره و مشخص بشه که به چه کسی تحویل داده شده، اگه شما بخوای هر دفعه تعداد رو کم کنی تا به 0 برسی چطوری مشخص میشه چی کجاست؟

sia_2007
پنج شنبه 17 تیر 1389, 19:35 عصر
دوست عزیز؛ ورود و خروج کالا به این سادگی که میفرمایید نیست.
این کار در قالب یک برگه انجام میپذیرد. ( حالا با هر اسمی )
به این صورت :
آی دی برگه - تاریخ برگه - آی دی مسئول امضای برگه صدور - آی دی شخص تحویل گیرنده و ...
و بعد تحت عنوان ردیف داریم :
آی دی ردیف - کد کالا - تعداد کالا - قیمت کالا - و ...

اینها دو تا جدول هستند؛ چطور شما اینها رو داخل یک جدول میکنید ؟

ببینید شما آی دی کالا رو ذخیره کردید.
دیگه چرا اسم کالا رو هم ذخیره میکنید ؟
مگه اسم کالا؛ جلوی آی دی اش تو جدول کالا نیست ؟
یا جدول کالا هم ندارید ؟
یا مثلا مگه مشخصه فنی تویه جدول کالا وجود نداره ؟
شما افزونگی اطلاعات دارید؛ به جای این که یک بار و فقط در یک ردیف ؛ در جدول کالا مشخصه فنی میز رو ذخیره کنین؛ اومدین هر بار در هر رکورد اون رو نوشتید.
تازه فرض کنید؛ بعد یک سال معلوم میشه؛ که عبارت 60*20 برای میز اشتباه بوده؛ و درستش 60*21 بوده.
حالا شما میرید تموم این ردیف ها رو اصلاح میکنین ؟
شما به جای آی دی کشور ایران؛ اسمش رو ذخیره کردین؛
در حالی که من آیدی اش رو ذخیره میکنم.
فرض کنید ؛ برای یک ردیف فاکتور؛ علاوه بر کشور سازنده؛ کد شماره تلفن اون هم مهمه؛ مثل 98؛ برای ایران؛ شما با این سیستمتون مجبورید؛ 98 رو هم ذخیره کنید.
این مشکل افزونگی اطلاعات رو داره.
علاوه بر این اگه روزی پیش شماره تلفن ایران عوض بشه ( ممکن نیست ولی این که ممکن نیست عوض بشه استثناست و در اکثر اوقات اطلاعات تغییر پذیر و اشتباه پذیرند )؛
شما باید بیاین کل اینها رو عوض کنین.
علاوه بر اون؛ به شما میگن که ببینید چه تعداد کالای ایرانی صادر شده؛ از انبار ؟
شما در شرط Where تون عبارت "ایران"؛ رو جستجو میکنید؛ اما من 1 رو یا 7 رو ...
خب معلومه که این سریع تره.
ببینید شما باید یه جدول کشور داشته باشید.
و رابطه ای بین ردیف فاکتور و کشور.
حالا شاید بگید که چرا قیمت رو ذخیره سازی کردم؛ مگه قیمت جلوی کالا تو ردیف کالا نیست ؟
بله هست؛ ولی برای ما قیمت موقع خروج کالا مهمه؛ پس ذخیرش میکنیم.
به این میگن حفظ سوابق.
تازه کلی اصول طراحی هستن؛ که اگه بخواین خودتون استنباط کنین؛ به هیچ وجه به نتیجه نمیرسین.
یعنی هیچ کس به نتیجه نمیرسه.
شما دارید با مدل رابطه ای کار میکنین؛ 99.9% این طوره ؛ چه SQL Server چه mySql و Oracle و ...
اینها رو آقای دیت سالهای سال پیش ایجاد کردند؛ و اونقدر محکم هستند که تا حالا دوام آوردند و بعدا هم دوام میآرن.
چون واقعا استانداردند.
بهتره خوب این مطالب رو یاد بگیرین.

hamid1988
پنج شنبه 17 تیر 1389, 20:11 عصر
اینایی که فرمودید درسته و قبول دارم.
مثلاَ در جداول زیر آیا احتیاج به برقرای رابطه هست؟(لطفاَ دلیل را توضیح دهید)


http://barnamenevis.org/forum/attachment.php?attachmentid=52535&stc=1&d=1278599788http://barnamenevis.org/forum/attachment.php?attachmentid=52548&stc=1&d=1278606481

L_eskandary
پنج شنبه 17 تیر 1389, 20:43 عصر
دوست عزیز
فک می کنم شما با اصل نرمال سازی مشکل دارین ولی خوب من هم از جمله افرادی بودم که می گفتم این کارا اصلا لزومی نداره ، و از بیشتر کارایی که موجب می شد جدول ها بیشتر بشن خود داری می کردم ...
و اما حالا بعد از اینکه به چند مسئله برخورد کردم و البته اطلاعاتی که گرفتم دیدم بهترین کار این هستش که ما از رابطه ها و البته از نرمال سازی در database استفاده کنیم . ولی چیزی که باید در نظر داشت اینه که بسیاری از مطالبی که تو کتاب ها نوشتن تئوری هستن و ما باید موقع طراحی database‌ به مواردی توجه کنیم که تو کار عملی به دردمون می خورن...
به هر حال من فقط به یه مثال بسنده می کنم و امیدوارم شما هم تا حدی توجیه بشین:
فرض کنین ما جداول زیر رو داریم:

مشتری(کد مشتری ، نام مشتری و ...)
کالا(کد کالا ، نام کالا ، ...)
فروش(کد فروش ، کد کالا ، کد مشتری ، ...)

حالا چند تا سوال :
1- می خوام بدونم امروز یه مشتری چند بار خرید کرده ؟
2- امروز در هر بار خرید مشتری چه کالاهایی رو خرید کرده ؟
3- اگه قیمت کالایی تغییر کنه و ما قیمت کالا رو تو جدول کالا وارد کرده باشیم ،تکلیف ما چیه باید تغییرش بدیم ؟

جواب هایی که ممکن داده بشه :
1- خوب میرم از جدول فروش یکی یکی میگردم و کالاهایی رو پیدا می کنم که مشتری امروز خرید کرده، ولی خوب مشخص نیست کدوم دفعه چه چیزهایی رو خریده و اصلا فک کنین به اینکه چندتا فیلد رو باید بررسی کنیم .
2-که اینم با سوال یک مشخص شده...
3- خوب من می خوام حساب ماه گذشته رو در بیارم ، قیمتی که تو جدول کالا وارد کرده بودم ، الان تغییر کرده بنابراین حسابی که محاسبه می کنم با قیمت تغییر یافته هست نه قیمتی که معامله شده و این هم فقط به دلیل وجود فیلد قیمت در جدول کالاست!:گیج:

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

مشتری(کدمشتری ، نام مشتری و ...)
فاکتور(کد فاکتور، کد مشتری، تاریخ ، ساعت )
سفارش(کد سفارش،کد فاکتور،کد انبار ، تعداد)
انبار(کد انبار ، کد کالا ، تاریخ ، ساعت ، قیمت ، تعداد)
کالا(کد کالا، نام کالاو ...)

حالا کافیه فقط کد مشتری رو با تاریخ امروز تو فاکتور پیدا کنیم . از طریق کد فاکتور هم می تونم بفهمم که مثلا تو یه بار خرید مشتری چه کالاهایی رو سفارش داده و الی آخر...

L_eskandary
پنج شنبه 17 تیر 1389, 20:52 عصر
در مورد تصاویر هم باید بگم خوب شما یه جدول برا ذخیره ی مثلا موضوع کتاب ها دارین و حالا این موضوعات هم خودشون دارای زیر مجموعه هستند پس مثل فاکتور و سفارش نساز هست که این ارتباط وجود داشته باشه . مثلا کامپیوتر یه موضوع کلی و سیستم عامل و پایگاه داده و ... زیر مجموعه های اون هستن ، حالا بهتر نیست که برای دسترسی بهتر و سریعتر اینا رو هم تفکیک کنیم ؟

hamid1988
پنج شنبه 17 تیر 1389, 22:51 عصر
در مورد تصاویر هم باید بگم خوب شما یه جدول برا ذخیره ی مثلا موضوع کتاب ها دارین و حالا این موضوعات هم خودشون دارای زیر مجموعه هستند پس مثل فاکتور و سفارش نساز هست که این ارتباط وجود داشته باشه . مثلا کامپیوتر یه موضوع کلی و سیستم عامل و پایگاه داده و ... زیر مجموعه های اون هستن ، حالا بهتر نیست که برای دسترسی بهتر و سریعتر اینا رو هم تفکیک کنیم ؟
دوست عزیز در اینجا جدول Context بیانگر مطلب و Category بیانگر نوع مطلب (مثل: خبر، مقاله یا...) هست و با دسته بندی شما فرق داره!
دوستان توجه کنین من با نرمال سازی مشکلی ندارم، من با رابطه ی بین جداول (خطی که در Sql Server) کشیده میشه مشکل دارم!
مثلاَ در تصویری که من در پست قبلی قرار دادم، طبق قوانین نرمال سازی (در مقیاس کوچکش) نرماله، حالا آیا بین دو جدول باید خط رابطه کشیده بشه یا نه؟

sia_2007
پنج شنبه 17 تیر 1389, 23:43 عصر
درسته؛ تصویری که شما گذاشتین در حد خودش کاملا نرماله.
حال مزیت اون خطه اینه که نمیشه Category ای که مطلب داره رو حذف کرد.
نمیشه پدری رو که فرزند داره رو کشت.
اکثر اوقات این با بیزینس برنامه نمیخونه.
نمیشه بگیم مطلب شماره 7 اصلا معلوم نیست مال چه گروهیه.
حال اون خط متضمن جامعیت ارجاعی؛ هستش؛ که پدر دارای فرزند حذف نشه.
علاوه بر این OR/Mapper هایی مثل LINQ to SQL و Entity Framework هم از این خط ها برای ساخت Bussince Object ها استفاده میکنند.
علاوه بر این دیتابیس که 2 تا جدول نداره؛ ممکنه 70 الی 80 تا جدول داشته باشه با 500 صفحه Document؛ نمیشه این طوری چشمی روابط رو کشف کرد.