विसंगतियों को खत्म करने के लिए अपने स्कीमा को 1NF से 3NF तक व्यवस्थित करें, और जानें कि पूरी सजगता के साथ कब डीनॉर्मलाइज़ करना है।
इस पाठ को Kodokon में खोलेंएक खराब स्कीमा आपको वर्षों तक भारी पड़ता है। नॉर्मलाइज़ेशन का लक्ष्य एक ही बात है: कि हर तथ्य केवल एक बार संग्रहीत हो, ताकि तीन विसंगतियाँ खत्म हों: अपडेट (एक ईमेल को दस जगहों पर बदलना), इंसर्शन (किसी ऑर्डर के बिना कोई उत्पाद न जोड़ पाना), और डिलीशन (आखिरी ऑर्डर हटाने से ग्राहक मिट जाता है)। इस जानबूझकर बिगाड़े गए स्कीमा को देखें।
CREATE TABLE bad_orders (
id INTEGER PRIMARY KEY,
customer_name TEXT,
customer_email TEXT,
product_names TEXT,
total REAL
);
INSERT INTO bad_orders
(customer_name, customer_email,
product_names, total)
VALUES
('Alice', 'alice@mail.com',
'keyboard,mouse', 74.0),
('Alice', 'alice@mail.co',
'monitor', 199.0);पहले तीन नॉर्मल फ़ॉर्म, व्यवहार में। 1NF: परमाणविक वैल्यू - product_names = 'keyboard,mouse' इसका उल्लंघन करता है, जिससे उत्पादों पर कोई भी WHERE या JOIN अव्यावहारिक हो जाता है। 2NF (संयुक्त कुंजी): हर कॉलम पूरी कुंजी पर निर्भर करता है - (order, product) से पहचानी जाने वाली किसी ऑर्डर लाइन में किसी उत्पाद की कैटलॉग कीमत संग्रहीत करना इसका उल्लंघन करता है, क्योंकि कीमत केवल उत्पाद पर निर्भर करती है। 3NF: कोई गैर-कुंजी कॉलम किसी अन्य गैर-कुंजी कॉलम पर निर्भर नहीं करता - customer_email, जो customer_name पर निर्भर करता है, इसका उल्लंघन करता है; इसी कारण alice@mail.co डुप्लिकेट। यह रहा ठीक किया गया स्कीमा।
CREATE TABLE customers (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
email TEXT NOT NULL UNIQUE
);
CREATE TABLE products (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
price REAL NOT NULL
);
CREATE TABLE purchases (
id INTEGER PRIMARY KEY,
customer_id INTEGER NOT NULL
REFERENCES customers(id)
);
CREATE TABLE purchase_items (
purchase_id INTEGER NOT NULL
REFERENCES purchases(id),
product_id INTEGER NOT NULL
REFERENCES products(id),
quantity INTEGER NOT NULL,
PRIMARY KEY (purchase_id, product_id)
);PRAGMA foreign_keys = ON;
INSERT INTO customers (name, email)
VALUES ('Alice', 'alice@mail.com');
INSERT INTO products (name, price)
VALUES ('keyboard', 49.0), ('mouse', 25.0);
INSERT INTO purchases (customer_id) VALUES (1);
INSERT INTO purchase_items
(purchase_id, product_id, quantity)
VALUES (1, 1, 1), (1, 2, 1);
SELECT c.name, p.name AS product,
i.quantity, p.price
FROM purchase_items AS i
JOIN purchases AS pu ON pu.id = i.purchase_id
JOIN customers AS c ON c.id = pu.customer_id
JOIN products AS p ON p.id = i.product_id;तो, आपको कब डीनॉर्मलाइज़ करना चाहिए? जब रीड्स मापी गई अड़चन बन जाएँ: किसी अहम स्क्रीन पर पाँच-टेबल जॉइन, हर रेंडर पर दोबारा गणना किया जाने वाला एक एग्रीगेट। ईमानदार पैटर्न: एक कैश कॉलम (purchases.total जो ऑर्डर के समय जमा दिया गया - और यह जायज़ है: चुकाई गई कीमत एक ऐतिहासिक तथ्य है, जो कैटलॉग कीमत से अलग है), किसी ट्रिगर द्वारा बनाए रखा गया एक काउंटर, या बैच में दोबारा बनाई गई एक रिपोर्टिंग टेबल। इसकी कीमत: हर प्रति भटक सकती है, और अब संगति की गारंटी इंजन नहीं, बल्कि आपका कोड देता है।