অ-প্রাথমিক কীতে বিদেশী কী


136

আমার কাছে একটি টেবিল রয়েছে যা ডেটা ধারণ করে এবং সেই সারিগুলির মধ্যে একটির অন্য টেবিলে থাকা দরকার। সুতরাং, আমি রেফারেন্সিয়াল অখণ্ডতা বজায় রাখতে একটি বিদেশী কী চাই।

CREATE TABLE table1
(
   ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
   AnotherID INT NOT NULL,
   SomeData VARCHAR(100) NOT NULL
)

CREATE TABLE table2
(
   ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
   AnotherID INT NOT NULL,
   MoreData VARCHAR(30) NOT NULL,

   CONSTRAINT fk_table2_table1 FOREIGN KEY (AnotherID) REFERENCES table1 (AnotherID)
)

তবে, আপনি দেখতে পাচ্ছেন, টেবিলটি আমি বিদেশী কী, কলামটি পিকে নয়। এই বিদেশী কী তৈরি করার কোনও উপায় আছে, বা সম্ভবত এই রেফারেন্সিয়াল অখণ্ডতা বজায় রাখার আরও ভাল উপায়?


এটি করতে খুব বেশি অর্থ হয় না। কেন উল্লেখ না table1.ID?
zerkms

এটি নিশ্চিত যে আপনার অ্যানোথিডআইডি যদি প্রাথমিক কী না হয় তবে এটি বিদেশী কী হওয়া উচিত, সুতরাং বিদেশী হিসাবে আপনার টেবিল 2 একই টেবিলের দিকে নির্দেশ করা উচিত (সম্ভাব্য টেবিল 3)
রজার ব্যারেটো

উত্তর:


182

আপনি যদি সত্যিই অ-প্রাথমিক কীটির জন্য একটি বিদেশী কী তৈরি করতে চান তবে এটি অবশ্যই একটি কলাম হবে যা এতে অনন্য বাধা has

অনলাইন বই থেকে :

একটি বিদেশী মূল সীমাবদ্ধতা কেবলমাত্র অন্য টেবিলে একটি প্রাথমিক মূল সীমাবদ্ধতার সাথে সংযুক্ত হতে হবে না; এটি অন্য সারণীতে একটি অনন্য বাধার কলামগুলি উল্লেখ করতে সংজ্ঞায়িত করা যেতে পারে।

সুতরাং আপনার ক্ষেত্রে যদি আপনি AnotherIDঅনন্য করেন তবে এটি অনুমোদিত হবে। আপনি যদি কোনও অনন্য প্রতিবন্ধকতা প্রয়োগ করতে না পারেন তবে আপনার ভাগ্যের বাইরে।

যদিও, যেমনটি উল্লেখ করা হয়েছে, আপনার যদি প্রার্থী কী হিসাবে পুরোপুরি ভাল প্রাথমিক কী থাকে তবে কেন এটি ব্যবহার করবেন না?


1
আপনার শেষ প্রশ্নের সাথে সম্পর্কিত ... আমি পরিস্থিতি আমি কোথায় চাই যৌগিক প্রার্থী কী প্রাথমিক কী হতে হবে শুধু কারণ এটি শব্দার্থগতভাবে আরো গুরুত্ব রয়েছে এবং শ্রেষ্ঠ আমার মডেল বর্ণনা করে। আমিও পারফরম্যান্সের জন্য (উপরে উল্লিখিত হিসাবে) একটি নতুন তৈরি সারোগেট কীটি বিদেশী কী উল্লেখ করতে চাই। কেউ কি এই ধরনের সেটআপ নিয়ে কোনও সমস্যার পূর্বাভাস দিতে পারে?
ড্যানিয়েল ম্যাকিয়াস

স্যার আপনি কি দয়া করে বলতে পারেন যে বিদেশী কীটির পিছনে যুক্তিটি কী সর্বদা অনন্য বাধার সাথে উল্লেখ করে?
শিবাঙ্গি গুপ্ত


সাধারণ অ প্রাথমিক প্রাথমিক কী পূর্ণসংখ্যাটিকে অন্য টেবিলে বিদেশী কী হিসাবে ঘোষণা করা যেতে পারে? এটার মত. এটা কি সম্ভব? টেবিল প্রজেক্ট তৈরি করুন (পিএসএলএনও সংখ্যা (8,0) নাল নয়, প্রনমন নুমারিক (8,0), স্টেনং নুমারিক (8,0), কনট্রিন্ট পিকেপ্রজেক্ট প্রাইমারী কে (পিএসএলএনও), কনটেক্সট এফ কেপ্রজেক্ট 1 বিদেশী কর্মী (প্রিমেক) কর্মচারী , চুক্তি এফকে_প্রজেক্ট 2 বিদেশী কী (স্টেন) রেফারেন্সস কর্মচারী (এমপিআইডি),)
নাবিড

19

অন্যরা যেমন উল্লেখ করেছে, আদর্শভাবে, বিদেশী কীটি একটি প্রাথমিক কী (সাধারণত কোনও পরিচয় কলাম) এর রেফারেন্স হিসাবে তৈরি করা হবে। যাইহোক, আমরা একটি আদর্শ বিশ্বে বাস করি না, এবং কখনও কখনও স্কিমাতে "ছোট" পরিবর্তন প্রয়োগের যুক্তিতে তাত্পর্যপূর্ণ প্রভাব ফেলতে পারে।

এসএসএন কলাম (এবং একটি বোবা প্রাথমিক কী) সহ একটি গ্রাহক টেবিলের ক্ষেত্রে এবং একটি দাবি সারণী বিবেচনা করুন যাতে একটি এসএসএন কলামও রয়েছে (গ্রাহক ডেটা থেকে ব্যবসায়িক যুক্তি দ্বারা পপুলেটেড, তবে কোনও এফকে বিদ্যমান নেই)। নকশাটি ত্রুটিযুক্ত, তবে বেশ কয়েক বছর ধরে এটি ব্যবহৃত হয়েছে এবং স্কিমায় তিনটি পৃথক অ্যাপ্লিকেশন তৈরি করা হয়েছে। এটি স্পষ্ট হওয়া উচিত যে দাবি.এসএসএন ছড়িয়ে দেওয়া এবং প্রকৃত পিকে-এফকে সম্পর্ক স্থাপন করা আদর্শ হবে, তবে এটি একটি তাত্পর্যপূর্ণ পর্যালোচনাও হবে । অন্যদিকে, গ্রাহকএসএসএন-তে একটি অনন্য বাধা স্থাপন করা এবং দাবি.এসএসএন-তে একটি এফকে যুক্ত করা, অ্যাপ্লিকেশনগুলিতে সামান্য বা কোনও প্রভাব ছাড়াই প্রাসঙ্গিক অখণ্ডতা সরবরাহ করতে পারে।

আমাকে ভুল করবেন না, আমি সবই নরমালাইজেশনের জন্য, তবে মাঝে মাঝে বাস্তববাদবাদ আদর্শবাদের উপরে জয়ী হয়। যদি একটি সাধারণ নকশাকে ব্যান্ড-সহায়তা দিয়ে সহায়তা করা যায় তবে সার্জারি এড়ানো হতে পারে।


18

Necromancing।
আমি ধরে নিয়েছি যখন কেউ এখানে অবতরণ করছে তখন তার একটি টেবিলের কলামের জন্য একটি বিদেশী কী প্রয়োজন হবে যাতে অ-অনন্য কী রয়েছে।

সমস্যাটি হ'ল, যদি আপনার সেই সমস্যাটি থাকে তবে ডেটাবেস-স্কিমাটি অস্বীকৃত হয়।

আপনি উদাহরণস্বরূপ একটি টেবিলের মধ্যে একটি কক্ষ-উড প্রাথমিক কী, একটি ডেটফ্রোম এবং একটি ডেটটো ক্ষেত্র এবং অন্য একটি ইউআইডি সহ কক্ষগুলি রাখুন, এখানে একই ঘরে ট্র্যাক রাখতে RM_ApertureID এবং আরএম_স্ট্যাটাসের মতো একটি নরম-মোছা ক্ষেত্র, যেখানে 99 এর অর্থ 'মোছা' এবং <> 99 এর অর্থ 'সক্রিয়'।

সুতরাং আপনি যখন প্রথম ঘরটি তৈরি করবেন, আপনি আরএম_উইডের সমান মান হিসাবে আরএম_উইড এবং আরএম_আপারচারিউড IDোকান। তারপরে, আপনি যখন ঘরটি কোনও তারিখের কাছে অবসান করেন এবং এটিকে নতুন তারিখের সীমাতে পুনরায় প্রতিষ্ঠিত করেন, আরএম_িউডিটি নতুন () হয়, এবং পূর্ববর্তী এন্ট্রি থেকে আরএম_আপারচারিউড নতুন আরএম_আপারচারিউড হয়।

সুতরাং, যদি এটি হয় তবে আরএম_আপারচার্ডআইডি একটি অ-অনন্য ক্ষেত্র, এবং তাই আপনি অন্য টেবিলে একটি বিদেশী-কী সেট করতে পারবেন না।

এবং কোনও অ-অনন্য কলাম / সূচীতে বিদেশী কী সেট করার কোনও উপায় নেই, যেমন T_ZO_REM_AP_Raum_Reinigung (যেখানে আরএম_ইউডিটি আসলে আরএম_আপারচারিউড)।
তবে অবৈধ মানগুলিকে নিষিদ্ধ করতে আপনার একটি বিদেশী কী সেট করা দরকার, অন্যথায়, ডেটা-আবর্জনা ফলাফলের পরিবর্তে শীঘ্রই শীঘ্রই ...

এখন আপনি এই ক্ষেত্রে কী করতে পারেন (পুরো অ্যাপ্লিকেশনটি পুনরায় লেখার সংক্ষিপ্ত) একটি চেক-সীমাবদ্ধতা সন্নিবেশ করছে, কীটির উপস্থিতি যাচাই করে একটি স্কেলার ফাংশন সহ:

IF  EXISTS (SELECT * FROM sys.check_constraints WHERE object_id = OBJECT_ID(N'[dbo].[Check_RM_ApertureIDisValid_T_ZO_REM_AP_Raum_Reinigung]') AND parent_object_id = OBJECT_ID(N'[dbo].[T_ZO_REM_AP_Raum_Reinigung]'))
ALTER TABLE dbo.T_ZO_REM_AP_Raum_Reinigung DROP CONSTRAINT [Check_RM_ApertureIDisValid_T_ZO_REM_AP_Raum_Reinigung]
GO


IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fu_Constaint_ValidRmApertureId]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
DROP FUNCTION [dbo].[fu_Constaint_ValidRmApertureId]
GO




CREATE FUNCTION [dbo].[fu_Constaint_ValidRmApertureId](
     @in_RM_ApertureID uniqueidentifier 
    ,@in_DatumVon AS datetime 
    ,@in_DatumBis AS datetime 
    ,@in_Status AS integer 
) 
    RETURNS bit 
AS 
BEGIN   
    DECLARE @bNoCheckForThisCustomer AS bit 
    DECLARE @bIsInvalidValue AS bit 
    SET @bNoCheckForThisCustomer = 'false' 
    SET @bIsInvalidValue = 'false' 

    IF @in_Status = 99 
        RETURN 'false' 


    IF @in_DatumVon > @in_DatumBis 
    BEGIN 
        RETURN 'true' 
    END 


    IF @bNoCheckForThisCustomer = 'true'
        RETURN @bIsInvalidValue 


    IF NOT EXISTS
    ( 
        SELECT 
             T_Raum.RM_UID 
            ,T_Raum.RM_Status 
            ,T_Raum.RM_DatumVon 
            ,T_Raum.RM_DatumBis 
            ,T_Raum.RM_ApertureID 
        FROM T_Raum 
        WHERE (1=1) 
        AND T_Raum.RM_ApertureID = @in_RM_ApertureID 
        AND @in_DatumVon >= T_Raum.RM_DatumVon 
        AND @in_DatumBis <= T_Raum.RM_DatumBis 
        AND T_Raum.RM_Status <> 99  
    ) 
        SET @bIsInvalidValue = 'true' -- IF ! 

    RETURN @bIsInvalidValue 
END 



GO



IF  EXISTS (SELECT * FROM sys.check_constraints WHERE object_id = OBJECT_ID(N'[dbo].[Check_RM_ApertureIDisValid_T_ZO_REM_AP_Raum_Reinigung]') AND parent_object_id = OBJECT_ID(N'[dbo].[T_ZO_REM_AP_Raum_Reinigung]'))
ALTER TABLE dbo.T_ZO_REM_AP_Raum_Reinigung DROP CONSTRAINT [Check_RM_ApertureIDisValid_T_ZO_REM_AP_Raum_Reinigung]
GO


-- ALTER TABLE dbo.T_AP_Kontakte WITH CHECK ADD CONSTRAINT [Check_RM_ApertureIDisValid_T_ZO_REM_AP_Raum_Reinigung]  
ALTER TABLE dbo.T_ZO_REM_AP_Raum_Reinigung WITH NOCHECK ADD CONSTRAINT [Check_RM_ApertureIDisValid_T_ZO_REM_AP_Raum_Reinigung] 
CHECK 
( 
    NOT 
    ( 
        dbo.fu_Constaint_ValidRmApertureId(ZO_RMREM_RM_UID, ZO_RMREM_GueltigVon, ZO_RMREM_GueltigBis, ZO_RMREM_Status) = 1 
    ) 
) 
GO


IF  EXISTS (SELECT * FROM sys.check_constraints WHERE object_id = OBJECT_ID(N'[dbo].[Check_RM_ApertureIDisValid_T_ZO_REM_AP_Raum_Reinigung]') AND parent_object_id = OBJECT_ID(N'[dbo].[T_ZO_REM_AP_Raum_Reinigung]')) 
ALTER TABLE dbo.T_ZO_REM_AP_Raum_Reinigung CHECK CONSTRAINT [Check_RM_ApertureIDisValid_T_ZO_REM_AP_Raum_Reinigung] 
GO

পার্টিতে সর্বদা দেরী ... তবে এই বাস্তব-বিশ্বের পরামর্শের জন্য ধন্যবাদ - আমার কাছে ঠিক তা-ই আছে - দ্বিতীয় সারণীতে থাকা ডেটা সংস্করণযুক্ত (একটি কী ছাড়াও একটি তারিখের সীমাও রয়েছে), এবং আমি কেবল সর্বশেষতম সংস্করণটি লিঙ্ক করতে চাই আমার প্রাথমিক সারণী থেকে ...
আয়ান

1
দুর্দান্ত বাস্তবের পরামর্শ! আমি লিগ্যাসি অ্যাপ্লিকেশন সহ প্রচুর পরিস্থিতি কল্পনা করতে পারি যেখানে "সেরা অনুশীলন" এক কারণে বা অন্য কোনও কারণে সম্ভব নয় এবং চেক সীমাবদ্ধতাটি সুন্দরভাবে কাজ করবে।
ryanwc

এই সমাধানটি অবিশ্বাস্য। দেখুন: dba.stackexchange.com/…/how-are-my-sql-server-constraints-being- বাইপাসড
স্টম

2

প্রাথমিক কীগুলি সর্বদা স্বতন্ত্র হওয়া দরকার, বিদেশী কীগুলিকে অ-অনন্য মানগুলির মঞ্জুরি দেওয়া দরকার যদি টেবিলটি একের মধ্যে একাধিক সম্পর্ক। যদি টেবিলটি এক-এক-এক সম্পর্কের দ্বারা না হয়ে, এক-একের মধ্যে সম্পর্কের দ্বারা সংযুক্ত থাকে তবে প্রাথমিক কী হিসাবে বিদেশী কীটি ব্যবহার করা পুরোপুরি ঠিক।

একটি বিদেশী মূল সীমাবদ্ধতা কেবলমাত্র অন্য টেবিলে একটি প্রাথমিক মূল সীমাবদ্ধতার সাথে সংযুক্ত হতে হবে না; এটি অন্য সারণীতে একটি অনন্য বাধার কলামগুলি উল্লেখ করতে সংজ্ঞায়িত করা যেতে পারে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.