क्या तालिका की परिभाषा में स्तंभों का क्रम मायने रखता है?


35

किसी तालिका को परिभाषित करते समय, यह तार्किक समूहों और उद्देश्य से समूहों को स्वयं कॉलम करने के लिए सहायक होता है। तालिका में स्तंभों का तार्किक क्रम डेवलपर को अर्थ बताता है और अच्छी शैली का एक तत्व है।

यह स्पष्ट है।

हालांकि, यह स्पष्ट नहीं है कि क्या किसी तालिका में स्तंभों के तार्किक क्रम का भंडारण की परत पर उनके भौतिक क्रम पर कोई प्रभाव पड़ता है, या यदि इसका कोई अन्य प्रभाव है, जिसकी किसी को परवाह हो सकती है।

शैली पर प्रभाव के अलावा, क्या स्तंभ क्रम कभी मायने रखता है?

इस बारे में स्टैक ओवरफ्लो पर एक सवाल है , लेकिन इसमें एक आधिकारिक जवाब का अभाव है।

जवाबों:


23

क्या किसी तालिका में स्तंभों के तार्किक क्रम का भंडारण स्तर पर उनके भौतिक क्रम पर कोई प्रभाव पड़ता है? हाँ।

यह मायने रखता है या नहीं यह एक अलग मुद्दा है जिसका मैं जवाब नहीं दे सकता (अभी तक)।

एक रिकॉर्ड की शारीरिक रचना पर पॉल रैंडल से अक्सर जुड़े लेख में वर्णित इसी तरह से , आइए DBCC IND के साथ एक सरल दो कॉलम तालिका देखें:

SET STATISTICS IO OFF;
SET STATISTICS TIME OFF;

USE master;
GO

IF DATABASEPROPERTY (N'RowStructure', 'Version') > 0 DROP DATABASE RowStructure;
GO

CREATE DATABASE RowStructure;
GO

USE RowStructure;
GO

CREATE TABLE FixedLengthOrder
(
    c1 INT IDENTITY(1,1) PRIMARY KEY CLUSTERED
    , c2 CHAR(10) DEFAULT REPLICATE('A', 10) NOT NULL
    , c3 CHAR(10) DEFAULT REPLICATE('B', 10) NOT NULL  
);
GO

INSERT FixedLengthOrder DEFAULT VALUES;
GO

DBCC IND ('RowStructure', 'FixedLengthOrder', 1);
GO

DBCC इंडस्ट्रीज़ आउटपुट

उपरोक्त आउटपुट से पता चलता है कि हमें पृष्ठ 89 को देखना है:

DBCC TRACEON (3604);
GO
DBCC PAGE ('RowStructure', 1, 89, 3);
GO

DBCC पृष्ठ से आउटपुट में हम c1 को c2 के 'B' से पहले 'A' अक्षर से भरते हुए देखते हैं:

Memory Dump @0x000000000D25A060

0000000000000000:   10001c00 01000000 41414141 41414141 †........AAAAAAAA
0000000000000010:   41414242 42424242 42424242 030000††††AABBBBBBBBBB...

और सिर्फ इसलिए, RowStructure.mdfएक हेक्स संपादक के साथ बस्ट को खोलने और 'ए' स्ट्रिंग की पुष्टि 'बी' स्ट्रिंग की पुष्टि करता है:

AAAAAAAAAA

अब परीक्षण दोहराएं लेकिन स्ट्रिंग्स के क्रम को उलट दें, c1 में 'B' अक्षर और c2 में 'A' अक्षर रखें:

CREATE TABLE FixedLengthOrder
(
    c1 INT IDENTITY(1,1) PRIMARY KEY CLUSTERED
    , c2 CHAR(10) DEFAULT REPLICATE('B', 10) NOT NULL
    , c3 CHAR(10) DEFAULT REPLICATE('A', 10) NOT NULL  
);
GO

इस बार हमारा DBCC पेज आउटपुट अलग है और 'B' स्ट्रिंग पहले दिखाई देता है:

Memory Dump @0x000000000FC2A060

0000000000000000:   10001c00 01000000 42424242 42424242 †........BBBBBBBB 
0000000000000010:   42424141 41414141 41414141 030000††††BBAAAAAAAAAA... 

फिर से, केवल गिगल्स के लिए, डेटा फ़ाइल के हेक्स डंप की जांच करें:

BBBBBBBBBB

जैसा कि एक रिकॉर्ड की एनाटॉमी बताती है, एक रिकॉर्ड की निश्चित और चर लंबाई के कॉलम अलग-अलग ब्लॉकों में संग्रहीत किए जाते हैं। लॉजिकल रूप से इंटरलेयिंग फिक्स्ड और वेरिएबल कॉलम टाइप का फिजिकल रिकॉर्ड पर कोई असर नहीं पड़ता है। हालाँकि, प्रत्येक ब्लॉक के भीतर आपके कॉलम का क्रम डेटा फ़ाइल में बाइट्स के क्रम में मैप करता है।

CREATE TABLE FixedAndVariableColumns
(
    c1 INT IDENTITY(1,1) PRIMARY KEY CLUSTERED
    , c2 CHAR(10) DEFAULT REPLICATE('A', 10) NOT NULL
    , c3 VARCHAR(10) DEFAULT REPLICATE('B', 10) NOT NULL  
    , c4 CHAR(10) DEFAULT REPLICATE('C', 10) NOT NULL
    , c5 VARCHAR(10) DEFAULT REPLICATE('D', 10) NOT NULL
    , c6 CHAR(10) DEFAULT REPLICATE('E', 10) NOT NULL  
);
GO

Memory Dump @0x000000000E07C060

0000000000000000:   30002600 01000000 41414141 41414141 0.&.....AAAAAAAA 
0000000000000010:   41414343 43434343 43434343 45454545 AACCCCCCCCCCEEEE 
0000000000000020:   45454545 45450600 00020039 00430042 EEEEEE.....9.C.B 
0000000000000030:   42424242 42424242 42444444 44444444 BBBBBBBBBDDDDDDD 
0000000000000040:   444444†††††††††††††††††††††††††††††††DDD

यह भी देखें:

कॉलम ऑर्डर कोई फर्क नहीं पड़ता ... आम तौर पर, लेकिन - आईटी डिपेंडेंट!


+1 मैं सहमत हूं। मैंने हमेशा पाया है कि प्रत्येक अनुभाग के भीतर कॉलम का क्रम शुरू में CREATE TABLEकथन के अनुसार होता है (सिवाय इसके कि सीआई प्रमुख कॉलम पहले सेक्शन में आते हैं)। यदि ALTER COLUMNडेटाटाइप्स / कॉलम की लंबाई बदलती है, तो कॉलम का क्रम बदल सकता है । एकमात्र मामूली मामला जहां यह मायने रखता है कि मैं सोच सकता हूं कि रिक्त स्ट्रिंग या NULL के साथ चर लंबाई अनुभाग के अंत में कॉलम कॉलम ऑफसेट सरणी (2008 में इंटर्नल बुक में केलेन डेलानी द्वारा प्रदर्शित) में बिल्कुल भी जगह नहीं लेता है
मार्टिन स्मिथ

1
कॉलम ऑर्डर दुर्लभ कोने के मामलों में मायने रख सकता है। उदाहरण के लिए, यदि आपके पास 3 कॉलम A, B और C के साथ एक तालिका है, तो प्रत्येक 3kb बाइट्स लंबा है। SQL सर्वर पृष्ठ 8kb हैं, इसलिए Cफिट नहीं है, और अपने स्वयं के विस्तारित पृष्ठ में चला जाता है। तो select A, BYourTable` से केवल आधे पृष्ठ की आवश्यकता होती है select A, C from YourTable
एंडोमर

"Whether it matters or not is a different issue that I can't answer (yet).": स्तंभों का क्रम प्रदर्शन को महत्वपूर्ण रूप से प्रभावित कर सकता है। इसके अलावा, यह त्रुटियों को भी प्रभावित कर सकता है! इसे जांचें - डेमो 2 इसे बेहतर तरीके से दिखाता है मुझे लगता है
रोने एरेली

@RonenAriely दिलचस्प उदाहरण है, लेकिन यह मूल प्रश्न के संदर्भ में कुछ हद तक वंचित है। आप यह प्रदर्शित कर रहे हैं कि जब आप बाद में कॉलम को छोड़ते हैं तो कॉलम ऑर्डर पर क्या प्रभाव पड़ता है। मुझे नहीं लगता कि मैंने कभी किसी तालिका की दूरदर्शिता के साथ डिज़ाइन किया है कि मैं किस कॉलम को छोड़ दूंगा।
मार्क स्टोरी-स्मिथ

हाय @ MarkStorey- स्मिथ। (1) एक वास्तुकार के रूप में, मैं हमेशा समझाता हूं कि अच्छी तरह से डिजाइन और महान डिजाइन के बीच का अंतर यह है कि अच्छा डिजाइन वर्तमान जरूरतों को प्रदान करता है, जबकि महान डिजाइन भविष्य की जरूरतों को प्रदान करता है जो अभी तक ज्ञात नहीं हैं। (२) प्रश्न का उत्तर शुद्ध यस है। उत्तर का कार्यान्वयन ओपी और हम में से प्रत्येक के लिए है। यह चर्चा के दायरे से बाहर है, लेकिन हम इस विषय को चर्चा के लिए खोल सकते हैं। लेकिन स्टैकवॉयरफ़्लो फ़ोरम फ़ैमिली में नहीं, क्योंकि इंटरफ़ेस एक वास्तविक चर्चा करने की अनुमति नहीं देता है, लेकिन प्रतिक्रियाओं में पाठ की एक ही छोटी छोटी पंक्ति जोड़ देता है
रोनेन एरेली

7

यदि आप एक संकुल सूचकांक को परिभाषित नहीं करते हैं, तो आपको एक ढेर तालिका मिलेगी। ढेर तालिका के लिए आप हमेशा डेटा पढ़ते समय स्कैन करते रहेंगे और इस प्रकार पूरी पंक्तियों को पढ़ा जाएगा, स्तंभों के क्रम को एक म्यूट पॉइंट प्रदान करते हुए।

जैसे ही आप एक क्लस्टर इंडेक्स को परिभाषित करते हैं, आपके द्वारा निर्दिष्ट किए गए कॉलम के भौतिक क्रम के अनुरूप डेटा को फिर से व्यवस्थित किया जाता है - और इस बिंदु पर, भौतिक क्रम महत्वपूर्ण हो जाता है। भौतिक क्रम वह है जो आपके द्वारा उपयोग किए जा रहे विधेय के आधार पर मांगने वाले ऑपरेटर पात्रता को निर्धारित करता है।

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

अपडेट
वास्तव में आप दो सवाल पूछ रहे हैं - "क्या तालिका में स्तंभों के तार्किक क्रम का भंडारण की परत पर उनके भौतिक आदेश पर कोई प्रभाव पड़ता है" नहीं। तार्किक क्रम, जैसा कि मेटाडेटा द्वारा परिभाषित किया गया है, भौतिक रूप में उसी क्रम में नहीं होना चाहिए। मैं आपके लिए एक उत्तर की तलाश कर रहा हूं, क्या यह है कि क्रिएट टेबल में तार्किक क्रम सृजन पर समान भौतिक क्रम में परिणाम देता है - जिसे मैं नहीं जानता, ढेर के लिए - हालांकि ऊपर चेतावनी के साथ।


2

SQL सर्वर में स्तंभों के क्रम को मैंने जो देखा और पढ़ा है, उसके आधार पर कोई फर्क नहीं पड़ता। स्टोरेज इंजन पंक्ति पर कॉलम रखता है, भले ही वे क्रिएट टेबल स्टेटमेंट में निर्दिष्ट हों। यह कहा जा रहा है, मुझे यकीन है कि कुछ अलग-थलग किनारे मामले हैं जहां यह मायने रखता है, लेकिन मुझे लगता है कि आपके पास इन पर एक निश्चित उत्तर प्राप्त करने का कठिन समय होगा। पॉल रैंडल की " इनसाइड द स्टोरेज इंजन। ""पोस्ट की ब्लॉग श्रेणी सभी विवरणों के लिए सबसे अच्छा स्रोत है कि भंडारण इंजन कैसे काम करता है जिसके बारे में मुझे पता है। मुझे लगता है कि आपको सभी विभिन्न तरीकों का अध्ययन करना होगा जिसमें भंडारण कार्य और मैट्रिक्स का उपयोग सभी मामलों के खिलाफ होता है। उन किनारे के मामलों को खोजने के लिए जहां ऑर्डर मायने रखता है। जब तक कि एक विशिष्ट किनारे के मामले को इंगित नहीं किया जाता है जो मेरी स्थिति पर लागू होता है मैं सिर्फ अपने सृजन पर कॉलम को तार्किक रूप से ऑर्डर करता हूं। मुझे आशा है कि यह मदद करता है।


1

मुझे तुमसे मतलब है। डिजाइन के नजरिए से एक तालिका जो इस तरह दिखती है:

**EMPLOYEES**
EmployeeID
FirstName
LastName
Birthday
SSN 

इस तरह दिखने वाली तालिका से बहुत बेहतर है:

**EMPLOYEES**
LastName
EmployeeID
SSN 
Birthday
FirstName

यदि आप इस तरह से tsql जारी करते हैं, लेकिन डेटाबेस इंजन वास्तव में आपके तार्किक कॉलम ऑर्डर की परवाह नहीं करता है:

SELECT FirstName, LastName, SSN FROM Employees

इंजन को बस यह पता होता है कि फर्स्टनाम की सूची डिस्क में कहाँ संग्रहीत है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.