SQL Academy · पाठ

ऐरे बनाम सामान्यीकृत तालिकाएँ

जानें कि ऐरे कब सही विकल्प हैं।

पाठ 4, कुल 4 में से13 चरण

ऐरे बनाम सामान्यीकृत तालिकाएँ, CoddyKit पर SQL Academy का एक निःशुल्क पाठ है। यह 4 में से 4वाँ पाठ है। आप नीचे पूरा पाठ निःशुल्क पढ़ सकते हैं—फिर अंतर्निहित कोड संपादक और 24/7 एआई ट्यूटर के साथ ब्राउज़र में इसका व्यावहारिक अभ्यास कर सकते हैं। यह SQL Academy सीखने के मार्ग का हिस्सा है और आपकी प्रगति वेब तथा CoddyKit ऐप पर सिंक होती रहती है। SQL Academy पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

कई मान संग्रहीत करने के दो तरीके

जब किसी एक पंक्ति में कई संबंधित मान रखने हों, तो PostgreSQL आपको दो मुख्य तरीके देता है: उन्हीं पंक्ति में उन्हें एक सरणी स्तंभ के रूप में संग्रहीत करें, या एक अलग उप-तालिका बनाएँ, जिसमें प्रत्येक मान की अपनी पंक्ति हो।

कुशल और रखरखाव योग्य डेटाबेस अभिकल्पित करने के लिए यह समझना एक महत्वपूर्ण कौशल है कि किस स्थिति में कौन-सा तरीका अपनाना चाहिए।

सामान्यीकृत तरीका

पूरी तरह सामान्यीकृत schema में डेटा का प्रत्येक भाग अपनी अलग पंक्ति में रहता है। यदि किसी उपयोगकर्ता के कई फ़ोन नंबर हो सकते हैं, तो आप user_phones तालिका बनाएँगे, जिसमें users से जुड़ी विदेशी कुंजी होगी।

यह पारंपरिक संबंधपरक मॉडल है और अधिकांश स्थितियों में डिफ़ॉल्ट विकल्प होता है।

CREATE TABLE users (
  id   SERIAL PRIMARY KEY,
  name TEXT NOT NULL
);

CREATE TABLE user_phones (
  id      SERIAL PRIMARY KEY,
  user_id INT REFERENCES users(id),
  phone   TEXT NOT NULL
);

INSERT INTO users (name) VALUES ('Alice'), ('Bob');

INSERT INTO user_phones (user_id, phone) VALUES
  (1, '+1-555-0101'),
  (1, '+1-555-0102'),
  (2, '+1-555-0200');

सरणी-आधारित तरीका

PostgreSQL का TEXT[] (या किसी भी अन्य प्रकार के बाद लगाया गया []) आपको एक ही स्तंभ के भीतर सीधे कई मान संग्रहीत करने देता है। किसी अतिरिक्त तालिका की आवश्यकता नहीं होती।

फ़ोन नंबर का यही डेटा प्रत्येक उपयोगकर्ता के लिए एक संक्षिप्त पंक्ति में संग्रहीत किया जा सकता है।

CREATE TABLE users_with_phones (
  id     SERIAL PRIMARY KEY,
  name   TEXT    NOT NULL,
  phones TEXT[]
);

INSERT INTO users_with_phones (name, phones) VALUES
  ('Alice', ARRAY['+1-555-0101', '+1-555-0102']),
  ('Bob',   ARRAY['+1-555-0200']);

सरणियों में क्वेरी करना आसान है

सरणी स्तंभ के भीतर खोज करना ANY ऑपरेटर या @> (समाहित करने वाला) ऑपरेटर के साथ सरल है। एक साधारण WHERE खंड की सहायता से आप उन सभी उपयोगकर्ताओं को खोज सकते हैं जिनके पास कोई विशिष्ट फ़ोन नंबर है।

-- Find users who have a specific phone number
SELECT name
FROM users_with_phones
WHERE '+1-555-0101' = ANY(phones);

-- Or using the array-contains operator
SELECT name
FROM users_with_phones
WHERE phones @> ARRAY['+1-555-0101'];

सरणियाँ कब बेहतर होती हैं: सरल खोज

सरणियाँ तब अच्छा विकल्प होती हैं जब:

  • मानों की सूची को एक इकाई के रूप में एक साथ पढ़ा जाता हो (टैग, लेबल, श्रेणियाँ)
  • आपको कभी भी अलग-अलग तत्वों पर जोड़ न करना पड़े
  • सूची की स्वाभाविक अधिकतम सीमा हो और उसके कुछ हिस्सों को कम ही बदला जाता हो

ब्लॉग पोस्ट पर टैग संग्रहीत करना इसका एक पारंपरिक उदाहरण है। आप हमेशा सभी टैग एक साथ प्राप्त करते हैं और किसी जटिल जोड़ में एकल टैग के आधार पर पोस्ट की क्वेरी बहुत कम करते हैं।

CREATE TABLE posts (
  id         SERIAL PRIMARY KEY,
  title      TEXT    NOT NULL,
  tags       TEXT[]
);

INSERT INTO posts (title, tags) VALUES
  ('Intro to SQL',      ARRAY['sql', 'beginner', 'database']),
  ('Advanced Indexes',  ARRAY['sql', 'performance', 'indexes']),
  ('NoSQL Overview',    ARRAY['nosql', 'beginner']);

-- Get all posts tagged 'beginner'
SELECT title FROM posts
WHERE 'beginner' = ANY(tags);

सामान्यीकृत तालिकाएँ कब बेहतर होती हैं: संबंध

सामान्यीकृत तालिकाएँ तब बेहतर विकल्प होती हैं जब:

  • अलग-अलग मानों के अपने गुण हों (जैसे, किसी फ़ोन नंबर का प्रकार घर या कार्यालय हो सकता है)
  • आपको अलग-अलग मानों पर जोड़ करना हो
  • मान स्वतंत्र रूप से और बार-बार बदलते हों
  • आपको विदेशी कुंजियों के माध्यम से संदर्भात्मक अखंडता चाहिए हो
-- Phone numbers need a 'type' attribute — array can't do this cleanly
CREATE TABLE user_phones (
  id      SERIAL PRIMARY KEY,
  user_id INT REFERENCES users(id),
  phone   TEXT NOT NULL,
  type    TEXT CHECK (type IN ('home', 'work', 'mobile'))
);

INSERT INTO user_phones (user_id, phone, type) VALUES
  (1, '+1-555-0101', 'home'),
  (1, '+1-555-0102', 'work');

अनुक्रमणिका में अंतर

सामान्यीकृत तालिका के साथ आप विदेशी कुंजी या मान वाले स्तंभ पर एक मानक बी-ट्री अनुक्रमणिका जोड़ सकते हैं। सरणियों के साथ, सरणी के भीतर तेज़ खोज सक्षम करने के लिए आपको GIN अनुक्रमणिका (सामान्यीकृत उलटी अनुक्रमणिका) की आवश्यकता होती है।

GIN अनुक्रमणिकाएँ अच्छी तरह काम करती हैं, लेकिन बी-ट्री अनुक्रमणिकाओं की तुलना में बड़ी होती हैं और उन्हें अद्यतन करने में अधिक समय लगता है।

-- Index for fast array element lookups
CREATE INDEX idx_posts_tags ON posts USING GIN (tags);

-- Now this query uses the index efficiently
EXPLAIN SELECT title FROM posts
WHERE tags @> ARRAY['sql'];

पंक्तियों में समेकन: सामान्यीकृत तरीका बेहतर

जब आपको अलग-अलग मानों पर गिनती, समूह बनाना या समेकन करना हो, तो सामान्यीकृत तालिकाएँ कहीं अधिक स्वाभाविक होती हैं। सरणियों के भीतर समेकन करने के लिए unnest() की आवश्यकता होती है, जो पहले सरणी को पंक्तियों में फैलाता है — यानी क्वेरी चलने के समय सामान्यीकृत संरचना को फिर से बना देता है।

-- Count posts per tag (array approach — needs unnest)
SELECT tag, COUNT(*) AS post_count
FROM posts, unnest(tags) AS tag
GROUP BY tag
ORDER BY post_count DESC;

-- With a normalized post_tags table this would be simpler:
-- SELECT tag, COUNT(*) FROM post_tags GROUP BY tag;

सरणी तत्वों में बदलाव करना

सरणी के भीतर किसी एक तत्व को अद्यतन या हटाने के लिए असुविधाजनक वाक्य-विन्यास की आवश्यकता होती है — आपको पूरी सरणी बदलनी पड़ती है या array_remove() का उपयोग करना पड़ता है। सामान्यीकृत तालिका में आप बस विशिष्ट पंक्ति पर DELETE या UPDATE लागू कर देते हैं।

-- Remove a single tag from an array column
UPDATE posts
SET tags = array_remove(tags, 'beginner')
WHERE id = 1;

-- Append a new tag
UPDATE posts
SET tags = array_append(tags, 'tutorial')
WHERE id = 1;

SELECT title, tags FROM posts WHERE id = 1;

मान्य मान लागू करना

सामान्यीकृत तालिका में आप विदेशी कुंजी का उपयोग करके यह सुनिश्चित कर सकते हैं कि प्रत्येक मान किसी ज्ञात समूह से ही आए। सरणियाँ किसी दूसरी तालिका का संदर्भ नहीं दे सकतीं — उनमें विदेशी कुंजी का समर्थन नहीं होता।

यदि आपको प्रत्येक तत्व के लिए सुनिश्चित संदर्भात्मक अखंडता चाहिए, तो उप-तालिका ही एकमात्र विकल्प है।

-- Normalized: only valid category IDs allowed (FK enforced)
CREATE TABLE categories (
  id   SERIAL PRIMARY KEY,
  name TEXT UNIQUE NOT NULL
);

CREATE TABLE post_categories (
  post_id     INT REFERENCES posts(id),
  category_id INT REFERENCES categories(id),
  PRIMARY KEY (post_id, category_id)
);

-- Array: no constraint possible — any text value is accepted
-- UPDATE posts SET tags = ARRAY['totally_invalid_tag'] WHERE id = 1;

व्यावहारिक निर्णय मार्गदर्शिका

सरणी का उपयोग तब करें जब डेटा एक सरल सपाट सूची हो, हमेशा एक इकाई के रूप में पढ़ा जाता हो, प्रत्येक तत्व के लिए कोई अतिरिक्त गुण न हो और संदर्भात्मक अखंडता आवश्यक न हो (जैसे, टैग, लेबल, खोज कीवर्ड)।

सामान्यीकृत उप-तालिका का उपयोग तब करें जब प्रत्येक तत्व के अपने गुण हों, आप अलग-अलग मानों पर जोड़ या समेकन करते हों, आपको विदेशी कुंजियों की आवश्यकता हो, या अलग-अलग तत्वों को बार-बार अद्यतन या हटाया जाता हो।

-- Summary example: tags as array (good fit)
SELECT title, tags
FROM posts
WHERE tags @> ARRAY['sql']
ORDER BY title;

-- Unnest when you need row-level processing
SELECT title, unnest(tags) AS tag
FROM posts
ORDER BY title, tag;

त्वरित जाँच

किस स्थिति में डेटा को सामान्यीकृत उप-तालिका के बजाय PostgreSQL सरणी के रूप में संग्रहीत करना सबसे उपयुक्त होगा?

पाठ का पुनरावलोकन

इस पाठ में आपने PostgreSQL में सरणियों और सामान्यीकृत तालिकाओं के बीच मुख्य समझौतों को सीखा।

  • सरणियाँ टैग जैसी सपाट, एक साथ पढ़ी जाने वाली सूचियों के लिए संक्षिप्त और सुविधाजनक होती हैं — लेकिन उनमें विदेशी कुंजियाँ नहीं होतीं, प्रति-तत्व अद्यतन असुविधाजनक होते हैं और तेज़ खोज के लिए GIN अनुक्रमणिकाओं की आवश्यकता होती है।
  • सामान्यीकृत तालिकाएँ प्रति-तत्व गुणों, विदेशी कुंजी की अखंडता, कुशल समेकन और सरल पंक्ति-स्तरीय अद्यतन का समर्थन करती हैं — इसकी कीमत एक अतिरिक्त जोड़ है।
  • सही विकल्प इस बात पर निर्भर करता है कि आप डेटा की क्वेरी, अद्यतन और संबंध कैसे बनाते हैं — केवल इस पर नहीं कि आप उसे कैसे संग्रहीत करते हैं।
शुरुआत निःशुल्क

एआई शिक्षक के साथ SQL सीखें — निःशुल्क

अपने ब्राउज़र में वास्तविक कोड लिखें और चलाएँ, चौबीसों घंटे एआई शिक्षक से तुरंत सहायता पाएँ, और वेब या ऐप पर वहीं से शुरू करें जहाँ आपने छोड़ा था।

पाठ्यक्रम
46
पाठ
183

अक्सर पूछे जाने वाले प्रश्न

क्या “ऐरे बनाम सामान्यीकृत तालिकाएँ” पाठ निःशुल्क है?

हाँ—“ऐरे बनाम सामान्यीकृत तालिकाएँ” का पूरा पाठ यहाँ वेब पर निःशुल्क पढ़ा जा सकता है। इंटरैक्टिव अभ्यास (अंतर्निहित कोड संपादक और 24/7 एआई ट्यूटर) करने और SQL Academy पाठ्यक्रम का बाकी हिस्सा अनलॉक करने के लिए CoddyKit PRO लें। SQL Academy पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

“ऐरे बनाम सामान्यीकृत तालिकाएँ” में मैं क्या सीखूँगा?

जानें कि ऐरे कब सही विकल्प हैं। आप ब्राउज़र में सीधे चलाए जाने वाले व्यावहारिक कोड के साथ SQL Academy का अभ्यास करते हैं, और पाठ पूरा करते समय 24/7 एआई ट्यूटर आपके प्रश्नों के उत्तर देता है।

क्या SQL Academy शुरू करने के लिए मुझे किसी अनुभव की आवश्यकता है?

पहले के अनुभव की आवश्यकता नहीं है। CoddyKit पर SQL Academy शुरुआती से लेकर उन्नत शिक्षार्थियों तक सभी के लिए व्यवस्थित किया गया है, इसलिए आप यहीं से या शुरुआत से सीखना शुरू कर सकते हैं और अपनी गति से आगे बढ़ सकते हैं। यह 4 में से 4वाँ पाठ है।

“ऐरे बनाम सामान्यीकृत तालिकाएँ” पाठ पूरा करने में कितना समय लगता है?

CoddyKit का अधिकांश पाठ लगभग 5–10 मिनट में पूरा हो जाता है। हर पाठ छोटा और संवादात्मक है, इसलिए आप लगातार प्रगति करते हैं और वेब या ऐप पर वहीं से सीखना जारी रख सकते हैं जहाँ आपने छोड़ा था।

क्या मैं इस SQL Academy पाठ में कोड लिख और चला सकता हूँ?

हाँ। हर SQL Academy पाठ में एक अंतर्निर्मित कोड संपादक शामिल है, जिससे आप सीधे अपने ब्राउज़र में वास्तविक कोड लिख और चला सकते हैं और तुरंत एआई प्रतिक्रिया पा सकते हैं—स्थानीय सेटअप की आवश्यकता नहीं है।

इस पाठ्यक्रम के सभी पाठ

  1. ऐरे कॉलम की मूल बातें
  2. ऐरे के भीतर खोजना
  3. UNNEST और एग्रीगेट करना
  4. ऐरे बनाम सामान्यीकृत तालिकाएँ
← SQL Academy पर वापस जाएँ