Özel benzersiz sütun kısıtlaması, yalnızca bir sütunun belirli bir değeri varsa uygulanır


19

Aşağıdaki gibi özel bir benzersiz sütun kısıtlaması olması mümkün müdür? Diyelim ki iki sütun subsetve her iki dizgim var type(veri türleri muhtemelen önemli değil).

Eğer type"doğru" olduğunu, sonra ben birleşimi istiyorum typeve subsetbenzersiz olması. Aksi takdirde, herhangi bir kısıtlama yoktur. Debian üzerinde PostgreSQL 8.4 kullanıyorum.


Yanıtlar:


31

Başka bir deyişle, subseteğer benzersiz olmak istersiniz type = 'true'.
Bir kısmi benzersiz dizin yapacak:

CREATE UNIQUE INDEX tbl_some_name_idx ON tbl (subset) WHERE type = 'true';

Bu yolla NULL, aksi halde mümkün olmayan benzersiz kombinasyonlar bile yapabilirsiniz - bu ilgili cevapta ayrıntılı olarak açıklandığı gibi:
PostgreSQL çok sütunlu benzersiz kısıtlama ve NULL değerler


Teşekkürler Erwin. Belgelere baktığımda bu seçeneği görmedim. Daha doğrudan bir bağlantı postgresql.org/docs/current/interactive/indexes-partial.html . Bakınız Örnek 11-3.
Faheem Mitha

@FaheemMitha: Gerekirse beri, bir seviye daha yüksek bağlantılı kombine bir kısmi endeksi bir ile benzersiz bir dizin .
Erwin Brandstetter

1
@Erwin Bu sayfada (kısmi dizinler hakkında), kısmi benzersiz dizine sahip bir örnek var.
ypercubeᵀᴹ

@ ypercube: Ah, doğru. Bu daha iyi bir bağlantı. Cevabımı bu son bölüme işaret edecek şekilde değiştirdim.
Erwin Brandstetter

6

Bu, Erwin'in yukarıdaki cevabı için tamamlayıcıdır, ancak PostgreSQL, bir dizi dizin türünü destekler. Bunlar genellikle birbirini dışlamaz. Bunları şu şekilde düşünebilirsiniz:

  • Endeks yöntemi (btree, GiST, GIN, vb.). Gerekirse birini seçin (btree varsayılan değerdir)
  • Kısmi veya dolu. Kısmi bir where cümlesi kullanın
  • Doğrudan veya işlevsel. Fonksiyonların çıktısını indeksleyebilirsiniz.
  • Benzersiz veya benzersiz olmayan

Bunların hepsi çeşitli şekillerde birleştirilebilir. Burada yaptığınız tek şey, benzersiz ve kısmi özellikleri kullanmaktır, böylece size kısmi benzersiz dizinler verir (bu, öğrenirken son derece yararlıdır).

Ancak , türün doğru olduğu alt küme alanında büyük / küçük harf duyarlı olmayan bir dizin olmasını istediğinizi varsayalım . Sonra işlevsel bir tanım eklersiniz:

CREATE INDEX my_index_name_idx_u ON tbl (lower(subset)) WHERE type;

Bunun, türün true olduğu alt küme özniteliğinde çağrılan lower () işlevinin çıktısında benzersiz bir dizin oluşturduğunu unutmayın .


Erwin'in cevabındaki indeks doğrudan, örneğinizdeki indeks fonksiyonel, doğru mu?
Faheem Mitha

@FaheemMitha: Doğru.
Erwin Brandstetter
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.