বিজ্ঞপ্তিযুক্ত বিদেশী কী উল্লেখগুলি গ্রহণযোগ্য কি \ সেগুলি কীভাবে এড়ানো যায়?


29

বিদেশী কী ক্ষেত্রে দুটি টেবিলের মধ্যে একটি বিজ্ঞপ্তি রেফারেন্স গ্রহণযোগ্য?

তা না হলে কীভাবে এই পরিস্থিতি এড়ানো যায়?

যদি তাই হয় তবে কীভাবে ডেটা ?োকানো যাবে?

নীচে যেখানে (আমার মতে) একটি বিজ্ঞপ্তি রেফারেন্স গ্রহণযোগ্য হবে তার উদাহরণ দেওয়া হল:

CREATE TABLE Account
(
    ID INT PRIMARY KEY IDENTITY,
    Name VARCHAR(50)
)

CREATE TABLE Contact
(
    ID INT PRIMARY KEY IDENTITY,
    Name VARCHAR(50),
    AccountID INT FOREIGN KEY REFERENCES Account(ID)
)

ALTER TABLE Account ADD PrimaryContactID INT FOREIGN KEY REFERENCES Contact(ID)

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

উত্তর:


12

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

এটি বলার পরে, আমার ব্যক্তিগত পছন্দটি নীচের সেটআপ করা হবে:

CREATE TABLE dbo.Accounts
(
    AccountID INT NOT NULL
        CONSTRAINT PK_Accounts
        PRIMARY KEY CLUSTERED
        IDENTITY(1,1)
    , AccountName VARCHAR(255)
);

CREATE TABLE dbo.Contacts
(
    ContactID INT NOT NULL
        CONSTRAINT PK_Contacts
        PRIMARY KEY CLUSTERED
        IDENTITY(1,1)
    , ContactName VARCHAR(255)
);

CREATE TABLE dbo.AccountsContactsXRef
(
    AccountsContactsXRefID INT NOT NULL
        CONSTRAINT PK_AccountsContactsXRef
        PRIMARY KEY CLUSTERED
        IDENTITY(1,1)
    , AccountID INT NOT NULL
        CONSTRAINT FK_AccountsContactsXRef_AccountID
        FOREIGN KEY REFERENCES dbo.Accounts(AccountID)
    , ContactID INT NOT NULL
        CONSTRAINT FK_AccountsContactsXRef_ContactID
        FOREIGN KEY REFERENCES dbo.Contacts(ContactID)
    , IsPrimary BIT NOT NULL 
        CONSTRAINT DF_AccountsContactsXRef
        DEFAULT ((0))
    , CONSTRAINT UQ_AccountsContactsXRef_AccountIDContactID
        UNIQUE (AccountID, ContactID)
);

CREATE UNIQUE INDEX IX_AccountsContactsXRef_Primary
ON dbo.AccountsContactsXRef(AccountID, IsPrimary)
WHERE IsPrimary = 1;

এটি এর ক্ষমতা প্রদান করে:

  1. পিটার তার উত্তরে যেভাবে পরামর্শ দেয় তা ক্রস-রেফারেন্স টেবিলের মাধ্যমে স্পষ্টভাবে পরিচিতি এবং অ্যাকাউন্টগুলির মধ্যে সম্পর্ক চিত্রিত করুন
  2. একটি শব্দ, অ-বৃত্তাকার পদ্ধতিতে রেফারেন্সিয়াল অখণ্ডতা বজায় রাখুন।
  3. সূচকের মাধ্যমে প্রাথমিক যোগাযোগের একটি অত্যন্ত রক্ষণাবেক্ষণযোগ্য তালিকা সরবরাহ করুন IX_AccountsContactsXRef_Primary। এই সূচীতে একটি ফিল্টার রয়েছে, সুতরাং এটি কেবল প্ল্যাটফর্মগুলিতে কাজ করবে যা তাদের সমর্থন করে। যেহেতু এই সূচকটি UNIQUEবিকল্পের সাথে নির্দিষ্ট করা হয়েছে , তাই প্রতিটি অ্যাকাউন্টের জন্য কেবলমাত্র একক প্রাথমিক যোগাযোগ থাকতে পারে।

উদাহরণস্বরূপ, আপনি যদি প্রতিটি অ্যাকাউন্টের তালিকার শীর্ষে প্রাথমিক পরিচিতিগুলি দেখিয়ে "প্রাথমিক" স্থিতিটি চিহ্নিত করে একটি কলাম সহ সমস্ত পরিচিতির একটি তালিকা প্রদর্শন করতে চান, আপনি এটি করতে পারেন:

SELECT A.AccountName
    , C.ContactName
    , XR.IsPrimary
FROM dbo.Accounts A
    INNER JOIN dbo.AccountsContactsXRef XR ON A.AccountID = XR.AccountID
    INNER JOIN dbo.Contacts C ON XR.ContactID = C.ContactID
ORDER BY A.AccountName
    , XR.IsPrimary DESC
    , C.ContactName;

ফিল্টারড সূচক একাউন্টে একক প্রাথমিক যোগাযোগের চেয়ে বেশি সন্নিবেশ রোধ করে, যখন একই সাথে প্রাথমিক পরিচিতির একটি তালিকা ফেরতের দ্রুত পদ্ধতি সরবরাহ করে। IsActiveঅ্যাকাউন্টের সাথে পরিচিতিগুলির আর কোনও সম্পর্ক নেই তার পরেও, অ্যাকাউন্টের জন্য পরিচিতির ইতিহাস বজায় রাখতে একটি অনন্য-অনন্য ফিল্টারড সূচক সহ সহজেই অন্য কলামটি কল্পনা করা যায় :

ALTER TABLE dbo.AccountsContactsXRef
ADD IsActive BIT NOT NULL
CONSTRAINT DF_AccountsContactsXRef_IsActive
DEFAULT ((1));

CREATE INDEX IX_AccountsContactsXRef_IsActive
ON dbo.AccountsContactsXRef(IsActive)
WHERE IsActive = 1;

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

আমি বৃত্তাকার উল্লেখগুলি পছন্দ করি না কারণ তারা অযথা নকশা জটিল করে তোলে এবং বেশিরভাগ সময় ট্রেড-অফের কোনও উল্লেখযোগ্য পারফরম্যান্স সুবিধা দেয় না। আমি ওকামের রেজারের একজন অনুরাগী এবং ফলস্বরূপ কোনও প্রদত্ত সমস্যার সহজ সমাধানের দিকে ঝুঁকছি।
ম্যাক্স ভার্নন

1
আমি সবই ওসামের রেজারের জন্য আছি তবে উপরের বর্ণনিত ডিজাইনটি আমাকে তৃতীয় সাধারণ ফর্মটি লঙ্ঘন না করে কিছু 2 য় প্রশ্ন এড়াতে বা যোগদান করতে সক্ষম করেছে। আমি আপনার প্রতিক্রিয়াটির প্রশংসা করি
উভচর

6

না, বিজ্ঞপ্তিযুক্ত বিদেশী কী উল্লেখগুলি গ্রহণযোগ্য নয়। কেবল এই কারণে নয় যে নিয়মিত সীমাবদ্ধতা ফেলে এবং পুনরায় সরিয়ে না রেখে ডেটা toোকানো অসম্ভব। তবে এটি যে কোনও এবং প্রতিটি ডোমেনের আমি ভাবতে পারি তার মৌলিক ত্রুটিযুক্ত মডেল। আপনার উদাহরণে আমি এমন কোনও ডোমেইনের কথা ভাবতে পারি না যেখানে অ্যাকাউন্ট এবং পরিচিতির মধ্যে সম্পর্ক এনএন নয়, এফকে রেফারেন্স সহ জংশন টেবিলের প্রয়োজন অ্যাকাউন্ট এবং পরিচিতি উভয় ক্ষেত্রেই।

CREATE TABLE Account
(
    ID INT PRIMARY KEY IDENTITY,
    Name VARCHAR(50)
)

CREATE TABLE Contact
(
    ID INT PRIMARY KEY IDENTITY,
    Name VARCHAR(50),
)

CREATE TABLE AccountContact
(
    AccountID INT FOREIGN KEY REFERENCES Account(ID),
    ContactID INT FOREIGN KEY REFERENCES Contact(ID),

    primary key(AccountID,ContactID)
)

5
" ডেটা toোকানো অসম্ভব " - না, এটি অসম্ভব হবে না। সীমাবদ্ধতাগুলি কেবল স্থগিতযোগ্য হিসাবে ঘোষণা করুন। তবে আমি একমত না: প্রায় সব ক্ষেত্রে বিজ্ঞপ্তি উল্লেখগুলি একটি খারাপ নকশা।
a_horse_with_no_name

3
@ এ_হর্স - এসকিউএল সার্ভারে একটি নিকৃষ্ট রেফারেন্সটি সংজ্ঞায়িত করা সম্ভব নয় ... আমি জানি আপনি ওরাকল এ পারবেন, কেবল তাত্পর্যটি তুলে ধরতে চেয়েছিলেন।
ম্যাক্স ভার্নন

2
@ ম্যাক্স ভার্নন: প্রশ্নটি কেবল এসকিউএল সার্ভার সম্পর্কে নয় এবং কেবল ওরাকলের চেয়ে আরও বেশি ডিবিএমএস রয়েছে যা মুলতুবি প্রতিরোধকে সমর্থন করে - তবে আমি যেমন বলেছিলাম: আমি পিটারের সাথে একমত হই যে নকশাটি নিজেই ভুল (এবং তার সমাধানটি আরও বেশি বোঝায়)
a_horse_with_no_name

4
যেকোন একটি উদাহরণের সুনির্দিষ্ট বিষয়গুলি বাদ দিয়ে, সাধারণভাবে বলা যায় যে পারস্পরিক সম্পর্কের (যেমন "বিজ্ঞপ্তি") রেফারেন্সিয়াল অখণ্ডতার সীমাবদ্ধতা থাকার বিষয়ে অগত্যা ভুল বা "ত্রুটিযুক্ত" কিছুই নেই। এটি কার্যকরভাবে যোগদানের নির্ভরতার এক উদাহরণ। আপনার ডিবিএমএস আপনাকে সেগুলি প্রয়োগ করার অনুমতি দিলে যোগদানের নির্ভরতা নীতিগতভাবে একটি ভাল জিনিস। এটি কেবলমাত্র এসকিউএল ডিবিএমএসগুলিতে টেবিলের মধ্যে জটিল নির্ভরতা প্রয়োগ করা খুব সহজ নয়।
এনভিজেল

6
@ পিটার, 1-1 কেবল যোগদানের নির্ভরতার একমাত্র উদাহরণ নয় এবং এটি কোনও বিশেষ ক্ষেত্রেও নয়। এমন কিছু ক্ষেত্রে রয়েছে যেখানে যোগদানের উপর নির্ভরশীলতার সীমাবদ্ধতাগুলি সঠিক ধারণা দেয়।
এনভোভেল

1

আপনি আপনার বাহ্যিক অবজেক্টটি অ্যাকাউন্টের পরিবর্তে প্রাথমিক যোগাযোগের দিকে নির্দেশ করতে পারেন। আপনার ডেটা এইরকম দেখাবে:

CREATE TABLE Account
(
    ID INT PRIMARY KEY IDENTITY,
    Name VARCHAR(50)
)

CREATE TABLE Contact
(
    ID INT PRIMARY KEY IDENTITY,
    Name VARCHAR(50),
    AccountID INT FOREIGN KEY REFERENCES Account(ID)
)

CREATE TABLE AccountOwner (
    Other Stuff Here . . .
    PrimaryContactID INT FOREIGN KEY REFERENCES Contact(ID)
)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.