چرا داده در سراسر چند جدول تقسیم میشود
ذخیره هر قطعه اطلاعات مرتبط در یک جدول واحد بهسرعت به داده تکراری منجر میشود. ذخیره تاریخچه سفارش هر مشتری مستقیماً درون جدول مشتری را در نظر بگیرید: هر سفارش جدید نیازمند تکرار دوباره نام و ایمیل آن مشتری خواهد بود، که فضا را هدر میدهد و ریسکی ایجاد میکند که نام همان مشتری در ردیفهای مختلف متفاوت نوشته شود.
طراحی مسئلهساز یک-جدولی:
| customer_name | email | order_id | order_date |
|----------------|----------------|----------|------------|
| Alice Smith | [email protected] | 101 | 2026-01-05 |
| Alice Smith | [email protected] | 102 | 2026-01-12 |
نام و ایمیل آلیس برای هر سفارش تکرار شده استتقسیم این به دو جدول مرتبط — یکی برای مشتریان، یکی برای سفارشها — جزئیات هر مشتری را دقیقاً یکبار ذخیره میکند، و هر سفارش صرفاً ارجاع میدهد کدام مشتری آن را ثبت کرده است.
کلیدهای خارجی: چسبی که جداول را متصل میکند
یک Foreign Key (کلید خارجی) یک ستون در یک جدول است که به Primary Key (کلید اصلی)، که پیشتر در این مجموعه بحث شد، جدول دیگری ارجاع میدهد، و یک اتصال بین یک ردیف در یک جدول و یک ردیف در دیگری برقرار میکند.
CREATE TABLE orders (
order_id INTEGER PRIMARY KEY,
customer_id INTEGER,
order_date DATE,
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);این محدودیت کلید خارجی بیش از صرفاً مستندسازی رابطه انجام میدهد؛ دیتابیس بهطور فعال آن را اعمال میکند، و از درج یک سفارش که به یک customer_id که واقعاً در جدول مشتریان وجود ندارد ارجاع میدهد امتناع میکند — یک محافظت به نام Referential Integrity (یکپارچگی ارجاعی) که از داده یتیم یا ناسازگار جلوگیری میکند.
بازیابی داده در سراسر جداول: بند JOIN
وقتی داده در سراسر جداول تقسیم شود، بازیابی یک تصویر کامل — مانند نام یک مشتری همراه با تاریخهای سفارشاتش — نیازمند ترکیب ردیفها از هر دو جدول با استفاده از یک JOIN است.
INNER JOIN: فقط ردیفهای منطبق
SELECT customers.name, orders.order_date
FROM customers
INNER JOIN orders ON customers.customer_id = orders.customer_id;یک INNER JOIN فقط ردیفهایی که تطبیقی در هر دو جدول وجود دارد را برمیگرداند — یک مشتری بدون سفارش اصلاً در این نتیجه ظاهر نمیشود، چون هیچ ردیف منطبقی در جدول سفارشها برای جفتشدن با آن وجود ندارد.
LEFT JOIN: هر ردیف از یک سمت را نگه دار
SELECT customers.name, orders.order_date
FROM customers
LEFT JOIN orders ON customers.customer_id = orders.customer_id;یک LEFT JOIN هر ردیف از جدول چپ (مشتریان) را صرفنظر از اینکه آیا تطبیقی در جدول راست (سفارشها) وجود دارد یا نه برمیگرداند، و NULL را برای ستونهای سفارش وقتی هیچ سفارش منطبقی وجود ندارد پر میکند. این انتخاب درست است هروقت هدف دیدن هر مشتری باشد، شامل آنهایی که هرگز سفارشی ثبت نکردهاند.
انتخاب بین انواع JOIN
INNER JOIN: فقط ردیفهایی با تطبیق در هر دو سمت
LEFT JOIN: همه ردیفهای جدول چپ، داده منطبق
از راست جایی که در دسترس است
RIGHT JOIN: تصویر آینهای LEFT JOIN
FULL JOIN: همه ردیفها از هر دو جدول، منطبق
جایی که ممکن است، NULL جایی که نهترکیب JOIN با تجمیع
JOIN ها مکرراً با GROUP BY و توابع تجمیعی که پیشتر در این مجموعه بحث شد ترکیب میشوند تا به پرسشهایی که در سراسر چند جدول گسترده هستند پاسخ دهند.
SELECT customers.name, COUNT(orders.order_id) AS order_count
FROM customers
LEFT JOIN orders ON customers.customer_id = orders.customer_id
GROUP BY customers.name;این کوئری میشمارد هر مشتری چند سفارش ثبت کرده، و بهدرستی یک شمارش صفر برای مشتریانی که هرگز سفارش ندادهاند نشان میدهد، بهلطف LEFT JOIN که ردیف آنها را حتی بدون تطبیق حفظ میکند.
بازبینی مدیریت جدول و داده
فراتر از CREATE TABLE پایه پوششدادهشده پیشتر در این مجموعه، کار واقعی دیتابیس اغلب نیازمند تغییر ساختار یک جدول پس از اینکه از قبل داده دارد، با استفاده از ALTER TABLE، است.
-- افزودن یک ستون جدید به یک جدول موجود
ALTER TABLE customers ADD COLUMN phone VARCHAR(20);
-- حذف یک ستون دیگر مورد نیاز نیست
ALTER TABLE customers DROP COLUMN phone;وقتی دادهای که جداول دیگر از طریق کلیدهای خارجی به آن وابستهاند حذف میشود، اعمال یکپارچگی ارجاعی دیتابیس، که پیشتر در این مقاله بحث شد، بهطور پیشفرض حذف را مسدود میکند مگر اینکه ردیفهای وابسته ابتدا حذف شوند، یا مگر اینکه کلید خارجی صراحتاً با یک رفتار آبشاری که مشخص میکند چه اتفاقی باید برای ردیفهای مرتبط بهطور خودکار بیفتد پیکربندی شود.
چرا تسلط بر JOIN ها یک نقطه عطف است
درک اینکه چگونه داده را بهدرستی در سراسر جداول مرتبط تقسیم کنیم و با استفاده از JOIN ها بهطور قابلاعتماد دوباره متصلش کنیم، مهمترین مهارت منفردی است که استفاده پایه SQL را از شایستگی واقعی دیتابیس رابطهای جدا میکند. تقریباً هر دیتابیس دنیای واقعی شامل دهها جدول بههممتصل است، و توانایی ترکیب درست داده از چندتای آنها بهطور همزمان، بدون تصادفاً تکرارکردن یا ازدستدادن ردیفها، برای نوشتن کوئریهای درست و، مهمتر، برای طراحی دیتابیسهای خوبساختاریافته از ابتدا، ضروری است — اصول طراحی عمیقتری که در سراسر باقی این مجموعه پوشش داده میشوند.