درآمدی بر اشتباهات رایج در طراحی دیتابیس


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

نرمال‌سازی پایگاه داده
Database Normalization تکنیکی در طراحی دیتابیس است که به موجب آن داده‌ها در چندین جدول مرتبط با یکدیگر سازماندهی شده تا افزونگی داده به حداقل برسد (Redundancy یا «افزونگی» بدان معنا است که داده‌ای خاص در چند جدول مختلف نگهداری شود.) وقتی در دیتابیس با افزونگی داده مواجه شویم، مشکلات عدیده‌ای پیش‌روی ما قرار خواهد گرفت به طوری که مثلاً حجم دیتابیس به خاطر ذخیره‌سازی داده‌های تکراری افزایش می‌یابد مضاف بر اینکه در حین آپدیت یا حذف داده‌ها ممکن است به مشکل برخوریم.

تجمیع داده‌های مختلف در یک جدول
اساساً هدف از به‌کارگیری دیتابیس‌های رابطه‌ای آن است که داده‌های مختلف را داخل جداول مختلفی ذخیره‌ ساخته و در صورت نیاز مابین آن‌ها ارتباط برقرار کرد. با این توضیحات، یکی از اشتباهات رایج در طراحی دیتابیس این است که از یک جدول برای ذخیرهٔ انواع و اقسام داده‌ها استفاده کرد.

برای درک بهتر این موضوع، فرض کنیم جدولی داریم به اسم users که حاوی ستونی است به اسم score که بسته به فعالیت کاربران در سایت، دائم مقدار امتیاز ایشان در حال آپدیت شدن است. همچنین این جدول حاوی فیلدهای دیگری نیز همچون name یا email نیز می‌باشد که کمتر در معرض به‌روزرسانی هستند و بیشتر جهت نمایش در سایت مورد استفاده قرار می‌گیرند. اِسکمای چنین جدولی به صورت زیر است:

+-------+--------------+
| Field | Type         |
+-------+--------------+
| id    | int(11)      |
| name  | varchar(255) |
| email | varchar(255) |
| score | int(11)      |
+-------+--------------+

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

+-------+--------------+
| Field | Type         |
+-------+--------------+
| id    | int(11)      |
| name  | varchar(255) |
| email | varchar(255) |
+-------+--------------+

که معمولاً برای فرایند Read (خواندن) مورد استفاده قرار می‌گیرد و جدول دیگری تحت عنوان user_score به طوری که ساختارش به صورت زیر است:

+---------+---------+
| Field   | Type    |
+---------+---------+
| user_id | int(11) |
| score   | int(11) |
+---------+---------+

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

چنین رویکردی در طراحی دیتابیس برای فروشگاه‌های آنلاین نیز کاربردی است. فرض کنیم جدولی داریم به اسم purchase که کلیهٔ خریدها در آن ثبت می‌گردد. آنچه در یک فروشگاه آنلاین مسلم است اینکه پس از مدتی نیاز است تا خریدهای قبلی مشتریان را فقط به صورت آرشیو داشته باشیم که در چنین شرایطی می‌توانیم خریدهای جدید مشتریان را از خرید‌های تکمیل‌شده و قدیمی مجزا سازیم؛ به عبارتی، به جای یک جدول کلی به نام purchase می‌توان از دو جدول مختلف استفاده کرد تحت عناوین purchase و archived_purchase بدین صورت که سفارشات تکمیل‌شده که مشتریان دیگر با آن‌ها کاری ندارند را به جدول آرشیو انتقال داد.

در واقع، سفارشات تازه دائم در حال آپدیت شدن هستند (مثلاً مشتری کالای جدیدی به سبد خرید خود اضافه می‌کند یا کالایی را حذف می‌کند.) و این در حالی است که سفارشات تکمیل‌شده فقط به عنوان آرشیو نگهداری می‌شوند و هرگز آپدیت نخواهند شد. با این تقسیم‌بندی دیتا، می‌توانیم حجم جدول purchase که دربرگیرندهٔ خریدهای جدید است را پایین نگاه داریم که مسلماً فراخوانی داده‌ها و پروسهٔ‌ ایندکسینگ آن سریع‌تر اتفاق خواهد افتاد اما در عین حال آرشیوی کامل از خریدهای قبلی هم در اختیار خواهیم داشت.

این بخش از محتوا مخصوص کاربرانی است که ثبت‌نام کرده‌اند.
جهت مشاهدهٔ این بخش از محتوا لاگین نمایید.

جمع‌بندی
آنچه در این مقاله ذکر شد صرفاً بخشی از یکسری اصطلاحاً Best Practice در فرآیند طراحی دیتابیس بود که بهتر است رعایت شوند اما این هرگز بدان معنا نیست که نرمال‌سازی پایگاه‌ داده به این موارد ختم می‌گردد بلکه بسته به ماهیت اپلیکیشن و نیازهای مختلف آن، باید سیاست‌های مختلفی در پروسهٔ طراحی دیتابیس مورد استفاده قرار گیرد (اگر علاقمند به آشنایی بیشتر با مفاهیم مرتبط با دیتابیس و زبان اس‌کیو‌ال هستید، می‌توانید به دورهٔ آموزش SQL و MySQL مراجعه نمایید.)