Boş sütun benzersiz kısıtlama oluşturma
Bu düzen ile bir tablo var:
CREATE TABLE Favorites
(
FavoriteId uuid NOT NULL PRIMARY KEY,
UserId uuid NOT NULL,
RecipeId uuid NOT NULL,
MenuId uuid
)
Benzersiz kısıtlama buna benzer oluşturmak istiyorum:
ALTER TABLE Favorites
ADD CONSTRAINT Favorites_UniqueFavorite UNIQUE(UserId, MenuId, RecipeId);
Ancak, bu aynı ile birden fazla satır (UserId, RecipeId)
Eğer MenuId IS NULL
izin verir. MenuId
NULL
ilgili menü olan bir favori saklamak için izin istiyorum, ama ben sadece en fazla kullanıcı/başına bu satırlar bir tarifi çifti istiyorum.
Şimdiye kadar sahip olduğum fikirler vardır:
Null yerine kodlanmış bazı UUID (sıfır gibi) kullanın.
Ancak,MenuId
her kullanıcının menülerde FK kısıtlaması var, o zaman özel bir "can sıkıcı bir durumdur." her kullanıcı için boş bir menü oluşturmak istiyorumBoş bir giriş yerine bir tetikleyici kullanarak varlığını denetle.
Bu ne kadar can sıkıcı olduğunu düşünüyorum ve tetikleyiciler mümkün olduğunca kaçınmak istiyorum. Artı, onları verilerimi asla kötü bir durumda olduğunu garanti güvenmiyorum.Unut gitsin ve orta-ware veya Ekle işlev boş bir girdiyi önceki varlığı için kontrol, ve bu kısıtlama yok.
PostgreSQL 9.0 kullanıyorum.
Gözden kaçırdığım herhangi bir yöntem var mı?
CEVAP
Oluşturmak two partial indexes:
CREATE UNIQUE INDEX favo_3col_uni_idx ON favorites (user_id, menu_id, recipe_id)
WHERE menu_id IS NOT NULL;
CREATE UNIQUE INDEX favo_2col_uni_idx ON favorites (user_id, recipe_id)
WHERE menu_id IS NULL;
Bu şekilde, yalnızca menu_id
BOŞ, etkili, istenen kısıtlama uyguluyor nerede (user_id, recipe_id)
bir kombinasyonu olabilir.
Olası sakıncaları: bir yabancı anahtar başvuru (user_id, menu_id, recipe_id)
Bu şekilde yapamazsınız Bankası CLUSTER
kısmi dizin ve sorgu olmadan bir eşleştirme WHERE
durumu kullanamazsınız kısmi dizin.
FK başvuru üç sütunluk (PK sütun kullanın) isteyeceğini pek sanmıyorum. Eğer bir ihtiyacınız olursatamamlayınendeks, alternatif olarak favo_3col_uni_idx
WHERE
durumu bırakın ve gereksinimlerinizi hala uygulanır.
Endeks, şimdi bütün tablo kapsayan, diğeri de büyür ile çakışıyor. Tipik sorgular ve NULL
değerleri yüzdesine bağlı olarak, bu olabilir ya da yararlı olmayabilir. Aşırı durumlarda bile favo_3col_uni_idx
Her iki sürümü korumak için yardımcı olabilir.
Kenara: mixed case identifiers in PostgreSQL. kullanmamanızı öneririm
Nasıl MySQL birden çok sütun benzersiz...
Kısıtlama - birden çok sütun üzerinde ...
Birden çok sütun benzersiz kısıtlama...
Varlık içinde Kısıtlama benzersiz Çerç...
SQL Server sütun için varsayılan kısıt...