سؤال

وأنا باستخدام SQL Server 2005. أريد أن تقييد القيم في عمود لتكون فريدة من نوعها، مع السماح بالقيم الخالية.

وبلدي الحل الحالي يتضمن فهرس فريد على عرض مثل ذلك:

CREATE VIEW vw_unq WITH SCHEMABINDING AS
    SELECT Column1
      FROM MyTable
     WHERE Column1 IS NOT NULL

CREATE UNIQUE CLUSTERED INDEX unq_idx ON vw_unq (Column1)

وأي أفكار أفضل؟

هل كانت مفيدة؟

المحلول

متأكد من أنك لا تستطيع أن تفعل ذلك، لأنه يخالف الغرض من الغرائب.

ولكن، يبدو أن هذا الشخص لعمل لائق حول: http://sqlservercodebook.blogspot.com /2008/04/multiple-null-values-in-unique-index-in.html

نصائح أخرى

وعن طريق SQL Server 2008 أو يمكنك إنشاء فهرس تصفيتها: HTTP: / /msdn.microsoft.com/en-us/library/cc280372.aspx. (أرى وأضاف سيمون في ذلك التعليق، ولكن اعتقد انه يستحق الإجابة الخاصة بها كما غاب عن تعليق بسهولة).

وثمة خيار آخر هو مشغل للتحقق التفرد، ولكن هذا قد يؤثر على أدائها.

وكما هو معروف على نطاق واسع الحيلة عمود محتسب بأنه "nullbuster". ملاحظاتي الائتمان ستيف كاس:

CREATE TABLE dupNulls (
pk int identity(1,1) primary key,
X  int NULL,
nullbuster as (case when X is null then pk else 0 end),
CONSTRAINT dupNulls_uqX UNIQUE (X,nullbuster)
)

وبالمعنى الدقيق للكلمة، عمود قيم الفارغة فريد (أو مجموعة من الأعمدة) يمكن أن يكون NULL (أو سجل بالقيم الفارغة) مرة واحدة فقط، لأن لها نفس القيمة (وهذا يشمل NULL) أكثر من مرة من الواضح يخالف قيد فريد.

ولكن، هذا لا يعني مفهوم "الأعمدة قيم الفارغة فريدة من نوعها" غير صالحة. في الواقع لتنفيذه في أي قاعدة بيانات علائقية علينا فقط أن نضع في الاعتبار أن هذا النوع من قواعد البيانات من المفترض أن تكون طبيعية للعمل بشكل صحيح، وتطبيع عادة ما ينطوي على إضافة العديد من (كيان غير) طاولات إضافية لإقامة علاقات بين كيانات .

ودعونا نعمل مثال الأساسية النظر فقط "عمود قيم الفارغة فريدة من نوعها" واحد، فإنه من السهل لتوسيعه ليشمل المزيد من هذه الأعمدة.

لنفترض أننا المعلومات التي يمثلها مثل هذا الجدول:

create table the_entity_incorrect
(
  id integer,
  uniqnull integer null, /* we want this to be "unique and nullable" */
  primary key (id)
);

ويمكننا أن نفعل ذلك عن طريق وضع uniqnull، وبصرف النظر إضافة الجدول الثاني لإقامة علاقة بين القيم uniqnull وthe_entity (بدلا من الاضطرار uniqnull the_entity "الداخل"):

create table the_entity
(
  id integer,
  primary key(id)
);

create table the_relation
(
  the_entity_id integer not null,
  uniqnull integer not null,

  unique(the_entity_id),
  unique(uniqnull),
  /* primary key can be both or either of the_entity_id or uniqnull */
  primary key (the_entity_id, uniqnull), 
  foreign key (the_entity_id) references the_entity(id)
);

لربط قيمة uniqnull إلى صف في the_entity نحتاج أيضا لإضافة صف في the_relation.

لالصفوف في the_entity كانت ترتبط أية قيم uniqnull (أي لتلك سوف نضع NULL في the_entity_incorrect) ونحن ببساطة لا إضافة صف في the_relation.

سوف

ملحوظة تقدر لuniqnull تكون فريدة من نوعها لجميع the_relation، ولاحظ أيضا أن لكل قيمة في the_entity يمكن أن يكون هناك في معظم قيمة واحدة في the_relation، منذ المفاتيح الأساسية والأجنبية على أنها تفرض ذلك.

وبعد ذلك، إذا كان قيمة 5 لuniqnull هي تترافق مع معرف the_entity من 3، ونحن بحاجة إلى:

start transaction;
insert into the_entity (id) values (3); 
insert into the_relation (the_entity_id, uniqnull) values (3, 5);
commit;

و، إذا كان قيمة id من 10 لthe_entity ليس لها نظير uniqnull، ونحن نفعل فقط:

start transaction;
insert into the_entity (id) values (10); 
commit;

لإلغاء تطبيع هذه المعلومات والحصول على البيانات فإن الجدول مثل the_entity_incorrect عقد، ونحن بحاجة إلى:

select
  id, uniqnull
from
  the_entity left outer join the_relation
on
  the_entity.id = the_relation.the_entity_id
;

و"الانضمام الخارجي اليسار" المشغل يضمن كافة الصفوف من the_entity سوف تظهر في النتيجة، وضع NULL في العمود uniqnull عندما موجودة في the_relation أي أعمدة مطابقة.

وتذكر، وقضى أي جهد لعدة أيام (أو أسابيع أو شهور) في تصميم قاعدة بيانات تطبيع جيدا (والمقابلة denormalizing الآراء والإجراءات) سيوفر لك سنوات (أو عقود) من الألم وإهدار الموارد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top