نرمال‌سازی سطح اول در پایگاه داده‌های رابطه ای

هنگامی‌که قواعد نرمال‌سازی را به مدل‌های پایگاه داده اضافه می‌کنیم، درواقع می‌خواهیم از صحت داده‌ها محافظت کنیم. نرمال‌سازی این کار را به دو طریق انجام می‌دهد:

  • داده‌های تکراری در مدل داده را کاهش می‌دهد. فرض کنید که بیت یا مقدار یکسانی از اطلاعات ذخیره‌شده در مدل داده‌ای داریم و داده را فقط در یک مکان تغییر دهیم. در این صورت ما با مسئله صحت داده‌ها مواجه هستیم.
  • در پی اطمینان برای اینکه داده‌ی موجود در یک جدول به داده‌ی دیگری در همان جدول مرتبط است. برای مثال اطلاعات جدول ORDER فقط باید بر اساس سفارش‌ها باشد. ما نمی‌توانیم اطلاعات مربوط به حقوق کارکنان را در این جدول داشته باشیم. مادامی‌که داده‌ها در محل مناسبی قرار گیرند، امکان بروز رسانی درست آن‌ها فراهم می‌شود.

فرم های نرمال متفاوتی وجود دارند، در این بخش ما به توضیح فرمال نرمال اول می‌پردازیم. فرم نرمال نوع اول دو نیازمندی دارد:

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

داده‌های اتمیک

داده‌ها به این صورت ذخیره می‌شوند که گروهی از داده‌ها در یک ستون نباشند (برای مثال چندین آیتم مربوط به سفارش که در یک ستون هستند) و یا اینکه چندین ستون با مقدار یکسان در یک جدول نباشند.

به ۲ مثال زیر توجه کنید:

گروهی از داده‌ها در یک ستون مشخص

در ادامه کد زیر را مشاهده می‌کنید:

ما جدول برای سفارش‌ها حاوی ستونی که تمامی قسمت‌های یک سفارش را دارد ایجاد کرده‌ایم:

مسئله‌ای که با آن روبرو هستیم این است که چه اتفاقی می‌افتد اگر سفارش تغییر کند؟ یا شخص فقط یک سفارش تی‌شرت داشته باشد؟ و یا اینکه بخواهیم درباره‌ی خرید تی‌شرت‌های سایز متوسط جستجو کنیم؟ به دلیل نحوه‌ی ذخیره‌سازی داده‌ها بیشتر این عملیات سخت‌تر از آن جه که هستند به نظرمی رسند. ما این ادعا را پیرامون یک سفارش خاص مانند تی‌شرت‌ها نداریم. این مسئله به‌عنوان مثالی برای حالتی که حاوی یک ستون با گروهی از داده‌ها هستیم، است. اگر این روشی برای مدل کردن داده‌ی ما باشد، پس در فرم نرمال سطح اول نیست.

چندین ستون از یک مقدار یکسان

ممکن است تصور کنیم نبود گروهی از داده‌ها در یک ستون را یاد گرفتیم؛ بنابراین، ما آیتم‌های سفارش را به چند ستون تقسیم‌بندی می‌کنیم که در اینجا ما تعداد ستون‌ها را ۲ در نظر می‌گیریم. با فرض اینکه سفارشی حاوی بیش از ۲ آیتم متفاوت را نداریم. این کد چنین ساختاری را تولید می‌کند:

به لحاظ بررسی داریم:

در اینجا نیز با چند مشکل مواجه هستیم. برای مثال، اگر تعداد آیتم‌های ما در یک سفارش ۳ باشد، چه اتفاقی می‌افتد؟ جدول فقط ۲ آیتم را پشتیبانی می‌کند، ازاین‌رو با مشکل روبرو می‌شویم. برای مثال اگر بخواهیم سفارش مربوط به تمام شلوارها را جستجو کنیم، برای به دست آوردن اطلاعات نیاز به بررسی هر ۲ مجموعه از ستون‌ها داریم. اگر بخواهیم با افزایش تعداد ستون‌های جدول، آن را گسترش دهیم تا بتوانیم قابلیت داشتن آیتم‌های بیشتر در طول یک سفارش را پشتیبانی کنیم، مجبوریم جستجوهای خود را بر این اساس افزایش دهیم.

شناسایی منحصربه‌فرد یک سطر مشخص

مسئله دیگری که داریم بحث شناسایی یک سفارش مشخص است. برای مثال اگر ما ۲ سطر از داده را داشته باشیم، با جستجوی زمان سفارش و شخص سفارش‌دهنده قادر به شناسایی ک سفارش مشخص خواهیم بود. اما همان‌طور که می‌بینید ما سفارش‌های هم‌زمان را نیز داریم.

ازاین‌رو نمی‌توانیم دقیق آن سفارش را مشخص نماییم. ما می‌توانیم پیش‌بریم و هرکدام از ستون‌ها را داشته باشیم، درحالی‌که آنچه در دنیای واقعی اتفاق می‌افتد، متفاوت است. برای جدا کردن این هرکدام از این سفارش‌ها می‌توان از order_id یا شماره سفارش استفاده کرد که می‌تواند در مدل داده ایجاد شود.

ما نیاز داریم هر سطر را به‌صورت منحصربه‌فرد مشخص کنیم. این کار را می‌توانیم با داشتن ستونی به نام شماره سفارش انجام دهیم. در مواردی که ما چنین امکانی را در دنیای واقعی نداریم تا استفاده کنیم (برای مثال فرض کنید فروشگاه توسط شماره‌ی سفارش قابل‌پیگیری نباشد) ما نیاز داریم که از چیزی استفاده شود ازاین‌رو کلید جایگزین را معرفی می‌کنیم. حال اگر ما از یک یا چند ستون برای شناسایی منحصربه‌فرد سطر استفاده کنیم، مجموعه‌ی ۱ تا چند ستون را کلید کاندید می‌نامیم. زمانی که ما هم از کلید کاندید و هم از کلید جایگزین برای مشخص کردن سطر یکتا استفاده کنیم، مفهوم کلید اصلی را خواهیم داشت.

قرار دادن همه‌ی این‌ها در کنار هم

اولین گام شکستن گروه‌ها و یا رها شدن از چندین ستون‌های حاوی مقدار یکسان می‌باشد. راه‌حلی که در اینجا داریم، ایجاد جدول جداگانه برای بررسی این آیتم‌های سفارش است. به این معنی که ما همه‌ی آیتم‌ها را از جدول سفارش‌ها بیرون می‌کشیم. اگر مانتوانیم سفارش‌های یکتا را مشخص کنیم، شکست‌خورده‌ایم، زیرا تساوی جدول دوم و جدول اصلی بسیار مهم است؛ و به این معنا که اتصال آیتم‌های سفارش با سفارش‌های مشخص آن‌ها راداریم. بنابراین ما نیاز به معرفی کلید جایگزین داریم که order_id نامیده می‌شود. در ادامه ما کد زیر راداریم:

اگرچه کد طولانی به نظر می‌رسد، اما با اجرای select همه‌چیز مشخص می‌شود. ما مسئله‌ی تشخیص سطر یکتا برای سفارش‌ها را حل کردیم. کلید کاندید برای آیتم‌های سفارش شامل شماره‌ی سفارش و نام آن آیتم است. بنابراین ۲ جدول با نیازمندی‌های این شناسایی روبرو می‌شوند. هم‌چنین ما گروه‌های داده و ستون‌هایی با مقادیر یکسان را حذف نمودیم. پس چنین مدل داده‌ای در سطح اول نرمال‌سازی است.

کار ما هنوز به پایان نرسیده است و کارهای بسیاری برای بهتر شدن مسئله‌داریم. برای مثال، توجه به اینکه نام مشتری در جدول سفارش‌ها ذخیره‌شده است. حال اگر مشتری نام حقوقی خود را تغییر دهد چه اتفاقی می‌افتد؟ پس‌ازآن ما نیاز داریم  اطمینان حاصل کنیم که تمامی سفارش‌ها مشتری به‌روزرسانی شده‌اند. بهتر است که این اطلاعات را در یک جدول جدید ذخیره نماییم و تنها به یک ذخیره‌سازی احتیاج پیدا کنیم.