मैं SQL सर्वर को मेरे अनुक्रमित दृश्य कॉलम को पहचानने में कैसे मदद कर सकता हूं वह पूर्ण-सक्षम नहीं है?


9

मेरे पास SQL ​​Server 2008 में परिभाषित अनुक्रमित दृश्य है (आप परीक्षण उद्देश्यों के लिए जिस्ट से एक कामकाजी स्कीमा डाउनलोड कर सकते हैं):

CREATE VIEW dbo.balances
WITH SCHEMABINDING
AS
SELECT
      user_id
    , currency_id

    , SUM(transaction_amount)   AS balance_amount
    , COUNT_BIG(*)              AS transaction_count
FROM dbo.transactions
GROUP BY
      user_id
    , currency_id
;
GO

CREATE UNIQUE CLUSTERED INDEX UQ_balances_user_id_currency_id
ON dbo.balances (
      user_id
    , currency_id
);
GO

user_id, currency_idऔर transaction_amountसभी को NOT NULLकॉलम के रूप में परिभाषित किया गया है dbo.transactions। हालाँकि, जब मैं प्रबंधन स्टूडियो के ऑब्जेक्ट एक्सप्लोरर में दृश्य परिभाषा को देखता हूं, तो यह दृश्य में दोनों balance_amountऔर transaction_countजैसे - जैसे NULLस्तंभों को चिह्नित करता है ।

मैंने कई चर्चाओं पर एक नज़र डाली है, यह उनमें से सबसे अधिक प्रासंगिक है, जो सुझाव देता है कि कार्यों में कुछ फेरबदल करने से SQL सर्वर को पहचानने में मदद मिल सकती है कि एक दृश्य स्तंभ हमेशा होता है NOT NULL। मेरे मामले में ऐसा कोई फेरबदल संभव नहीं है, हालांकि, अनुक्रमित विचारों में समग्र कार्यों (जैसे एक ISNULL()से अधिक SUM()) पर अभिव्यक्तियों की अनुमति नहीं है

  1. क्या कोई ऐसा तरीका है जिससे मैं SQL सर्वर को पहचानने में मदद कर सकता हूं balance_amountऔर transaction_countयह संभव है NOT NULL?

  2. यदि नहीं, तो क्या मुझे इन स्तंभों के बारे में कोई चिंता होनी चाहिए जो गलती से पहचाने जाने योग्य हैं NULL?

    मैं जिन दो चिंताओं के बारे में सोच सकता था, वे हैं:

    • संतुलन को देखने के लिए मैप की गई कोई भी एप्लिकेशन ऑब्जेक्ट संतुलन की गलत परिभाषा प्राप्त कर रही है।
    • बहुत सीमित मामलों में, कुछ ऑप्टिमाइज़ेशन क्वेरी ऑप्टिमाइज़र के लिए उपलब्ध नहीं हैं, क्योंकि यह इस बात की गारंटी नहीं है कि ये दो कॉलम हैं NOT NULL

    क्या इन चिंताओं में से एक बड़ी बात है? क्या कोई अन्य चिंताएँ हैं जिन्हें मुझे ध्यान में रखना चाहिए?


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

यह एक गैर-अशक्त क्षेत्र (कोई कुल) पर पुनरावृत्ति करते समय एक पुनरावर्ती cte में भी एक मुद्दा प्रतीत होता है, हालांकि अंत में एक IsNull (..., 0) इलाज कर सकता है।
क्रोकसेक

जवाबों:


10

user_id, currency_idऔर transaction_amountसभी को NOT NULLकॉलम के रूप में परिभाषित किया गया हैdbo.transactions

यह मुझे दिखता है कि SQL सर्वर में एक कंबल धारणा है कि एक समुच्चय एक nullक्षेत्र का उत्पादन कर सकता है, भले ही वह जिस क्षेत्र पर चल रहा हो not null। यह कुछ मामलों में स्पष्ट रूप से सच है:

create table foo(bar integer not null);
select sum(bar) from foo
-- returns 1 row with `null` field

और की group byतरह सामान्यीकृत संस्करणों में भी सच हैcube

यह सरल परीक्षण मामला इस बात को दर्शाता है कि किसी भी समुच्चय को अशक्त होने के रूप में समझा जाता है:

CREATE VIEW dbo.balances
with schemabinding
AS
SELECT
      user_id
    , sum(1)   AS balance_amount
FROM dbo.transactions
GROUP BY
      user_id
;
GO

IMO यह SQL सर्वर की एक सीमा (यद्यपि एक नाबालिग) है - कुछ अन्य RDBMS उन विचारों पर कुछ बाधाओं के निर्माण की अनुमति देते हैं जो लागू नहीं होते हैं और केवल ऑप्टिमाइज़र को सुराग देने के लिए मौजूद होते हैं, हालांकि मुझे लगता है कि 'विशिष्टता' की अधिक संभावना है 'अशक्तता' की तुलना में एक अच्छी क्वेरी योजना बनाने में मदद


यदि स्तंभ की अशक्तता महत्वपूर्ण है, तो शायद ORM के साथ उपयोग करने के लिए, अनुक्रमणित दृश्य को किसी अन्य दृश्य में लपेटने पर विचार करें जो केवल गैर-अशक्तता की गारंटी देता है ISNULL:

CREATE VIEW dbo.balancesORM
WITH SCHEMABINDING
AS
SELECT 
    B.[user_id],
    B.currency_id,
    balance_amount = ISNULL(B.balance_amount, 0),
    transaction_count = ISNULL(B.transaction_count, 0)
FROM dbo.balances AS B;

SSMS ऑब्जेक्ट एक्सप्लोरर विवरण


5

मुझे नहीं लगता कि कोई भी तरीका है जो आपको SQL सर्वर को इन स्तंभों को पहचानने के लिए मजबूर नहीं कर सकता है, भले ही वे स्पष्ट रूप से नहीं हैं। आप कैसे परिभाषित के आदेश को बदलने की कोशिश कर सकते हैं ISNULL/ COALESCEअभिव्यक्ति के आसपास के अंदर SUM() , उदाहरण के लिए, लेकिन यह मदद करने के लिए नहीं जा रहा है।

मैं यह भी नहीं मानता कि आपके द्वारा याद किए जा रहे कोई भी अनुकूलन हैं - उन कॉलमों को वर्तमान में अनुक्रमित नहीं किया गया है, इसलिए ऐसा नहीं है कि ऑप्टिमाइज़र यह निर्धारित करने के लिए एक अलग एक्सेस विधि चुन सकता है, कह सकता है, सभी balance_amountमान> 10000। एक ऐसी स्थिति हो सकती है जहां यदि आप उन स्तंभों में से एक पर एक गैर-संकुलित सूचकांक बनाते हैं, तो आपको अनुमान लगाने की तुलना में थोड़ा बेहतर अनुमान मिल सकता है कि क्या सूचकांक नहीं है, लेकिन इसका अशक्तता से कोई लेना-देना नहीं है।

मैं प्रदर्शन के नजरिए से इस बारे में बहुत चिंतित नहीं हूं। मैं पीछे गया और मैंने वर्षों में बनाए गए अनुक्रमित दृश्यों का एक गुच्छा देखा और ये एकत्रीकरण कॉलम सभी अशक्त हैं। वे ठीक प्रदर्शन करते हैं।

जहां तक ​​ऑब्जेक्ट मैपिंग की बात है, फिर से, मैं इसके बारे में बहुत चिंतित नहीं होगा। चूंकि एप्लिकेशन अनुक्रमित दृश्य को अपडेट नहीं कर सकता है, इससे कोई फर्क नहीं पड़ता कि यह सोचता है कि यह balance_amountहो सकता है null। यह कभी नहीं एक प्राप्त करने के लिए जा रहा है null, और यह एक लिखने की कोशिश नहीं कर सकते null, तो <shrug>



@ एरन, ऑब्जेक्ट मैपिंग के बारे में: मैं इसे देखने लायक समझता हूं, क्योंकि एक मैपर संभवत: अशक्त प्रकारों के साथ बेकार / भ्रामक वस्तुओं को उत्पन्न करेगा जो कि वास्तव में कभी भी उपयोग नहीं किया जाएगा।
मार्सेल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.