मान लीजिए कि मेरे पास 4 प्रकार की सेवाएं हैं जो मैं प्रदान करता हूं (वे अक्सर बदलने की संभावना नहीं हैं):
- परिक्षण
- डिज़ाइन
- प्रोग्रामिंग
- अन्य
मान लीजिए कि मेरे पास 60-80 वास्तविक सेवाएँ हैं, जिनमें से प्रत्येक उपरोक्त श्रेणियों में से एक में आती है। उदाहरण के लिए, 'ए सर्विस' तकनीक ए का उपयोग करके "टेस्ट प्रोग्राम" हो सकता है और यह "परीक्षण" प्रकार का है।
मैं उन्हें एक डेटाबेस में बदलना चाहता हूं। मैं कुछ विकल्पों के साथ आया:
विकल्प 0:
VARCHAR
सीधे सेवा प्रकार को एक स्ट्रिंग के रूप में एन्कोड करने के लिए सीधे उपयोग करें
विकल्प 1:
डेटाबेस का उपयोग करें enum
। लेकिन, एनम बुराई है
विकल्प 2:
दो तालिकाओं का उपयोग करें:
service_line_item (id, service_type_id INT, description VARCHAR);
service_type (id, service_type VARCHAR);
मैं भी संदर्भात्मक अखंडता का आनंद ले सकते हैं:
ALTER service_line_item
ADD FOREIGN KEY (service_type_id) REFERENCES service_type (id);
अच्छा लगता है, हाँ?
लेकिन मुझे अभी भी चीजों को सांकेतिक शब्दों में बदलना और पूर्णांक से निपटना है, अर्थात तालिका को पॉप्युलेट करते समय। या मुझे टेबल के साथ काम करते समय या काम करते समय विस्तृत प्रोग्रामिंग या डीबी निर्माण करना पड़ता है। अर्थात्, जब डेटाबेस से सीधे निपटते हैं, या प्रोग्रामिंग साइड पर नई ऑब्जेक्ट ओरिएंटेड इकाइयाँ बनाते हैं, और यह सुनिश्चित करते हैं कि मैं उन्हें सही ढंग से संचालित करूं।
विकल्प 3:
उपयोग न करें enum
, दो तालिकाओं का उपयोग न करें, लेकिन सिर्फ एक पूर्णांक स्तंभ का उपयोग करें
service_line_item (
id,
service_type INT, -- use 0, 1, 2, 3 (for service types)
description VARCHAR
);
यह एक um फर्जी एनम ’की तरह है, जिसे चीजों के कोड साइड पर अधिक ओवरहेड की आवश्यकता होती है, जैसे कि यह जानना {2 == 'Programming'}
और उससे उचित तरीके से निपटना।
सवाल:
वर्तमान में मैंने इसे विकल्प 2 का उपयोग करके लागू किया है , अवधारणाओं के तहत निर्देशित
- एनम का उपयोग न करें (विकल्प 1)
- स्प्रेडशीट के रूप में डेटाबेस का उपयोग करने से बचें (विकल्प 0)
लेकिन मैं यह महसूस करने में मदद नहीं कर सकता कि प्रोग्रामिंग और संज्ञानात्मक ओवरहेड के संदर्भ में मुझे बेकार लगता है - मुझे दो तालिकाओं के बारे में पता होना चाहिए, और दो तालिकाओं, बनाम एक के साथ व्यवहार करना होगा।
'कम बेकार' तरीके के लिए, मैं देख रहा हूं Option 3
। आईटी हल्का होता है और इसे अनिवार्य रूप से एक ही कोड को संचालित करने की आवश्यकता होती है (मामूली संशोधनों के साथ लेकिन जटिलता और संरचना मूल रूप से एक ही है लेकिन एक एकल तालिका के साथ)
मुझे लगता है कि आदर्श रूप में यह हमेशा बेकार नहीं होता है, और दोनों में से किसी एक विकल्प के लिए अच्छे मामले हैं, लेकिन क्या एक अच्छा दिशानिर्देश है जब किसी को विकल्प 2 और कब विकल्प 3 का उपयोग करना चाहिए?
जब केवल दो प्रकार होते हैं (बाइनरी)
इस प्रश्न को थोड़ा और जोड़ने के लिए ... उसी स्थान पर, मेरे पास "मानक" या "अपवाद" सेवा का एक द्विआधारी विकल्प है, जो सेवा लाइन आइटम पर लागू हो सकता है। मैंने विकल्प 3 का उपयोग करते हुए एनकोड किया है ।
मैंने मान {{मानक ”,“ अपवाद ”} रखने के लिए नई तालिका नहीं बनाने का निर्णय लिया। इसलिए मेरा कॉलम सिर्फ {0, 1} रखता है और मेरे कॉलम का नाम कहा जाता है exception
, और मेरा कोड एक अनुवाद कर {0, 1} => {STANDARD, EXCEPTION}
रहा है (जिसे मैंने प्रोग्रामिंग भाषा में स्थिरांक के रूप में एन्कोड किया है)
अब तक उस तरह से या तो ..... पसंद नहीं है (विकल्प 2 पसंद नहीं है और न ही विकल्प 3)। मैं विकल्प 2 को 3 से बेहतर पाता हूं, लेकिन अधिक ओवरहेड के साथ, और फिर भी मैं एन्कोडिंग चीजों से बच नहीं सकता क्योंकि पूर्णांक से कोई फर्क नहीं पड़ता कि मैं 2 और 3 में से किस विकल्प का उपयोग करता हूं।
ORM
कुछ संदर्भ जोड़ने के लिए, उत्तर पढ़ने के बाद - मैंने अभी-अभी (हाल ही में) एक ओआरएम का उपयोग करना शुरू किया है, मेरे मामले में डॉक्ट्रिन 2. एनोटेशन के माध्यम से डीबी स्कीमा को परिभाषित करने के बाद, मैं डेटाबेस को आबाद करना चाहता था। चूंकि मेरा पूरा डेटा सेट अपेक्षाकृत छोटा है, इसलिए मैं यह देखने के लिए कि यह कैसे काम करता है, प्रोग्रामिंग कंस्ट्रक्शंस का उपयोग करने की कोशिश करना चाहता था।
मैंने पहली बार service_type
s, और फिर service_line_item
s को आबाद किया , क्योंकि एक वास्तविक स्प्रेडशीट से मौजूदा सूची थी। इसलिए 'मानक / अपवाद' और 'परीक्षण' जैसी चीजें स्प्रेडशीट पर सभी तार हैं, और उन्हें डीबी में संग्रहीत करने से पहले उचित प्रकारों में एन्कोड किया जाना है।
मुझे यह SO उत्तर मिला: doctrine2 में ENUM के बजाय आप क्या उपयोग करते हैं? , जिसने डीबी के एनम निर्माण का उपयोग नहीं करने का सुझाव दिया, लेकिन एक INT
क्षेत्र का उपयोग करने के लिए और प्रोग्रामिंग भाषा के 'कास्ट' निर्माण का उपयोग करके प्रकारों को एन्कोड करने के लिए।
लेकिन जैसा कि ऊपर एसओ प्रश्न में कहा गया है, मैं सीधे पूर्णांक का उपयोग करने से बच सकता हूं और भाषा निर्माण - स्थिरांक का उपयोग कर सकता हूं - एक बार जब वे परिभाषित होते हैं ...।
लेकिन फिर भी .... कोई फर्क नहीं पड़ता कि आप इसे कैसे चालू करते हैं, अगर मैं string
एक प्रकार के रूप में शुरू कर रहा हूं, तो मुझे पहले इसे एक उचित प्रकार में बदलना होगा, यहां तक कि एक ओआरएम का उपयोग करते समय भी।
तो अगर कहते हैं $str = 'Testing';
, मुझे अभी भी कहीं एक ब्लॉक की आवश्यकता है जो कुछ ऐसा करता है:
switch($str):
{
case 'Testing': $type = MyEntity::TESTING; break;
case 'Other': $type = MyEntity::OTHER; break;
}
अच्छी बात यह है कि आप पूर्णांक / मैजिक नंबरों के साथ काम नहीं कर रहे हैं [इसके बजाय, एन्कोडेड निरंतर मात्रा के साथ काम कर रहे हैं], लेकिन बुरी बात यह है कि आप इस रूपांतरण चरण के बिना डेटाबेस में चीजों को ऑटो-जादुई रूप से खींच नहीं सकते, मेरे लिए ज्ञान।
और इसका मतलब है कि, मेरे हिस्से में, "अभी भी चीजों को सांकेतिक शब्दों में बदलना और पूर्णांक से निपटने के लिए" जैसी चीजें हैं। (दी गई, अब, Ocramius की टिप्पणी के बाद, मुझे सीधे पूर्णांक के साथ सौदा नहीं करना होगा, लेकिन नामांकित स्थिरांक और स्थिरांक से / के रूप में कुछ रूपांतरण करने की आवश्यकता है)।