अवधारणाएं
आपने कुछ बुनियादी अवधारणाओं को गलत समझा है, और कठिनाइयाँ उसी का परिणाम हैं। हमें पहले अवधारणाओं को संबोधित करना होगा, न कि समस्या जैसा कि आप इसे समझते हैं, और परिणामस्वरूप, आपकी समस्या गायब हो जाएगी।
<ब्लॉकक्वॉट>स्वतः वृद्धि हुई आईडी, जो निश्चित रूप से प्राथमिक कुंजी हैं।
नहीं, वे नहीं हैं। यह एक आम गलत धारणा है। और समस्याओं के आने की गारंटी है।
एक ID
फ़ील्ड अंग्रेजी या तकनीकी या संबंधपरक इंद्रियों में प्राथमिक कुंजी नहीं हो सकती है।
-
ज़रूर, SQL में, आप कोई भी . घोषित कर सकते हैं फ़ील्ड एक
PRIMARY KEY
होना चाहिए , लेकिन यह जादुई रूप से इसे अंग्रेजी, तकनीकी, या संबंधपरक इंद्रियों में प्राथमिक कुंजी में परिवर्तित नहीं करता है। आप एक चिहुआहुआ को "रॉटवीलर" नाम दे सकते हैं, लेकिन वह इसे रोटवीलर में नहीं बदलता है, यह चिहुआहुआ बना रहता है। किसी भी भाषा की तरह, SQL केवल आपके द्वारा दिए गए आदेशों को निष्पादित करता है, यहPRIMARY KEY
को नहीं समझता है। कुछ संबंधपरक मतलब के लिए, यह सिर्फ कॉलम (या फ़ील्ड) पर एक अद्वितीय अनुक्रमणिका को मारता है। -
समस्या यह है, क्योंकि आपने घोषित . किया है
ID
एकPRIMARY KEY
होने के लिए , आप सोचते हैं इसे प्राथमिक कुंजी के रूप में, और आप उम्मीद . कर सकते हैं कि इसमें प्राथमिक कुंजी के कुछ गुण हैं। आईडी की विशिष्टता को छोड़कर मान , यह कोई लाभ नहीं देता है। इसमें प्राथमिक कुंजी, या उस मामले के लिए किसी भी प्रकार की रिलेशनल कुंजी का कोई गुण नहीं है। यह अंग्रेजी, तकनीकी, या संबंधपरक इंद्रियों में एक कुंजी नहीं है। एक गैर-कुंजी को एक कुंजी घोषित करके, आप केवल अपने आप को भ्रमित करेंगे, और आपको पता चलेगा कि कुछ बहुत ही गलत है, जब उपयोगकर्ता तालिका में डुप्लिकेट के बारे में शिकायत करता है।
संबंधपरक तालिकाओं में पंक्ति होनी चाहिए विशिष्टता
एक PRIMARY KEY
एक ID
. पर फ़ील्ड पंक्ति प्रदान नहीं करता है विशिष्टता इसलिए यह पंक्तियों वाली एक रिलेशनल टेबल नहीं है, और यदि ऐसा नहीं है, तो यह एक फाइल है जिसमें रिकॉर्ड हैं। इसमें कोई भी अखंडता, या शक्ति नहीं है (इस स्तर पर आपको केवल शक्ति में शामिल होने के बारे में पता होगा), या गति, जो एक रिलेशनल डेटाबेस में एक तालिका है।
यह कोड निष्पादित करें (एमएस एसक्यूएल 2008) और इसे स्वयं साबित करें। कृपया इसे केवल पढ़ें और समझें, और फिर इस उत्तर के बाकी हिस्सों को पढ़ने के लिए आगे बढ़ें, आगे पढ़ने से पहले इस कोड को निष्पादित किया जाना चाहिए . इसका उपचारात्मक महत्व है।
CREATE TABLE dumb_file (
id INT NOT NULL IDENTITY PRIMARY KEY,
name_first CHAR(30) NOT NULL,
name_last CHAR(30) NOT NULL
)
INSERT dumb_file VALUES ( "Mickey", "Mouse" ) -- succeeds
INSERT dumb_file VALUES ( "Mickey", "Mouse" ) -- succeeds, but not intended
INSERT dumb_file VALUES ( "Mickey", "Mouse" ) -- succeeds, but not intended
SELECT * FROM dumb_file
ध्यान दें कि आपके पास डुप्लिकेट पंक्तियाँ हैं . संबंधपरक तालिकाओं में अद्वितीय पंक्तियों . होना आवश्यक है . इस बात का और सबूत कि आपके पास कोई रिलेशनल टेबल नहीं है, या इनमें से कोई गुण नहीं है।
ध्यान दें कि आपकी रिपोर्ट में, केवल एक चीज जो अद्वितीय है वह है ID
फ़ील्ड, जिसकी कोई उपयोगकर्ता परवाह नहीं करता है, कोई उपयोगकर्ता नहीं देखता है, क्योंकि यह डेटा नहीं है, यह कुछ अतिरिक्त बकवास है कि कुछ बहुत ही बेवकूफ "शिक्षक" ने आपको हर फाइल में डालने के लिए कहा था। आपके पास रिकॉर्ड है विशिष्टता लेकिन नहीं पंक्ति विशिष्टता
डेटा के संदर्भ में (असली डेटा घटा बाहरी जोड़), डेटा name_last
और name_first
ID
. के बिना मौजूद हो सकता है खेत। किसी व्यक्ति के माथे पर बिना आईडी की मुहर लगे उसका पहला नाम और उपनाम होता है।
दूसरी चीज़ जिसका आप उपयोग कर रहे हैं जो आपको भ्रमित करती है वह है AUTOINCREMENT.
यदि आप एक रिकॉर्ड फाइलिंग सिस्टम को बिना किसी रिलेशनल क्षमता के कार्यान्वित कर रहे हैं, तो निश्चित रूप से, यह सहायक है, आपको रिकॉर्ड डालने के दौरान वृद्धि को कोड करने की आवश्यकता नहीं है। लेकिन अगर आप एक रिलेशनल डेटाबेस को लागू कर रहे हैं, तो इसका कोई उद्देश्य नहीं है, क्योंकि आप इसका कभी भी उपयोग नहीं करेंगे। SQL में ऐसी कई विशेषताएं हैं जिनका अधिकांश लोग कभी भी उपयोग नहीं करते हैं।
सुधारात्मक कार्रवाई
तो आप एक रिलेशनल टेबल के कुछ गुणों और लाभों को प्राप्त करने के लिए, उस डंब_फाइल को कैसे अपग्रेड, एलिवेट करते हैं, जो एक रिलेशनल टेबल पर डुप्लिकेट पंक्तियों से भरा है? इसके तीन चरण हैं।
-
आपको चाबियों को समझने की जरूरत है
- और जब से हम 1970 के ISAM फाइलों से रिलेशनल मॉडल की ओर बढ़े हैं , आपको रिलेशनल कीज़ को समझने की आवश्यकता है . यही है, यदि आप एक रिलेशनल डेटाबेस के लाभ (अखंडता, शक्ति, गति) प्राप्त करना चाहते हैं।
डॉ ई एफ कूड, अपने RM . में , घोषित किया कि:
<ब्लॉकक्वॉट>एक कुंजी डेटा से बनती है
और
<ब्लॉकक्वॉट>तालिका में पंक्तियाँ अद्वितीय होनी चाहिए
आपकी "कुंजी" डेटा से नहीं बनी है। यह कुछ अतिरिक्त, गैर-डेटा परजीवी है, जो आपके "शिक्षक" की बीमारी से संक्रमित होने के कारण होता है। इसे इस रूप में पहचानें, और अपने आप को पूर्ण मानसिक क्षमता की अनुमति दें जो भगवान ने आपको दी है (ध्यान दें कि मैं आपको अलग या खंडित या अमूर्त शब्दों में सोचने के लिए नहीं कहता, डेटाबेस में सभी तत्वों को एक दूसरे के साथ एकीकृत किया जाना चाहिए)। डेटा से एक वास्तविक कुंजी बनाएं और केवल डेटा से। इस मामले में, केवल एक संभावित कुंजी है:
(name_last, name_first).
-
इस कोड को आजमाएं , घोषणा करें डेटा पर एक अद्वितीय बाधा:
CREATE TABLE dumb_table ( id INT NOT NULL IDENTITY PRIMARY KEY, name_first CHAR(30) NOT NULL, name_last CHAR(30) NOT NULL CONSTRAINT UK UNIQUE ( name_last, name_first ) ) INSERT dumb_table VALUES ( "Mickey", "Mouse" ) -- succeeds INSERT dumb_table VALUES ( "Mickey", "Mouse" ) -- fails, as intended INSERT dumb_table VALUES ( "Minnie", "Mouse" ) -- succeeds SELECT * FROM dumb_table
अब हमारे पास पंक्ति विशिष्टता . है . यही क्रम ज्यादातर लोगों के साथ होता है:वे एक फाइल बनाते हैं जो नकल की अनुमति देता है; उन्हें पता नहीं है कि ड्रॉप-डाउन में धोखा क्यों दिखाई दे रहे हैं; उपयोगकर्ता चिल्लाता है; वे फ़ाइल को ट्वीक करते हैं और नकल को रोकने के लिए एक इंडेक्स जोड़ते हैं; वे अगले बग फिक्स पर जाते हैं। (वे ऐसा सही ढंग से कर सकते हैं या नहीं, यह एक अलग कहानी है।)
-
दूसरा स्तर। उन लोगों को सोचने के लिए जो तय से परे सोचते हैं-इसकी। चूँकि अब हमारे पास पंक्ति विशिष्टता है, स्वर्ग के नाम में
ID
. का उद्देश्य क्या है? क्षेत्र, हमारे पास भी क्यों है ??? ओह, क्योंकि चिहुआहुआ का नाम रोट्टी है और हम इसे छूने से डरते हैं।यह घोषणा कि यह एक
PRIMARY KEY
है झूठा है, लेकिन यह बना रहता है, जिससे भ्रम और झूठी उम्मीदें पैदा होती हैं। केवल वास्तविक कुंजी है,(name_last, name_fist),
. है और यह एक वैकल्पिक कुंजी . है इस बिंदु पर।इसलिए
ID
क्षेत्र पूरी तरह से ज़रूरत से ज़्यादा है; और ऐसा ही वह सूचकांक है जो इसका समर्थन करता है; और ऐसा ही बेवकूफी भरा हैAUTOINCREMENT
; और इसी तरह झूठी घोषणा है कि यह एकPRIMARY KEY
है; और इससे आपकी कोई भी अपेक्षाएं झूठी हो सकती हैं।इसलिए फालतू
ID
को हटा दें खेत। इस कोड को आजमाएं :CREATE TABLE honest_table ( name_first CHAR(30) NOT NULL, name_last CHAR(30) NOT NULL CONSTRAINT PK PRIMARY KEY ( name_last, name_first ) ) INSERT honest_table VALUES ( "Mickey", "Mouse" ) -- succeeds INSERT honest_table VALUES ( "Mickey", "Mouse" ) -- fails, as intended INSERT honest_table VALUES ( "Minnie", "Mouse" ) -- succeeds SELECT * FROM honest_table
बाहरी क्षेत्रों और सूचकांकों के बिना, ठीक काम करता है, इरादा के अनुसार काम करता है।
कृपया इसे याद रखें, और इसे हर बार सही तरीके से करें।
झूठे शिक्षक
इन अंतिम समयों में, जैसा कि सलाह दी गई है, हमारे पास उनमें से कई होंगे। ध्यान दें, "शिक्षक" जो ID
का प्रचार करते हैं कॉलम, इस पोस्ट में विस्तृत साक्ष्य के आधार पर, केवल रिलेशनल मॉडल . को नहीं समझते हैं या संबंधपरक डेटाबेस। खासकर वे जो इसके बारे में किताबें लिखते हैं।
जैसा कि सबूत है, वे 1970 से पहले की ISAM तकनीक में फंस गए हैं। वे बस इतना ही समझते हैं, और यही सब वे सिखा सकते हैं। वे एक्सेस, रिकवरी, बैकअप आदि की आसानी के लिए एक SQL डेटाबेस कंटेनर का उपयोग करते हैं, लेकिन सामग्री शुद्ध रिकॉर्ड फाइलिंग सिस्टम है जिसमें कोई संबंधपरक अखंडता, शक्ति या गति नहीं है। AFAIC, यह एक गंभीर धोखाधड़ी है।
ID
. के अलावा क्षेत्र, निश्चित रूप से, ऐसे कई आइटम हैं जो प्रमुख संबंधपरक-या-अवधारणाएं हैं, जिन्हें एक साथ लिया जाता है, जिससे मुझे इस तरह के गंभीर निष्कर्ष मिलते हैं। वे अन्य आइटम इस पोस्ट के दायरे से बाहर हैं।
इडियट्स की एक विशेष जोड़ी वर्तमान में फर्स्ट नॉर्मल फॉर्म पर हमला कर रही है। वे शरण में हैं।
जवाब
अब आपके शेष प्रश्न के लिए।
<ब्लॉकक्वॉट>क्या कोई ऐसा तरीका है जिससे मैं ऑटो इंक्रीमेंट सुविधाओं को खोए बिना एक रिलेशनल टेबल बना सकता हूं?
यह एक आत्म-विरोधाभासी वाक्य है। मुझे विश्वास है कि आप मेरी व्याख्या से समझेंगे, संबंधपरक तालिकाओं की कोई आवश्यकता नहीं है AUTOINCREMENT
. के लिए "विशेषताएँ"; अगर फ़ाइल में AUTOINCREMENT
है , यह एक संबंधपरक तालिका नहीं है।
AUTOINCREMENT
केवल एक ही चीज़ के लिए अच्छा है:यदि, और केवल यदि, आप SQL डेटाबेस कंटेनर में एक एक्सेल स्प्रेडशीट बनाना चाहते हैं, तो A,
नामक फ़ील्ड से भरा हुआ है। B,
और C,
शीर्ष पर, और बाईं ओर नीचे की संख्या रिकॉर्ड करें। डेटाबेस के संदर्भ में, यह परिणाम . है एक चयन का, डेटा का एक चपटा दृश्य, जो नहीं है स्रोत डेटा का, जो व्यवस्थित (सामान्यीकृत) है।
एक और संभावित (लेकिन पसंदीदा नहीं) समाधान हो सकता है कि पहली तालिका में एक और प्राथमिक कुंजी हो, जो कि उपयोगकर्ता का उपयोगकर्ता नाम है, न कि ऑटो इंक्रीमेंट स्टेटमेंट के साथ। क्या यह अपरिहार्य है?
तकनीकी कार्य में, हम वरीयताओं की परवाह नहीं करते हैं, क्योंकि यह व्यक्तिपरक है, और यह हर समय बदलता रहता है। हम तकनीकी शुद्धता की परवाह करते हैं, क्योंकि यह उद्देश्य है, और यह नहीं बदलता है।
हाँ, यह अपरिहार्य है। क्योंकि यह तो बस समय की बात है; बग की संख्या; "नहीं कर सकता" की संख्या; जब तक आप तथ्यों का सामना नहीं कर लेते, अपनी झूठी घोषणाओं पर काबू पा लेते हैं और महसूस करते हैं कि:
-
यह सुनिश्चित करने का एकमात्र तरीका है कि उपयोगकर्ता पंक्तियाँ अद्वितीय हैं, कि user_name अद्वितीय हैं, एक
UNIQUE
घोषित करना है उस पर प्रतिबंध -
और
user_id
. से छुटकारा पाएं याID
उपयोगकर्ता फ़ाइल में -
जो
user_name
. को बढ़ावा देता है करने के लिएPRIMARY KEY
हां, क्योंकि संयोग से नहीं, बल्कि तीसरी तालिका के साथ आपकी पूरी समस्या समाप्त हो जाती है।
वह तीसरी तालिका एक सहयोगी तालिका . है . केवल आवश्यक कुंजी (प्राथमिक कुंजी) दो मूल प्राथमिक कुंजी का एक संयोजन है। यह पंक्तियों . की विशिष्टता सुनिश्चित करता है , जो उनकी चाबियों से पहचाने जाते हैं, न कि उनके IDs.
. से
मैं आपको इसके बारे में चेतावनी दे रहा हूं क्योंकि वही "शिक्षक" जिन्होंने आपको ID
लागू करने की त्रुटि सिखाई थी फ़ील्ड, ID
को लागू करने की त्रुटि सिखाएं साहचर्य तालिका में फ़ील्ड, जहाँ, एक सामान्य तालिका की तरह, यह अतिश्योक्तिपूर्ण है, कोई उद्देश्य नहीं है, डुप्लिकेट का परिचय देता है, और भ्रम का कारण बनता है। और यह दोगुना अनावश्यक है क्योंकि प्रदान करने वाली दो चाबियां पहले से ही हैं, हमें चेहरे पर देख रही हैं।
चूंकि वे RM . को नहीं समझते हैं , या संबंधपरक शब्द, वे साहचर्य तालिकाएँ "लिंक" या "मानचित्र" तालिकाएँ कहते हैं। अगर उनके पास ID
है फ़ील्ड, वे वास्तव में, फ़ाइलें हैं।
लुकअप टेबल
ID
फ़ील्ड विशेष रूप से हैं बेवकूफ करने योग्य बातें लुकअप या संदर्भ तालिकाओं के लिए। उनमें से अधिकांश के पास पहचानने योग्य कोड हैं, उनमें कोड की सूची की गणना करने की कोई आवश्यकता नहीं है, क्योंकि कोड अद्वितीय (होना चाहिए) हैं।
इसके अलावा, चाइल्ड टेबल में कोड को FK के रूप में रखना एक अच्छी बात है:कोड बहुत अधिक अर्थपूर्ण है, और यह अक्सर एक अनावश्यक जुड़ाव को बचाता है:
SELECT ...
FROM child_table -- not the lookup table
WHERE gender_code = "M" -- FK in the child, PK in the lookup
इसके बजाय:
SELECT ...
FROM child_table
WHERE gender_id = 6 -- meaningless to the maintainer
या इससे भी बदतर:
SELECT ...
FROM child_table C -- that you are trying to determine
JOIN lookup_table L
ON C.gender_id = L.gender_id
WHERE L.gender_code = "M" -- meaningful, known
ध्यान दें कि यह ऐसी चीज है जिससे कोई नहीं बच सकता है:आपको लुकअप कोड और . पर विशिष्टता की आवश्यकता है विवरण पर विशिष्टता। प्रत्येक . में डुप्लिकेट को रोकने का यही एकमात्र तरीका है दो स्तंभों में से:
CREATE TABLE gender (
gender_code CHAR(2) NOT NULL,
name CHAR(30) NOT NULL
CONSTRAINT PK
PRIMARY KEY ( gender_code )
CONSTRAINT AK
UNIQUE ( name )
)
पूर्ण उदाहरण
आपके प्रश्न के विवरण से, मुझे संदेह है कि आपके पास SQL सिंटैक्स और FK परिभाषा मुद्दे हैं, इसलिए मैं आपको एक उदाहरण के रूप में आवश्यक संपूर्ण समाधान दूंगा (चूंकि आपने फ़ाइल परिभाषा नहीं दी है):
CREATE TABLE user ( -- Typical Identifying Table
user_name CHAR(16) NOT NULL, -- Short PK
name_first CHAR(30) NOT NULL, -- Alt Key.1
name_last CHAR(30) NOT NULL, -- Alt Key.2
birth_date DATE NOT NULL -- Alt Key.3
CONSTRAINT PK -- unique user_name
PRIMARY KEY ( user_name )
CONSTRAINT AK -- unique person identification
PRIMARY KEY ( name_last, name_first, birth_date )
)
CREATE TABLE sport ( -- Typical Lookup Table
sport_code CHAR(4) NOT NULL, -- PK Short code
name CHAR(30) NOT NULL -- AK
CONSTRAINT PK
PRIMARY KEY ( sport_code )
CONSTRAINT AK
PRIMARY KEY ( name )
)
CREATE TABLE user_sport ( -- Typical Associative Table
user_name CHAR(16) NOT NULL, -- PK.1, FK
sport_code CHAR(4) NOT NULL, -- PK.2, FK
start_date DATE NOT NULL
CONSTRAINT PK
PRIMARY KEY ( user_name, sport_code )
CONSTRAINT user_plays_sport_fk
FOREIGN KEY ( user_name )
REFERENCES user ( user_name )
CONSTRAINT sport_occupies_user_fk
FOREIGN KEY ( sport_code )
REFERENCES sport ( sport_code )
)
वहां, PRIMARY KEY
घोषणा ईमानदार है, यह एक प्राथमिक कुंजी है; नहीं ID;
नहीं AUTOINCREMENT;
कोई अतिरिक्त सूचकांक नहीं; कोई डुप्लिकेट नहीं पंक्तियाँ; कोई गलत उम्मीद नहीं; कोई परिणामी समस्या नहीं।
डेटा मॉडल
यहाँ परिभाषाओं के साथ जाने के लिए डेटा मॉडल है।
-
यदि आप नोटेशन के अभ्यस्त नहीं हैं, तो कृपया सलाह दें कि हर छोटी टिक, पायदान और निशान, ठोस बनाम धराशायी रेखाएं, वर्ग बनाम गोल कोनों का अर्थ कुछ विशिष्ट है। IDEF1X नोटेशन का संदर्भ लें। .
-
एक तस्वीर एक हजार शब्दों के बराबर होती है; इस मामले में एक मानक-शिकायत तस्वीर इससे अधिक मूल्य की है; एक बुरा कागज उस कागज के लायक नहीं है जिस पर इसे खींचा गया है।
-
कृपया क्रिया वाक्यांशों को ध्यान से देखें, उनमें विधेय का एक समूह होता है। शेष विधेय को सीधे मॉडल से निर्धारित किया जा सकता है। अगर यह स्पष्ट नहीं है, तो कृपया पूछें।