it-swarm.asia

متى يجب علي استخدام قيد فريد بدلاً من فهرس فريد؟

عندما أريد أن يحتوي العمود على قيم مميزة ، يمكنني إما استخدام قيد

create table t1(
id int primary key,
code varchar(10) unique NULL
);
go

أو يمكنني استخدام فهرس فريد

create table t2(
id int primary key,
code varchar(10) NULL
);
go

create unique index I_t2 on t2(code);

تبدو الأعمدة ذات القيود الفريدة مرشحة جيدة للمؤشرات الفريدة.

هل هناك أسباب معروفة لاستخدام قيود فريدة وعدم استخدام فهارس فريدة بدلاً من ذلك؟

210
bernd_k

تحت غطاء المحرك يتم تنفيذ القيد الفريد بنفس الطريقة التي يتم بها تنفيذ الفهرس الفريد - هناك حاجة لفهرس لتلبية متطلبات فرض القيد بكفاءة. حتى إذا تم إنشاء الفهرس كنتيجة لقيد فريد ، يمكن لمخطط الاستعلام استخدامه مثل أي فهرس آخر إذا رأى أنه أفضل طريقة للتعامل مع استعلام معين.

لذلك بالنسبة لقاعدة البيانات التي تدعم كلتا الميزتين ، غالبًا ما يرجع الاختيار الذي ستستخدمه إلى النمط والاتساق المفضل.

إذا كنت تخطط لاستخدام الفهرس كفهرس (أي أن الكود الخاص بك قد يعتمد على البحث/الفرز/التصفية في هذا الحقل ليكون سريعًا) ، فسأستخدم صراحة فهرسًا فريدًا (وأعلق على المصدر) بدلاً من القيد لإجراء ذلك واضح - بهذه الطريقة إذا تم تغيير متطلبات التفرد في مراجعة لاحقة للتطبيق ، ستعرف (أو أي مبرمج آخر) التأكد من وضع فهرس غير فريد بدلاً من الفريد الفريد (فقط إزالة قيود فريدة ستزيل الفهرس بالكامل). كما يمكن تسمية فهرس معين في تلميح الفهرس (أي مع (INDEX (ix_index_name)) ، والذي لا أعتقد أنه هو حالة الفهرس الذي تم إنشاؤه خلف الكواليس لإدارة التفرد حيث من غير المحتمل أن تعرف اسمه.

وبالمثل إذا كنت تحتاج فقط إلى فرض التفرد كقاعدة عمل بدلاً من الحقل الذي يجب البحث فيه أو استخدامه للفرز ، فسأستخدم القيد ، مرة أخرى لجعل الاستخدام المقصود أكثر وضوحًا عندما ينظر شخص آخر إلى تعريف الجدول الخاص بك.

لاحظ أنه إذا كنت تستخدم كلاً من القيد الفريد والفهرس الفريد في نفس الحقل ، فلن تكون قاعدة البيانات ساطعة بما يكفي لرؤية التكرار ، لذلك ستنتهي بفهرسين يستهلكان مساحة إضافية ويبطئان إدراج/تحديث الصفوف.

165
David Spillett

بالإضافة إلى النقاط في الإجابات الأخرى ، إليك بعض الاختلافات الرئيسية بين الاثنين.

ملاحظة: رسائل الخطأ من SQL Server 2012.

أخطاء

يؤدي انتهاك قيد فريد إلى إرجاع الخطأ 2627.

Msg 2627, Level 14, State 1, Line 1
Violation of UNIQUE KEY constraint 'P1U_pk'. Cannot insert duplicate key in object 'dbo.P1U'. The duplicate key value is (1).
The statement has been terminated.

يؤدي انتهاك فهرس فريد إلى إرجاع الخطأ 2601.

Msg 2601, Level 14, State 1, Line 1
Cannot insert duplicate key row in object 'dbo.P1' with unique index 'P1_u'. The duplicate key value is (1).
The statement has been terminated.

تعطيل

لا يمكن تعطيل القيد الفريد.

Msg 11415, Level 16, State 1, Line 1
Object 'P1U_pk' cannot be disabled or enabled. This action applies only to foreign key and check constraints.
Msg 4916, Level 16, State 0, Line 1
Could not enable or disable the constraint. See previous errors.

ولكن يمكن تعطيل الفهرس الفريد وراء قيد المفتاح الأساسي أو القيد الفريد ، مثل أي فهرس فريد. Brain2000 -

ALTER INDEX P1_u ON dbo.P1 DISABLE ;

لاحظ التحذير المعتاد بأن تعطيل فهرس مجمع يجعل البيانات غير قابلة للوصول.

خيارات

قيود فريدة تدعم خيارات الفهرسة مثل FILLFACTOR و IGNORE_DUP_KEY ، على الرغم من أن هذا لم يكن هو الحال بالنسبة لكل إصدارات SQL Server.

الأعمدة المضمنة

يمكن أن تتضمن الفهارس غير المجمعة أعمدة غير مفهرسة (تسمى فهرس تغطية ، وهذا تحسين رئيسي للأداء). لا يمكن أن تتضمن الفهارس وراء قيود PRIMARY KEY و UNIQUE أعمدة. طرف القبعةypercube.

الفلتره

لا يمكن تصفية القيد الفريد.

يمكن تصفية فهرس فريد.

CREATE UNIQUE NONCLUSTERED INDEX Students6_DrivesLicence_u 
ON dbo.Students6( DriversLicenceNo ) WHERE DriversLicenceNo is not null ;

قيود المفاتيح الأجنبية

لا يمكن أن يشير قيد مفتاح خارجي إلى فهرس فريد تمت تصفيته ، على الرغم من أنه يمكن أن يشير إلى فهرس فريد غير مصفى (أعتقد أنه تمت إضافته في SQL Server 2005).

تسمية

عند إنشاء القيد ، يكون تحديد اسم القيد اختياريًا (لجميع أنواع القيود الخمسة). إذا لم تحدد اسمًا ، فسيقوم MSSQL بإنشاء اسم لك.

CREATE TABLE dbo.T1 (
    TID int not null PRIMARY KEY
) ;
GO
CREATE TABLE dbo.T2 (
    TID int not null CONSTRAINT T2_pk PRIMARY KEY
) ;

عند إنشاء الفهارس ، يجب تحديد اسم.

Hat-tip @ i-one.

الروابط

http://technet.Microsoft.com/en-us/library/aa224827 (v = SQL.80) .aspx

http://technet.Microsoft.com/en-us/library/ms177456.aspx

107
Greenstone Walker

لاقتباس MSDN كمصدر موثوق:

لا توجد فروق ذات دلالة إحصائية بين إنشاء قيد فريد وإنشاء فهرس فريد مستقل عن القيد . يحدث التحقق من صحة البيانات بنفس الطريقة ، ولا يميز مُحسِّن الاستعلام بين فهرس فريد تم إنشاؤه بواسطة قيد أو تم إنشاؤه يدويًا. ومع ذلك ، فإن إنشاء قيد فريد على العمود يجعل هدف الفهرس واضحًا ... مزيد من المعلومات هنا

و ...

يقوم مشغل قاعدة البيانات تلقائيًا بإنشاء فهرس فريد لفرض متطلبات التفرد لقيد فريد. لذلك ، إذا جرت محاولة لإدراج صف مكرر ، يقوم مشغل قاعدة البيانات بإرجاع رسالة خطأ تنص على أنه تم انتهاك القيد الفريد ولا يضيف الصف إلى الجدول. ما لم يتم تحديد فهرس مجمع بشكل صريح ، يتم إنشاء فهرس فريد غير مجمع بشكل افتراضي لفرض القيد الفريد ... مزيد من المعلومات هنا

أخرى في: https://technet.Microsoft.com/en-us/library/aa224827٪28v=sql.80٪29.aspx

10
user919426

أحد الاختلافات الرئيسية بين القيد الفريد والفهرس الفريد هو أن قيد المفتاح الخارجي على جدول آخر يمكن أن يشير إلى الأعمدة التي تشكل قيدًا فريدًا. هذا لا ينطبق على الفهارس الفريدة. بالإضافة إلى ذلك ، يتم تعريف القيود الفريدة كجزء من معيار ANSI ، في حين أن الفهارس ليست كذلك. أخيرًا ، يعتبر القيد الفريد هو العيش في مجال تصميم قاعدة البيانات المنطقية (والتي يمكن تنفيذها بشكل مختلف بواسطة محركات DB المختلفة) بينما يكون الفهرس هو الجانب المادي. لذلك ، فإن القيد الفريد أكثر تعبيرا. أفضّل قيودًا فريدة في جميع الحالات تقريبًا.

7
Dmitry Frenkel

في Oracle ، هناك اختلاف كبير هو أنه يمكنك إنشاء فهرس فريد للوظيفة ، وهو غير قابل للتنفيذ مع قيود فريدة:

فمثلا

create unique index ux_test on my_table (case when amount != 0 then fk_xyz end);

لذا fk_xyz فريد فقط للتسجيل الذي يحتوي على amount != 0.

1
Amir Pashazadeh