DBMS में Normalization
Normalization असल में क्या हल करता है
Normalization database को इस तरह व्यवस्थित करने की प्रक्रिया है कि एक ही जानकारी कई जगह न दोहराई जाए। यह सुनने में अमूर्त लगता है, पर जो तकलीफ़ यह हटाता है वह बहुत वास्तविक है। जब data दोहराता है, तीन बुरी समस्याएँ आती हैं: जगह बर्बाद होती है, update ख़तरनाक हो जाता है, और आपका data धीरे-धीरे बेमेल हो जाता है।
एक बड़ी table सोचिए जहाँ हर student row उनके course का नाम और fee भी रखती है। अगर दो सौ student "Python" लेते हैं, तो "Python" text और उसकी fee table में दो सौ बार बैठती है। अब fee बदलती है। आपको दो सौ row बिल्कुल सही update करनी होंगी। एक भी छूटी, तो database अब एक ही course की दो अलग fee बताता है। Normalization इसे रोकता है, यह पक्का करके कि हर तथ्य ठीक एक जगह रहे।
हम normalization तक चरणों में पहुँचते हैं जिन्हें normal forms कहते हैं: 1NF, 2NF और 3NF। हर चरण एक ख़ास तरह का दोहराव हटाता है। इन्हें क्रम में लगाते हैं, और ज़्यादातर project के लिए 3NF लक्ष्य है।
समस्या: बिना normalize किया table
यहाँ एक अव्यवस्थित table है जो सब कुछ एक साथ रखती है। देखिए कितना दोहराता है।
| student_id | name | courses | course_fee |
|---|---|---|---|
| 1 | Aarav | Python, MySQL | 2000, 1500 |
| 2 | Diya | Python | 2000 |
दो चीज़ें ग़लत हैं। पहली, courses cell एक अकेली value के बजाय एक list ("Python, MySQL") रखती है — यही खोजना और join करना कठिन बना देता है। दूसरी, Python की fee "2000" हर उस student के लिए बार-बार लिखी है जो इसे लेता है। हम इन्हें चरण-दर-चरण ठीक करेंगे।
First Normal Form (1NF)
नियम: हर cell में एक अकेली, atomic value हो। कोई list नहीं, कोई comma वाला समूह नहीं। हम multi-value row को तोड़ते हैं ताकि हर row ठीक एक course रखे।
| student_id | name | course | course_fee |
|---|---|---|---|
| 1 | Aarav | Python | 2000 |
| 1 | Aarav | MySQL | 1500 |
| 2 | Diya | Python | 2000 |
अब हर cell एक अकेली value है — table 1NF में है। "MySQL कौन लेता है" खोजना अब एक सरल query है। पर ध्यान दीजिए Python की fee 2000 अब भी दोहराती है, और "Aarav" नाम भी दोहराता है। 1NF ने list की समस्या ठीक की, दोहराव की नहीं।
Second Normal Form (2NF)
नियम: 1NF में हो, और हर non-key column पूरी primary key पर निर्भर हो। यहाँ स्वाभाविक key जोड़ी (student_id, course) है। पर course_fee सिर्फ़ course पर निर्भर है, student पर नहीं — यह partial dependency है। हम course के तथ्य अलग table में ले जाते हैं।
-- courses table (हर course की fee एक बार)
CREATE TABLE courses (
course VARCHAR(30) PRIMARY KEY,
course_fee DECIMAL(8,2)
);
-- enrollment table (कौन क्या लेता है)
CREATE TABLE enrollment (
student_id INT,
course VARCHAR(30),
PRIMARY KEY (student_id, course),
FOREIGN KEY (course) REFERENCES courses(course)
);अब Python की fee courses में एक ही बार रखी है। इसे वहाँ बदलिए, और हर student तुरंत नई fee देखता है। Partial dependency ख़त्म — table 2NF में है।
Third Normal Form (3NF)
नियम: 2NF में हो, और कोई non-key column किसी दूसरे non-key column पर निर्भर न हो। मान लीजिए हमारी student table में city और pincode भी थे। pincode से city तय होती है, तो city, pincode — एक non-key column — पर निर्भर है, सीधे student id पर नहीं। यह transitive dependency है।
-- pincode -> city अलग table में
CREATE TABLE areas (
pincode CHAR(6) PRIMARY KEY,
city VARCHAR(40)
);
CREATE TABLE students (
student_id INT PRIMARY KEY,
name VARCHAR(50),
pincode CHAR(6),
FOREIGN KEY (pincode) REFERENCES areas(pincode)
);अब हर pincode की city areas में एक बार लिखी है। students table सिर्फ़ pincode रखती है। Transitive dependency हट गई — डिज़ाइन 3NF में है, साफ़ और update के लिए सुरक्षित।
एक table लीजिए जिसमें order_id, product, product_price, customer_name, customer_city हों। इसे 3NF तक ले जाइए: कौन-सा column partial dependency बनाता है, और कौन-सी जोड़ी transitive? कोई SQL लिखने से पहले tables का अंतिम समूह बनाइए।
तीनों forms का त्वरित सार
| Form | एक line में नियम | क्या हटाता है |
|---|---|---|
| 1NF | हर cell में एक value | दोहराते समूह / list |
| 2NF | पूरी-key पर निर्भरता | Partial dependency |
| 3NF | non-key से non-key link नहीं | Transitive dependency |
याद रखने का एक आसान तरीक़ा: 1NF row का आकार ठीक करता है, 2NF key के हिस्से पर निर्भरता ठीक करता है, और 3NF non-key columns के बीच निर्भरता ठीक करता है।
आम गलतियाँ
- सीधे 3NF पर कूदना। Forms एक-दूसरे पर बनते हैं। पहले 1NF और 2NF जाँचिए, वरना कोई छिपी partial dependency छूट जाएगी।
- एक cell में list रखना। एक field में "Python, MySQL" 1NF तोड़ता है और हर query कठिन बनाता है। एक cell, एक value।
- छोटी tables को ज़रूरत से ज़्यादा normalize करना। दो-column lookup को और tables में तोड़ना बिना फ़ायदे के सिर्फ़ join बढ़ाता है। वहीं normalize कीजिए जहाँ दोहराव सच में नुक़सान करे।
- Normalization को performance tuning समझना। Normalization शुद्धता और बिना दोहराव के बारे में है; speed tuning (index, denormalization) एक अलग, बाद की बात है।
सारांश
- Normalization हर तथ्य एक बार रखता है, जिससे जगह की बर्बादी और update गलतियाँ रुकती हैं।
- 1NF: हर cell में एक atomic value।
- 2NF: 1NF में, और हर column पूरी key पर निर्भर (कोई partial dependency नहीं)।
- 3NF: 2NF में, और कोई non-key column दूसरे non-key column पर निर्भर नहीं (कोई transitive dependency नहीं)।
- ज़्यादातर application के लिए 3NF सुरक्षित default है।
आगे, हल किए उदाहरण देखिए 1NF, 2NF और 3NF उदाहरणों के साथ में, या इन tables की रक्षा करने वाले नियम सीखिए constraints in MySQL में।
