تفاوت Primary Key، Unique Key و Foreign Key در SQL Server
کلید اصلی، کلید یکتا و کلید خارجی هر سه «قید» (Constraint) هستند، اما سه کار کاملاً متفاوت میکنند. این تفاوت یکی از سؤالهای همیشگی امتحان پایگاهداده است.
جدول مقایسه
| ویژگی | Primary Key | Unique Key | Foreign Key |
|---|---|---|---|
| هدف | شناسایی یکتای هر ردیف | جلوگیری از تکرار مقدار | ایجاد ارتباط بین دو جدول |
| مقدار تکراری | مجاز نیست | مجاز نیست | مجاز است (چند ردیف میتوانند به یک والد اشاره کنند) |
| NULL | مجاز نیست | فقط یک NULL | مجاز (اگر ستون NOT NULL نباشد) |
| تعداد در هر جدول | فقط یکی | چندتا | چندتا |
| ایندکس خودکار | بله (پیشفرض Clustered) | بله (NonClustered) | خیر؛ باید خودت بسازی |
Primary Key: هویت ردیف
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). اگر مقدار تکراری درج شود:
Msg 2627: Violation of PRIMARY KEY constraint 'PK_Student_...'. Cannot insert duplicate key in object 'dbo.Student'.
Unique Key: یکتایی بدون هویت اصلی
کد ملی هم یکتاست ولی ما StudentId را کلید اصلی گذاشتیم. با UNIQUE یکتایی کد ملی را هم تضمین میکنیم:
ALTER TABLE Student ADD CONSTRAINT UQ_Student_NationalCode UNIQUE (NationalCode);
ایمیل، شمارهی موبایل و نامکاربری نمونههای رایج ستون UNIQUE هستند.
Foreign Key: ارتباط بین جدولها
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). پیام خطا:
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 | مقدار پیشفرض ستون جایگزین میشود |
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 دارد میتواند اشاره کند. معمولاً به کلید اصلی اشاره میکند.
میخوای SQL را از پایه و با تمرین یاد بگیری؟
دورهی رایگان SQLFarsi را با Playground و پروژههای واقعی دنبال کن.
شروع یادگیری