خانه/ وبلاگ/ تفاوت Primary Key، Unique Key و Foreign Key در SQL Server
آموزش SQL

تفاوت Primary Key، Unique Key و Foreign Key در SQL Server

آموزش SQL ۵ آبان ۱۴۰۵ 9 دقیقه مطالعه

کلید اصلی، کلید یکتا و کلید خارجی هر سه «قید» (Constraint) هستند، اما سه کار کاملاً متفاوت می‌کنند. این تفاوت یکی از سؤال‌های همیشگی امتحان پایگاه‌داده است.

جدول مقایسه

ویژگیPrimary KeyUnique KeyForeign Key
هدفشناسایی یکتای هر ردیفجلوگیری از تکرار مقدارایجاد ارتباط بین دو جدول
مقدار تکراریمجاز نیستمجاز نیستمجاز است (چند ردیف می‌توانند به یک والد اشاره کنند)
NULLمجاز نیستفقط یک NULLمجاز (اگر ستون NOT NULL نباشد)
تعداد در هر جدولفقط یکیچندتاچندتا
ایندکس خودکاربله (پیش‌فرض Clustered)بله (NonClustered)خیر؛ باید خودت بسازی

Primary Key: هویت ردیف

sql
CREATE TABLE Student (
  StudentId INT IDENTITY(1,1) PRIMARY KEY,
  NationalCode CHAR(10) NOT NULL,
  FullName NVARCHAR(100) NOT NULL
);

StudentId هر دانشجو را یکتا می‌کند. کلید اصلی می‌تواند ترکیبی هم باشد، مثلاً در جدول واسط: PRIMARY KEY (StudentId, CourseId). اگر مقدار تکراری درج شود:

text
Msg 2627: Violation of PRIMARY KEY constraint 'PK_Student_...'.
Cannot insert duplicate key in object 'dbo.Student'.

Unique Key: یکتایی بدون هویت اصلی

کد ملی هم یکتاست ولی ما StudentId را کلید اصلی گذاشتیم. با UNIQUE یکتایی کد ملی را هم تضمین می‌کنیم:

sql
ALTER TABLE Student
ADD CONSTRAINT UQ_Student_NationalCode UNIQUE (NationalCode);

ایمیل، شماره‌ی موبایل و نام‌کاربری نمونه‌های رایج ستون UNIQUE هستند.

Foreign Key: ارتباط بین جدول‌ها

sql
CREATE TABLE Enrollment (
  EnrollmentId INT IDENTITY PRIMARY KEY,
  StudentId INT NOT NULL,
  CourseId  INT NOT NULL,
  CONSTRAINT FK_Enrollment_Student FOREIGN KEY (StudentId)
    REFERENCES Student(StudentId)
);

حالا نمی‌توان ثبت‌نامی برای دانشجویی که وجود ندارد درج کرد و نمی‌توان دانشجویی را که ثبت‌نام دارد حذف کرد (مگر ON DELETE CASCADE). پیام خطا:

text
Msg 547: The INSERT statement conflicted with the FOREIGN KEY constraint
"FK_Enrollment_Student". The conflict occurred in database "SchoolDB",
table "dbo.Student", column 'StudentId'.

راه‌حل این خطا را در رفع خطای conflicted with the FOREIGN KEY constraint ببین.

رفتار حذف و به‌روزرسانی (Referential Actions)

گزینهاثر روی ردیف‌های فرزند
NO ACTION (پیش‌فرض)عملیات حذف/تغییر والد با خطا رد می‌شود
CASCADEفرزندها هم حذف یا به‌روزرسانی می‌شوند
SET NULLستون کلید خارجی فرزندها NULL می‌شود
SET DEFAULTمقدار پیش‌فرض ستون جایگزین می‌شود
sql
ALTER TABLE Enrollment
ADD CONSTRAINT FK_Enrollment_Course FOREIGN KEY (CourseId)
    REFERENCES Course(CourseId) ON DELETE CASCADE;

چند نکته‌ی عملی

  • کلید خارجی ایندکس خودکار نمی‌سازد؛ روی ستون‌های FK که زیاد JOIN می‌شوند ایندکس بساز.
  • کلید اصلی «مصنوعی» (IDENTITY) معمولاً بهتر از کلید طبیعی (مثل کد ملی) است چون تغییر نمی‌کند.
  • قیدها را نام‌گذاری کن (PK_، UQ_، FK_) تا پیام خطاها و نگهداری ساده شود.

برای تمرین، درس‌های Primary Key و Foreign Key را ببین.

سوالات متداول درباره‌ی این موضوع

آیا Primary Key می‌تواند NULL داشته باشد؟

نه. ستون‌های کلید اصلی باید NOT NULL باشند و مقدار تکراری نداشته باشند. هر جدول فقط یک کلید اصلی دارد.

Unique چند NULL قبول می‌کند؟

در SQL Server یک قید UNIQUE فقط یک مقدار NULL را می‌پذیرد (NULL دوم تکراری حساب می‌شود). برای چند NULL مجاز، از ایندکس یکتای فیلترشده (WHERE col IS NOT NULL) استفاده می‌شود.

آیا کلید خارجی حتماً باید به Primary Key اشاره کند؟

به کلید اصلی یا هر ستون/ترکیبی که قید UNIQUE دارد می‌تواند اشاره کند. معمولاً به کلید اصلی اشاره می‌کند.

مصطفی موسویسازنده و نویسنده‌ی SQLFarsi. اگر اشتباهی در مقاله دیدی یا پیشنهادی داری، از طریق mousavi.dev خبر بده.

می‌خوای SQL را از پایه و با تمرین یاد بگیری؟

دوره‌ی رایگان SQLFarsi را با Playground و پروژه‌های واقعی دنبال کن.

شروع یادگیری