मुझे इसके लिए दो तालिकाओं की आवश्यकता के कुछ कारण दिखाई दे रहे हैं:
- असली कर्मचारियों के पास एक नाम, एक विभाग आदि होना चाहिए, जबकि पूर्वानुमान कर्मचारियों में केवल ये विशेषताएं हो सकती हैं
- ऐसी जिम्मेदारियां होंगी जो केवल वास्तविक कर्मचारियों के पास हो सकती हैं, इसलिए आप उन्हें अलग से संदर्भित करने में सक्षम होना चाहते हैं
लेकिन साथ ही आप यह सुनिश्चित करना चाहते हैं कि दो तालिकाओं में आईडी का कोई टकराव न हो, क्योंकि (उम्मीद है) पूर्वानुमान कर्मचारी वास्तविक कर्मचारी बन जाएंगे।
ऐसा करने का तरीका सुपर-टाइप/सब-टाइप स्ट्रक्चर को लागू करना है। तो आपके पास एक टेबल है, कर्मचारी जो एकल प्राथमिक कुंजी की गारंटी देता है, और वास्तविक और पूर्वानुमान कर्मचारियों के लिए दो आश्रित टेबल। टाइप कॉलम का उपयोग महत्वपूर्ण है, क्योंकि यह सुनिश्चित करता है कि दिया गया कर्मचारी केवल एक उप-तालिका में दिखाई दे।
create table employees
( emp_id number not null
, emp_type varchar2(8) not null
, constraint emp_pk primary key (emp_id)
, constraint emp_uk unique (emp_id, emp_type)
, constraint emp_type_ck check (emp_type in ('FORECAST', 'ACTUAL'));
create table actual_employees
( emp_id number not null
, emp_type varchar2(8) not null
, name varchar2(30) not null
, deptno number(2,0) not null
, sal number(7,2) not null
, hiredate date not null
, constraint actemp_pk primary key (emp_id)
, constraint actemp_type_ck check (emp_type = 'ACTUAL')
, constraint actemp_emp_fk foreign key (emp_id, emp_type)
references emp (emp_id, emp_type)
deferrable initially deferred ;
create table forecast_employees
( emp_id number not null
, emp_type varchar2(8) not null
, name varchar2(30)
, deptno number(2,0)
, sal number(7,2)
, predicted_joining_date date
, constraint foremp_pk primary key (emp_id)
, constraint foremp_type_ck check (emp_type = 'FORECAST')
, constraint foremp_emp_fk foreign key (emp_id, emp_type)
references emp (emp_id, emp_type)
deferrable initially deferred ;
तो चाबियाँ थोड़ी अजीब लग सकती हैं। पैरेंट टेबल में प्राइमरी की और कंपाउंड यूनिक की दोनों होती हैं। प्राथमिक कुंजी EMP_ID के एकल उदाहरण की गारंटी देती है। अद्वितीय कुंजी हमें चाइल्ड टेबल पर विदेशी कुंजी बनाने की अनुमति देती है जो EMP_ID और EMP_TYPE दोनों को संदर्भित करती है। बच्चे पर चेक बाधाओं के साथ संयुक्त tयह इसलिए है क्योंकि वे इसकी प्राथमिक कुंजी के बजाय मूल तालिका पर अद्वितीय कुंजी का संदर्भ देते हैं। यह व्यवस्था सुनिश्चित करती है कि कर्मचारी FORECAST_EMPLOYEES या ACTUAL_EMPLOYEES में से किसी में भी हो सकता है लेकिन दोनों में नहीं।
पूर्वानुमान कर्मचारियों को वास्तविक कर्मचारी में बदलने की अनुमति देने के लिए विदेशी कुंजी आस्थगित हैं। इसके लिए तीन गतिविधियों की आवश्यकता है:
- FORECAST_EMPLOYEES से रिकॉर्ड हटाया जा रहा है
- ACTUAL_EMPLOYEES में रिकॉर्ड सम्मिलित करना
- EMP_TYPE को बदलना (लेकिन नहीं EMPLOYEES में EMP_ID)।
आस्थगित बाधाओं के साथ क्रिया 2 और 3 को सिंक्रनाइज़ करना आसान है।
साथ ही, ध्यान दें कि कर्मचारियों को संदर्भित करने वाली अन्य विदेशी कुंजी बाधाओं को अद्वितीय कुंजी के बजाय प्राथमिक कुंजी का उपयोग करना चाहिए। यदि संबंध कर्मचारी के प्रकार की परवाह करता है, तो शायद इसके बजाय चाइल्ड टेबल से लिंक होना चाहिए।
डेटा मॉडलिंग की दुनिया में आपका स्वागत है। यह एक बड़ा सिरदर्द है। क्योंकि गन्दा वास्तविकता को एक स्वच्छ डेटा मॉडल में फिट करने की कोशिश करना कठिन है :आपको इसे ठीक करने के लिए स्पष्ट आवश्यकताओं की आवश्यकता है, और यह समझने की आवश्यकता है कि सबसे महत्वपूर्ण क्या है ताकि आप समझदारी से समझौता कर सकें।
मैंने आपके अन्य प्रश्न के आधार पर एक सुपर-टाइप/सब-टाइप दृष्टिकोण का प्रस्ताव दिया, और क्योंकि यह डेटा के दो सेटों को संभालने का सबसे अच्छा तरीका प्रतीत होता है:वास्तविक कर्मचारी और काल्पनिक कर्मचारी। मुझे लगता है कि उन दो समूहों के साथ अलग तरह से व्यवहार करने की जरूरत है। उदाहरण के लिए, मैं प्रबंधकों को वास्तविक कर्मचारी होने पर जोर दूंगा। यह ACTUAL_EMPLOYEES के खिलाफ एक अखंडता बाधा के साथ करना आसान है और एक ही तालिका के साथ प्राप्त करना कठिन है जिसमें दोनों प्रकार के कर्मचारी शामिल हैं।
निश्चित रूप से दो टेबल होने का मतलब संभवतः उनकी संरचनाओं को सिंक्रनाइज़ करने के संबंध में अधिक काम उत्पन्न करता है। तो क्या? यह काफी हद तक तुच्छ है, क्योंकि एक से दो ALTER TABLE स्टेटमेंट लिखना मुश्किल से अधिक काम है। साथ ही यह बहुत संभव है कि नया कॉलम केवल वास्तविक कर्मचारियों पर लागू होता है और कर्मचारियों की भविष्यवाणी करने के लिए इसका कोई मतलब नहीं है (जैसे EARNED_COMMISSION, LAST_REVIEW_RATING)। उस रोशनी में अलग-अलग टेबल होने से डेटा मॉडल अधिक सटीक हो जाता है।
निर्भर तालिकाओं की नकल करने के संबंध में, जैसा कि ओली बताते हैं, यह एक गलतफहमी है। तालिकाएँ जो सभी कर्मचारियों पर लागू होती हैं, उनकी वास्तविकता की परवाह किए बिना, उन्हें कर्मचारी तालिका का संदर्भ देना चाहिए, न कि उसके बच्चों को।
अंत में मुझे समझ में नहीं आता कि ऐतिहासिक डेटा को बनाए रखना एक की तुलना में दो तालिकाओं के साथ कठिन क्यों है। अधिकांश जर्नलिंग कोड पूरी तरह से डेटा डिक्शनरी से उत्पन्न होना चाहिए।
तीन हैं टेबल:
- कर्मचारी - अद्वितीय EMP_IDs की गारंटी के लिए एक मास्टर टेबल
- ACTUAL_EMPLOYEES - आपकी कंपनी के लिए काम करने वाले लोगों के लिए चाइल्ड टेबल
- FORECAST_EMPLOYEES - उन लोगों के लिए चाइल्ड टेबल, जिन्हें आप अपनी कंपनी में भर्ती करना चाहते हैं
कृपया ध्यान रखें कि मैं आपके द्वारा प्रदान किए गए कम विवरण से आपके व्यावसायिक तर्क के बारे में अनुमान लगा रहा हूं।
अब मुझे ऐसा लगता है कि जो लोग अभी तक आपकी कंपनी के लिए काम नहीं करते हैं उनके पास कोई भी संबद्ध गतिविधि नहीं होनी चाहिए। उस परिदृश्य में आपके पास एक टेबल होगा, EMPLOYEE_ACTIVITIES, जो ACTUAL_EMPLOYEES का एक बच्चा है।
लेकिन शायद आप वास्तव में उन लोगों के लिए गतिविधियाँ करते हैं जो मौजूद नहीं हैं। तो यहाँ एक विकल्प है:एक टेबल या दो? एक टेबल डिज़ाइन में EMPLOYEE_TASKS मास्टर EMPLOYEES टेबल के चाइल्ड के रूप में है। दो टेबल डिज़ाइन में ACTUAL_EMPLOYEE_TASKS और FORECAST_EMPLOYEE_TASKS क्रमशः ACTUAL_EMPLOYEES और FORECAST_EMPLOYEES टेबल के बच्चे हैं।
कौन सा डिज़ाइन सही है यह इस बात पर निर्भर करता है कि आपको कार्यों के असाइनमेंट के संबंध में नियमों को लागू करने की आवश्यकता है या नहीं। उदाहरण के लिए, आपकी कंपनी का एक नियम हो सकता है जो बताता है कि केवल वास्तविक लोग ही नए कर्मचारियों को रख सकते हैं। इसलिए एक ऐसा मॉडल होना उपयोगी होगा जो केवल ACTUAL_EMPLOYEES को भर्ती कार्यों को सौंपने की अनुमति देता है।
ठीक है, मैंने दो तालिकाओं में दिनांक कॉलम जोड़े हैं। इससे आप अपनी इच्छित रिपोर्ट चला सकेंगे।