کلید اصلی و کلید خارجی در SQL
آموزش

کلید اصلی و کلید خارجی در SQL

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

تحریریه‌ی دینا کد
نویسنده
۶ دقیقه مطالعه۰ بازدید
اشتراک گذاری۰
فهرست مطالب
  1. ۱نقش کلید اصلی در شناسایی بی‌همتای سطرها
  2. ۲نقش کلید خارجی در اتصال جدول‌ها
  3. ۳نمونه عملی تعریف جدول‌ها با قیدهای کلیدی
  4. ۴اشتباه‌های رایج هنگام کار با کلیدهای SQL
  5. ۵قدم بعدی برای یادگیری عمیق‌تر

وقتی داده‌های یک سامانه در چند جدول پراکنده می‌شوند، بزرگ‌ترین چالش حفظ سلامت رابطه‌ها است. برای نمونه اگر بتوانید سفارشی ثبت کنید که به هیچ کاربری تعلق ندارد، یا برای یک کاربر دو شناسه یکسان با دو ایمیل متفاوت بسازید، سیستم حسابداری و احراز هویت دچار خطاهای پنهان می‌شود. زبان SQL برای حل این آشفتگی دو ابزار کنترلی بنیادی به نام کلید اصلی (Primary Key) و کلید خارجی (Foreign Key) در اختیار شما می‌گذارد.

در این راهنما، سازوکار هر دو قید را بر اساس استاندارد SQL و مستندات PostgreSQL بررسی می‌کنیم و رفتار پایگاه داده را هنگام ثبت داده‌های نامعتبر زیر ذره‌بین می‌بریم.

نقش کلید اصلی در شناسایی بی‌همتای سطرها

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

اگر در یک جدول هیچ کلیدی تعیین نکنید، ممکن است به اشتباه دو سطر کاملاً یکسان وارد جدول شوند و بعداً هنگام ویرایش یا حذف یکی از آن‌ها، هر دو رکورد به طور همزمان تغییر کنند.

نقش کلید خارجی در اتصال جدول‌ها

کلید خارجی قیدی است که روی یک ستون تعریف می‌شود تا مقدار آن حتماً با یکی از مقدارهای کلید اصلی یا یکتای یک جدول دیگر همخوانی داشته باشد. به این اصل «یکپارچگی ارجاعی» (Referential Integrity) می‌گویند. کلید خارجی مانع ورود داده‌های سرگردان می‌شود. اگر کاربری با شناسه ۱۲ وجود نداشته باشد، پایگاه داده اجازه نمی‌دهد سفارشی با user_id = ۱۲ ثبت شود.

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

نمونه عملی تعریف جدول‌ها با قیدهای کلیدی

برای درک بهتر، سناریوی دو جدول مشتریان و سفارش‌ها را پیاده‌سازی می‌کنیم. ابتدا جدول والد را می‌سازیم:

sql-- ساخت جدول مشتریان با کلید اصلی
CREATE TABLE customers (
    customer_id integer PRIMARY KEY,
    full_name text NOT NULL,
    email text UNIQUE NOT NULL
);

-- ساخت جدول سفارش‌ها با کلید خارجی متصل به جدول مشتریان
CREATE TABLE orders (
    order_id integer PRIMARY KEY,
    order_date date NOT NULL,
    customer_id integer REFERENCES customers (customer_id),
    total_amount numeric CHECK (total_amount > ۰)
);

حالا داده‌های معتبر را درون این جدول‌ها ثبت می‌کنیم:

sql-- ثبت یک مشتری جدید
INSERT INTO customers (customer_id, full_name, email)
VALUES (۱, 'علی رضایی', '[email protected]');

-- ثبت سفارش برای همان مشتری
INSERT INTO orders (order_id, order_date, customer_id, total_amount)
VALUES (۱۰۱, '2026-03-01', ۱, ۴۵۰۰۰۰);

پایگاه داده هر دو دستور بالا را تایید می‌کند. اما چه اتفاقی می‌افتد اگر بخواهیم سفارشی برای مشتری ثبت کنیم که وجود خارجی ندارد؟

sql-- تلاش برای ثبت سفارش با شناسه مشتری ناموجود
INSERT INTO orders (order_id, order_date, customer_id, total_amount)
VALUES (۱۰۲, '2026-03-02', ۹۹, ۱۲۰۰۰۰);

موتور SQL بی‌درنگ از اجرای این کوئری جلوگیری می‌کند و پیام زیر را برمی‌گرداند:

textERROR: insert or update on table "orders" violates foreign key constraint "orders_customer_id_fkey"
DETAIL: Key (customer_id)=(۹۹) is not present in table "customers".

همین سازوکار سخت‌گیرانه باعث می‌شود نرم‌افزار شما در طول سال‌ها فعالیت، رکوردهای بی‌پدر و یتیم تولید نکند.

اشتباه‌های رایج هنگام کار با کلیدهای SQL

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

اشتباه دیگر این است که فراموش می‌کنند کلید خارجی به خودی خود ستون را نمایه (Index) نمی‌کند. در حالی که کلید اصلی به طور خودکار ایندکس اختصاصی می‌گیرد، کلید خارجی در جدول فرزند ایندکس خودکار ندارد. اگر روی ستون کلید خارجی ایندکس دستی تعریف نکنید، عملیات JOIN بین این دو جدول در حجم داده بالا به شدت کند می‌شود.

قدم بعدی برای یادگیری عمیق‌تر

گام بعدی شما آشنایی با رفتارهای پیشرفته کلید خارجی هنگام تغییر یا حذف رکوردها است؛ گزینه‌هایی مانند ON DELETE CASCADE و ON DELETE SET NULL که رفتارهای اتوماتیک جدول فرزند را معین می‌کنند. برای یادگیری ساختار اصولی پایگاه‌های داده رابطه‌ای و قواعد نرمال‌سازی جدول‌ها، می‌توانید سرفصل‌های دوره پایگاه داده و SQL را دنبال کنید.

تحریریه‌ی دینا کد
نویسنده

نظرها

اولین نفری باشید که نظر می‌دهد
برای ثبت نظر وارد شوید

سؤالتان را بپرسید یا تجربه‌تان را بنویسید تا نویسنده‌ی مطلب پاسخ بدهد.

مطالب مرتبط

از همین دسته
دستور GROUP BY در SQL چطور کار می‌کند
آموزش

دستور GROUP BY در SQL چطور کار می‌کند

عملکرد دستور GROUP BY در SQL و نحوه گروه‌بندی سطرها به همراه توابع تجمیعی را با مثال‌های واقعی یاد بگیرید.

تحریریه‌ی دینا کد۵ دقیقه
struct در Go چیست و چه فرقی با کلاس دارد
آموزش

struct در Go چیست و چه فرقی با کلاس دارد

ساختار داده struct در زبان Go جایگزین کلاس‌های مرسوم شیءگرایی است و چگونگی گروه‌بندی داده‌ها و متدها را به شیوه‌ای ساده‌تر ممکن می‌سازد.

تحریریه‌ی دینا کد۷ دقیقه