मान लें कि मेरे पास मदों की एक तालिका है:
CREATE TABLE items
(
item serial PRIMARY KEY,
...
);
अब, मैं प्रत्येक आइटम के लिए "अनुमति" की अवधारणा को पेश करना चाहता हूं (कृपया ध्यान दें, मैं यहां डेटाबेस एक्सेस अनुमतियों के बारे में बात नहीं कर रहा हूं , लेकिन उस आइटम के लिए व्यावसायिक तर्क अनुमतियाँ)। प्रत्येक आइटम में डिफ़ॉल्ट अनुमतियाँ हैं और प्रति-उपयोगकर्ता अनुमतियाँ भी हैं जो डिफ़ॉल्ट अनुमतियों को ओवरराइड कर सकती हैं।
मैंने इसे लागू करने के कई तरीकों के बारे में सोचने की कोशिश की और निम्नलिखित समाधानों के साथ आया, लेकिन मुझे यकीन नहीं है कि कौन सा सबसे अच्छा है और क्यों:
1) बूलियन समाधान
प्रत्येक अनुमति के लिए बूलियन कॉलम का उपयोग करें:
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,
...
);
लाभ : प्रत्येक अनुमति का नाम है।
नुकसान : दर्जनों अनुमतियाँ हैं जो स्तंभों की संख्या में काफी वृद्धि करती हैं और आपको उन्हें दो बार (प्रत्येक तालिका में एक बार) परिभाषित करना होगा।
2) द इंटेगर सॉल्यूशन
पूर्णांक का उपयोग करें और इसे एक बिटफील्ड के रूप में मानें (यानी बिट 0 के लिए है can_change_description
, बिट 1 के लिए है can_change_price
, और इसी तरह, और अनुमतियों को सेट या पढ़ने के लिए बिटवाइज़ संचालन का उपयोग करें)।
CREATE DOMAIN permissions AS integer;
लाभ : बहुत तेज।
नुकसान : आपको इस बात का ध्यान रखना होगा कि कौन सा बिट डेटाबेस और फ्रंट-एंड इंटरफेस दोनों में किस अनुमति के लिए है।
3) बिटफील्ड सॉल्यूशन
2 के रूप में भी), लेकिन उपयोग करें bit(n)
। ज्यादातर समान फायदे और नुकसान की संभावना है, शायद थोड़ा धीमा।
4) एनम समाधान
अनुमतियों के लिए एक एनुम प्रकार का उपयोग करें:
CREATE TYPE permission AS ENUM ('can_change_description', 'can_change_price', .....);
और फिर डिफ़ॉल्ट अनुमतियों के लिए एक अतिरिक्त तालिका बनाएं:
CREATE TABLE item_default_permissions
(
item int NOT NULL REFERENCES items(item),
perm permission NOT NULL,
PRIMARY KEY(item, perm)
);
और प्रति-उपयोगकर्ता परिभाषा तालिका को इसमें बदलें:
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)
);
लाभ : व्यक्तिगत अनुमतियों के नाम पर आसान (आपको बिट पदों को संभालने की आवश्यकता नहीं है)।
नुकसान : यहां तक कि जब केवल डिफ़ॉल्ट अनुमतियों को पुनर्प्राप्त किया जाता है, तो इसके लिए दो अतिरिक्त तालिकाओं तक पहुंचने की आवश्यकता होती है: पहला, डिफ़ॉल्ट अनुमतियाँ तालिका, और दूसरा, सिस्टम कैटलॉग में एनम मानों को संग्रहीत करना।
विशेष रूप से क्योंकि उस आइटम के हर एक पृष्ठ दृश्य के लिए डिफ़ॉल्ट अनुमतियाँ पुनर्प्राप्त की जानी चाहिए , अंतिम विकल्प का प्रदर्शन प्रभाव महत्वपूर्ण हो सकता है।
5) एनुम अर्रे समाधान
4 के समान), लेकिन सभी (डिफ़ॉल्ट) अनुमतियों को रखने के लिए एक सरणी का उपयोग करें:
CREATE TYPE permission AS ENUM ('can_change_description', 'can_change_price', .....);
CREATE TABLE items
(
item serial PRIMARY KEY,
granted_permissions permission ARRAY,
...
);
लाभ : व्यक्तिगत अनुमतियों के नाम पर आसान (आपको बिट पदों को संभालने की आवश्यकता नहीं है)।
नुकसान : 1 सामान्य रूप को तोड़ता है और थोड़ा बदसूरत होता है। यदि अनुमतियों की संख्या बड़ी है (लगभग 50) तो एक पंक्ति में काफी संख्या में बाइट्स लेता है।
क्या आप अन्य विकल्पों के बारे में सोच सकते हैं?
कौन सा दृष्टिकोण लिया जाना चाहिए और क्यों?
कृपया ध्यान दें: यह Stackoverflow पर पहले पोस्ट किए गए प्रश्न का एक संशोधित संस्करण है ।
bigint
फ़ील्ड (प्रत्येक 64 बिट के लिए अच्छा) या थोड़ा स्ट्रिंग चुन सकता हूं । मैंने एसओ पर संबंधित जवाबों की एक जोड़ी