क्या कोई नल स्तंभ प्राथमिक कुंजी का हिस्सा हो सकता है?


15

मैं SQL Server 2012 डेटाबेस विकसित कर रहा हूं और मेरे पास वन-टू-जीरो-ओर-वन रिलेशनशिप के बारे में एक सवाल है।

मेरे पास दो टेबल हैं, Codesऔर HelperCodes। एक कोड में शून्य या एक सहायक कोड हो सकता है। यह इन दो तालिकाओं और उनके संबंधों को बनाने के लिए sql स्क्रिप्ट है:

CREATE TABLE [dbo].[Code]
(
    [Id] NVARCHAR(20) NOT NULL, 
    [Level] TINYINT NOT NULL, 
    [CommissioningFlag] TINYINT NOT NULL, 
    [SentToRanger] BIT NOT NULL DEFAULT 0, 
    [LastChange] NVARCHAR(50) NOT NULL, 
    [UserName] NVARCHAR(50) NOT NULL, 
    [Source] NVARCHAR(50) NOT NULL, 
    [Reason] NVARCHAR(200) NULL, 
    [HelperCodeId] NVARCHAR(20) NULL,
    CONSTRAINT [PK_Code] PRIMARY KEY CLUSTERED
    (
        [Id] ASC
    ),
    CONSTRAINT [FK_Code_LevelConfiguration]
       FOREIGN KEY ([Level])
        REFERENCES [dbo].[LevelConfiguration] ([Level]),
    CONSTRAINT [FK_Code_HelperCode]
       FOREIGN KEY ([HelperCodeId])
        REFERENCES [dbo].[HelperCode] ([HelperCodeId])
)

CREATE TABLE [dbo].[HelperCode]
(
    [HelperCodeId] NVARCHAR(20) NOT NULL, 
    [Level] TINYINT NOT NULL, 
    [CommissioningFlag] TINYINT NOT NULL, 
    [LastChange] NVARCHAR(50) NOT NULL,
    CONSTRAINT [PK_HelperCode] PRIMARY KEY CLUSTERED
    (
        [HelperCodeId] ASC
    ),
    CONSTRAINT [FK_HelperCode_LevelConfiguration]
       FOREIGN KEY ([Level])
        REFERENCES [dbo].[LevelConfiguration] ([Level])
)

क्या वो सही है?

एक कोड और एक हेल्परकोड दोनों अलग-अलग संस्थाएं हैं। एक हेल्परकोड का उपयोग किया जा सकता है (कोई भी कोड इसे संदर्भित नहीं करता है), या उपयोग किया जाता है (केवल एक कोड इसे संदर्भित करता है)।

शायद Code.HelperCodeId कोड तालिका प्राथमिक कुंजी का हिस्सा होना चाहिए। लेकिन मुझे यकीन नहीं है कि एक अशक्त स्तंभ प्राथमिक का हिस्सा हो सकता है। ऐसा करते हुए, मैं चाहता हूं कि दो या अधिक कोड एक ही हेल्परकोड का संदर्भ दें।


1
आप HelperCodeIdपीके का हिस्सा क्यों बनना चाहेंगे ? क्या यह किसी भी संयोग से है, क्योंकि आप एक ही हेल्परकोड को संदर्भित करने के लिए दो या अधिक कोड को रोकना चाहते हैं?
एंड्री एम।

हां, मैं चाहता हूं कि दो या अधिक कोड एक ही हेल्परकोड का संदर्भ दें। एक अन्य विकल्प HelperCodeIdकॉलम को विशिष्ट के रूप में सेट करना है ।
वंसफनेल

@ypercube क्या आप उत्तर के रूप में पूरा sql वाक्य जोड़ सकते हैं? मैं बहुत बार sql के साथ काम नहीं करता और मुझे नहीं पता कि यह कैसे करना है। धन्यवाद।
वंसफनल

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

@AlterMitty मुझे कभी समझ में नहीं आया कि पीके में एक शून्य मान होने से आरडीबीएमएस द्वारा लाया गया मूल्य नष्ट हो जाएगा। मैंने इसे कई बार सुना है। क्या आप विस्तार से समझा सकते हैं?
usr

जवाबों:


24

शीर्षक में प्रश्न का उत्तर देने के लिए, नहीं, सभी प्राथमिक कॉलम होने चाहिए NOT NULL

लेकिन तालिकाओं के डिज़ाइन में बदलाव किए बिना, आप Code (HelperCodeId)स्तंभ पर एक फ़िल्टर किया गया अनुक्रमणिका जोड़ सकते हैं :

CREATE UNIQUE INDEX 
    FUX_Code_HelperCodeId
ON dbo.Code 
    (HelperCodeId) 
WHERE 
    HelperCodeId IS NOT NULL ;

WHERE HelperCodeId IS NOT NULLSQL- सर्वर जिस तरह से अद्वितीय अवरोधों और अद्वितीय अनुक्रमणिकाओं में नल का इलाज करता है, उसके कारण फ़िल्टर ( ) की आवश्यकता है। फिल्टर के बिना, एसक्यूएल सर्वर के साथ-एक से अधिक पंक्ति की अनुमति नहीं होगी NULLमें HelperCodeId


एक वैकल्पिक डिजाइन को दूर किया जाएगा HelperCodeIdसे Codeऔर एक तिहाई तालिका स्टोर करेगा जोड़ने Code- HelperCodeसंबंधों। दोनों संस्थाओं के बीच संबंध शून्य-या-एक से शून्य-या-एक (दोनों कोड में कोई हेल्परकोड नहीं हो सकता है और एक हेल्परकोड का उपयोग बिना किसी कोड के किया जा सकता है):

CREATE TABLE [dbo].[Code]
(
    [Id] NVARCHAR(20) NOT NULL, 
    [Level] TINYINT NOT NULL, 
    [CommissioningFlag] TINYINT NOT NULL, 
    [SentToRanger] BIT NOT NULL DEFAULT 0, 
    [LastChange] NVARCHAR(50) NOT NULL, 
    [UserName] NVARCHAR(50) NOT NULL, 
    [Source] NVARCHAR(50) NOT NULL, 
    [Reason] NVARCHAR(200) NULL, 
    -- 
    -- removed:   [HelperCodeId] NVARCHAR(20) NULL,
    -- 
    CONSTRAINT [PK_Code] PRIMARY KEY CLUSTERED
    (
        [Id] ASC
    ),
    CONSTRAINT [FK_Code_LevelConfiguration]
       FOREIGN KEY ([Level])
        REFERENCES [dbo].[LevelConfiguration] ([Level]),
) ;

HelperCode कुछ नहीं बदला है:

CREATE TABLE [dbo].[HelperCode]
(
    [HelperCodeId] NVARCHAR(20) NOT NULL, 
    [Level] TINYINT NOT NULL, 
    [CommissioningFlag] TINYINT NOT NULL, 
    [LastChange] NVARCHAR(50) NOT NULL,
    CONSTRAINT [PK_HelperCode] PRIMARY KEY CLUSTERED
    (
        [HelperCodeId] ASC
    ),
    CONSTRAINT [FK_HelperCode_LevelConfiguration]
       FOREIGN KEY ([Level])
        REFERENCES [dbo].[LevelConfiguration] ([Level])
) ;

अतिरिक्त तालिका में दो UNIQUEविरोधाभास (या एक प्राथमिक और एक अद्वितीय) होंगे ताकि यह सुनिश्चित किया जा सके कि प्रत्येक कोड (अधिकतम) एक हेल्परकोड से संबंधित है और प्रत्येक हेल्परकोड (अधिकतम) एक कोड से संबंधित है। दोनों कॉलम होंगे NOT NULL:

CREATE TABLE [dbo].[Code_HelperCode]
(
    [CodeId] NVARCHAR(20) NOT NULL, 
    [HelperCodeId] NVARCHAR(20) NOT NULL, 
    CONSTRAINT [UQ_Code_HelperCode_CodeId]
       UNIQUE (CodeId),
    CONSTRAINT [UQ_Code_HelperCode_HelperCodeId]
       UNIQUE (HelperCodeId),
    CONSTRAINT [FK_HelperCode_Code]
       FOREIGN KEY ([CodeId])
        REFERENCES [dbo].[Code] ([Id]),
    CONSTRAINT [FK_Code_HelperCode]
       FOREIGN KEY ([HelperCodeId])
        REFERENCES [dbo].[HelperCode] ([HelperCodeId])
) ;

धन्यवाद, यदि आप चाहें तो आप डिजाइन को बदल सकते हैं। मैं बहुत कुछ सीख सकता था।
वंसफनेल

आपके डिजाइन के लिए धन्यवाद। मैंने एक नई तालिका नहीं जोड़ी है क्योंकि मुझे लगता है कि इन तालिकाओं का उपयोग कई-से-कई संबंधों में किया जाता है।
VansFannel

0

इसके बजाय एक अद्वितीय बाधा का उपयोग करने का प्रयास करें। माना जाता है कि एएनएसआई मानक ने अमान्य घोषित होने के लिए एक प्राथमिक कुंजी के रूप में अशक्त घोषित किया है, लेकिन मैंने कभी मानक नहीं देखा है और इसे सत्यापित करने के लिए इसे खरीदने की इच्छा नहीं है।

अशक्त कुंजियाँ न होना उन चीजों में से एक प्रतीत होता है जो डेवलपर्स को एक तरह से या दूसरे पर बहुत कठिन विश्वास है। मेरी प्राथमिकता उनका उपयोग करना है क्योंकि मुझे यह देखने के लिए उपयोगी है कि टूलटिप्स वाले लुकअप टेबल और कॉम्बोक्स के लिए संबंधित डेटा जो आबादी नहीं हैं।

मुझे सिखाया गया था कि अशक्त मान इंगित करता है कि एक चर कभी सेट नहीं किया गया है और खाली मान इंगित करता है कि मूल्य अतीत में निर्धारित किया गया है। बेशक यह एप्लिकेशन के लिए परिभाषित करने के लिए डेवलपर पर निर्भर है, लेकिन मुझे खाली प्राथमिक कुंजी की अनुमति देने के लिए यह निरर्थक लगता है लेकिन प्राथमिक कुंजी नहीं।

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