Diyelim ki bir tablom var:
CREATE TABLE items
(
item serial PRIMARY KEY,
...
);
Şimdi, (not ben değilim lütfen her öğe için "izinler" kavramını tanıtmak istiyorum değil o öğenin burada veritabanı erişim izinleri hakkında konuşurken, ancak iş mantığı izinleri). Her öğenin varsayılan izinleri ve varsayılan izinleri geçersiz kılabilecek kullanıcı başına izinleri vardır.
Bunu uygulamanın birkaç yolunu düşünmeye çalıştım ve aşağıdaki çözümleri buldum, ancak hangisinin en iyi ve neden olduğu konusunda emin değilim:
1) Boole Çözümü
Her izin için bir boole sütunu kullanın:
CREATE TABLE items
(
item serial PRIMARY KEY,
can_change_description boolean NOT NULL,
can_change_price boolean NOT NULL,
can_delete_item_from_store boolean NOT NULL,
...
);
CREATE TABLE item_per_user_permissions
(
item int NOT NULL REFERENCES items(item),
user int NOT NULL REFERENCES users(user),
PRIMARY KEY(item, user),
can_change_description boolean NOT NULL,
can_change_price boolean NOT NULL,
can_delete_item_from_store boolean NOT NULL,
...
);
Avantajları : Her izin adlandırılır.
Dezavantajları : Sütun sayısını önemli ölçüde artıran düzinelerce izin vardır ve bunları iki kez tanımlamanız gerekir (her tabloda bir kez).
2) Tamsayı Çözümü
Bir tam sayı kullanın ve bunu bir bit alanı olarak ele alın (yani bit 0 içindir can_change_description
, bit 1 içindir can_change_price
, vb. Ve izinleri ayarlamak veya okumak için bitsel işlemleri kullanın).
CREATE DOMAIN permissions AS integer;
Avantajları : çok hızlı.
Dezavantajları : Hem veritabanında hem de ön uç arabiriminde hangi bitin hangi izin anlamına geldiğini takip etmeniz gerekir.
3) Bitfield Çözümü
2 ile aynı), ancak kullanın bit(n)
. Büyük olasılıkla aynı avantaj ve dezavantajlar, belki biraz daha yavaş.
4) Enum Çözümü
İzinler için bir numaralandırma türü kullanın:
CREATE TYPE permission AS ENUM ('can_change_description', 'can_change_price', .....);
ve ardından varsayılan izinler için fazladan bir tablo oluşturun:
CREATE TABLE item_default_permissions
(
item int NOT NULL REFERENCES items(item),
perm permission NOT NULL,
PRIMARY KEY(item, perm)
);
ve kullanıcı başına tanım tablosunu şu şekilde değiştirin:
CREATE TABLE item_per_user_permissions
(
item int NOT NULL REFERENCES items(item),
user int NOT NULL REFERENCES users(user),
perm permission NOT NULL,
PRIMARY KEY(item, user, perm)
);
Avantajları : Bireysel izinleri adlandırması kolaydır (bit konumlarını işlemeniz gerekmez).
Dezavantajları : Yalnızca varsayılan izinleri alırken bile, iki ek tabloya erişmeyi gerektirir: birincisi, varsayılan izinler tablosu ve ikincisi, enum değerlerini depolayan sistem kataloğu.
Özellikle bu öğenin her bir sayfa görünümü için varsayılan izinlerin alınması gerektiğinden , son alternatifin performans etkisi önemli olabilir.
5) Enum Dizi Çözümü
4 ile aynı), ancak tüm (varsayılan) izinleri tutmak için bir dizi kullanın:
CREATE TYPE permission AS ENUM ('can_change_description', 'can_change_price', .....);
CREATE TABLE items
(
item serial PRIMARY KEY,
granted_permissions permission ARRAY,
...
);
Avantajları : Bireysel izinleri adlandırması kolaydır (bit konumlarını işlemeniz gerekmez).
Dezavantajları : 1. normal formu kırar ve biraz çirkin. İzin sayısı büyükse (yaklaşık 50) arka arkaya önemli sayıda bayt alır.
Başka alternatifler düşünebilir misiniz?
Hangi yaklaşım izlenmeli ve neden?
Lütfen dikkat: Bu, daha önce Stackoverflow'da yayınlanan bir sorunun değiştirilmiş sürümüdür .
bigint
alan (her biri 64 bit için iyi) veya bir bit dizesi seçebilirim . SO'ya yardımcı olabilecek birkaç ilgili cevap