Filtrelenen benzersiz dizin mükemmel bir fikir ama küçük bir dezavantajı var - WHERE identity_column > <current value>
şartı ya da kullanımı farketmez WHERE identity_column NOT IN (<list of ids for duplicate values here>)
.
İlk yaklaşımla, gelecekteki yinelenen verileri, mevcut (şimdi) verilerin yinelemelerini ekleyebileceksiniz. Örneğin, şu anda (yalnızca bir satır) satırınız varsa CompanyName = 'Software Inc.'
, dizin aynı şirket adıyla bir satır daha eklenmesini yasaklamaz. Sadece iki kez denerseniz bunu yasaklar.
İkinci yaklaşımla bir gelişme var, yukarıdaki işe yaramayacak (ki bu iyi.) Ancak yine de daha fazla kopya veya mevcut kopya ekleyebileceksiniz. Örneğin, şu anda (iki veya daha fazla) CompanyName = 'DoubleData Co.'
satırınız varsa, dizin aynı şirket adıyla bir satır daha eklenmesini yasaklamaz. Sadece iki kez denerseniz bunu yasaklar.
(Güncelleme) Bu, her yinelenen ad için, bir hariç tutma listesinden uzak tutmanız durumunda düzeltilebilir. Yukarıdaki örnekte olduğu gibi, yinelenen CompanyName = DoubleData Co.
ve kimlikleri olan 4 satır varsa 4,6,8,9
, dışlama listesinde bu kimliklerden yalnızca 3 tanesinin olması gerekir.
İkinci yaklaşımda, başka bir dezavantaj hantal durumdur (ne kadar hantal, ilk etapta kaç kopya olduğuna bağlıdır), çünkü SQL-Server, NOT IN
operatörü WHERE
filtrelenmiş indeksler bölümünde desteklemiyor gibi görünmektedir . SQL-Fiddle'a bakınız . Bunun yerine, yüzlerce kopya adınız varsa, böyle bir koşulda verimlilik sonuçları olup olmadığından emin değilim WHERE (CompanyID NOT IN (3,7,4,6,8,9))
gibi bir şeye sahip WHERE (CompanyID <> 3 AND CompanyID <> 7 AND CompanyID <> 4 AND CompanyID <> 6 AND CompanyID <> 8 AND CompanyID <> 9)
olmalısınız.
Başka bir çözüm (@Alex Kuznetsov'unkilere benzer) başka bir sütun eklemek, onu sayı numaralarıyla doldurmak ve bu sütunu içeren benzersiz bir dizin eklemek:
ALTER TABLE Company
ADD Rn TINYINT DEFAULT 1;
UPDATE x
SET Rn = Rnk
FROM
( SELECT
CompanyID,
Rn,
Rnk = ROW_NUMBER() OVER (PARTITION BY CompanyName
ORDER BY CompanyID)
FROM Company
) x ;
CREATE UNIQUE INDEX CompanyName_UQ
ON Company (CompanyName, Rn) ;
Ardından, yinelenen adı olan bir satır eklemek DEFAULT 1
özellik ve benzersiz dizin nedeniyle başarısız olur . Bu hala% 100 kusursuz değil (Alex's iken). İfadede Rn
açıkça ayarlanmışsa INSERT
veya Rn
değerler kötü amaçlı olarak güncellenirse , yinelenenler yine de kaymaya devam eder .
SQL Fiddle-2