SORU
27 Kasım 2011, Pazar


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:

  1. 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 istiyorum

  2. Boş 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.

  3. 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
27 Kasım 2011, Pazar


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

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • buttheadgsxr1000

    buttheadgsxr

    24 Ocak 2008
  • Diogo Oliveira

    Diogo Olivei

    4 HAZİRAN 2006
  • Harvest: Greg Laurie

    Harvest: Gre

    6 HAZİRAN 2006