আমি কীভাবে একটি ডেটাবেসে IS-A সম্পর্ককে মানচিত্র করব?


26

নিম্নোক্ত বিবেচনা কর:

entity User
{
    autoincrement uid;
    string(20) name;
    int privilegeLevel;
}

entity DirectLoginUser
{
    inherits User;
    string(20) username;
    string(16) passwordHash;
}

entity OpenIdUser
{
    inherits User;
    //Whatever attributes OpenID needs... I don't know; this is hypothetical
}

বিভিন্ন ধরণের ব্যবহারকারী (সরাসরি লগইন ব্যবহারকারী এবং ওপেনআইডি ব্যবহারকারী) আইএস-এ সম্পর্ক প্রদর্শন করে; যথা, উভয় ধরণের ব্যবহারকারীই ব্যবহারকারী। আরডিবিএমএসে এটি উপস্থাপনের বিভিন্ন উপায় রয়েছে:

ওয়ে এক

CREATE TABLE Users
(
    uid INTEGER AUTO_INCREMENT NOT NULL,
    name VARCHAR(20) NOT NULL,
    privlegeLevel INTEGER NOT NULL,
    type ENUM("DirectLogin", "OpenID") NOT NULL,
    username VARCHAR(20) NULL,
    passwordHash VARCHAR(20) NULL,
    //OpenID Attributes
    PRIMARY_KEY(uid)
)

ওয়ে দুই

CREATE TABLE Users
(
    uid INTEGER AUTO_INCREMENT NOT NULL,
    name VARCHAR(20) NOT NULL,
    privilegeLevel INTEGER NOT NULL,
    type ENUM("DirectLogin", "OpenID") NOT NULL,
    PRIMARY_KEY(uid)
)

CREATE TABLE DirectLogins
(
    uid INTEGER NOT_NULL,
    username VARCHAR(20) NOT NULL,
    passwordHash VARCHAR(20) NOT NULL,
    PRIMARY_KEY(uid),
    FORIGEN_KEY (uid) REFERENCES Users.uid
)

CREATE TABLE OpenIDLogins
(
    uid INTEGER NOT_NULL,
    // ...
    PRIMARY_KEY(uid),
    FORIGEN_KEY (uid) REFERENCES Users.uid
)

ওয়ে থ্রি

CREATE TABLE DirectLoginUsers
(
    uid INTEGER AUTO_INCREMENT NOT NULL,
    name VARCHAR(20) NOT NULL,
    privlegeLevel INTEGER NOT NULL,
    username VARCHAR(20) NOT NULL,
    passwordHash VARCHAR(20) NOT NULL,
    PRIMARY_KEY(uid)
)

CREATE TABLE OpenIDUsers
(
    uid INTEGER AUTO_INCREMENT NOT NULL,
    name VARCHAR(20) NOT NULL,
    privlegeLevel INTEGER NOT NULL,
    //OpenID Attributes
    PRIMARY_KEY(uid)
)

আমি প্রায় নিশ্চিত তৃতীয় উপায়টি ভুল উপায়, কারণ ডেটাবেসের অন্য কোথাও ব্যবহারকারীর বিরুদ্ধে সরল যোগদান সম্ভব নয়।

আমার আসল বিশ্বের উদাহরণটি যদিও বিভিন্ন লগইনের উদাহরণ সহ ব্যবহারকারী নয়; এই সম্পর্কটিকে সাধারণ ক্ষেত্রে কীভাবে মডেল করা যায় সে সম্পর্কে আমি আগ্রহী।


জোয়েল ব্রাউন দ্বারা দেওয়া মন্তব্যে প্রস্তাবিত পদ্ধতির অন্তর্ভুক্ত করার জন্য আমি আমার উত্তরটি সম্পাদনা করেছি। এটা আপনার জন্য কাজ করা উচিত। আপনি যদি আরও পরামর্শ সন্ধান করছেন, আপনি কোনও মাইএসকিউএল-নির্দিষ্ট উত্তর খুঁজছেন তা বোঝাতে আমি আপনার প্রশ্নটি আবার ট্যাগ করব।
নিক চাম্মাস

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

পোস্টগ্রিএসকিউএল-এর মতো অবজেক্ট-রিলেশনাল ডেটাবেজে, আসলে চতুর্থ উপায় রয়েছে: আপনি অন্য টেবিল থেকে একটি সারণী নিখরচায় ঘোষণা করতে পারেন। postgresql.org/docs/current/static/tutorial-inheritance.html
মার্কাসচবার

উত্তর:


16

উপায় দুটি সঠিক উপায়।

আপনার বেস ক্লাসটি একটি টেবিল পায় এবং তারপরে শিশু ক্লাসগুলি কেবলমাত্র তাদের অতিরিক্ত ক্ষেত্রগুলি উপস্থাপন করে, বেস টেবিলের সাথে বিদেশী কী উল্লেখ সহ তাদের নিজস্ব টেবিলগুলি পায়।

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

উদাহরণস্বরূপ, মাইএসকিউএল ডিডিএল এর মতো দেখতে লাগবে:

CREATE TABLE Users
(
      uid               INTEGER AUTO_INCREMENT NOT NULL
    , type              ENUM("DirectLogin", "OpenID") NOT NULL
    // ...

    , PRIMARY_KEY(uid)
);

CREATE TABLE DirectLogins
(
      uid               INTEGER NOT_NULL
    , type              ENUM("DirectLogin") NOT NULL
    // ...

    , PRIMARY_KEY(uid)
    , FORIGEN_KEY (uid, type) REFERENCES Users (uid, type)
);

CREATE TABLE OpenIDLogins
(
      uid               INTEGER NOT_NULL
    , type              ENUM("OpenID") NOT NULL
    // ...

    PRIMARY_KEY(uid),
    FORIGEN_KEY (uid, type) REFERENCES Users (uid, type)
);

(অন্যান্য প্ল্যাটফর্মে আপনি CHECKপরিবর্তে একটি সীমাবদ্ধতা ব্যবহার করবেন ENUM)) মাইএসকিউএল যৌথ বিদেশী কী সমর্থন করে যাতে এটি আপনার পক্ষে কাজ করা উচিত।

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

উপায় তিনটি এমন কোনও প্রশ্নের উপর চাপ দেয় যা ব্যবহারকারীদের উভয় টেবিলের বিপরীতে পরীক্ষা করতে বাধ্য করে। এটি আপনাকে বিদেশী চাবির মাধ্যমে একক ব্যবহারকারীর টেবিলটি উল্লেখ করতে বাধা দেয়।


1
আমি উপায়টি কীভাবে ব্যবহার করব যে উপায় 2 ব্যবহার করে, এটি প্রয়োগ করার কোনও উপায় নেই যে দুটি অন্য টেবিলের সাথে ঠিক একই রকম সারি রয়েছে?
বিলি ওনিল

2
@ বিলি - ভাল আপত্তি যদি আপনার ব্যবহারকারীদের কেবল একটি বা অন্য থাকতে পারে তবে আপনি এটি আপনার প্রোক স্তর বা ট্রিগারগুলির মাধ্যমে প্রয়োগ করতে পারেন। আমি ভাবছি যদি এই সীমাবদ্ধতা প্রয়োগের জন্য কোনও ডিডিএল-স্তরের উপায় থাকে? (হায়, সূচী দর্শনগুলি অনুমতি দেয় না UNION , বা আমি দুটি টেবিলের UNION ALLতুলনায় অনন্য uid
সূচকযুক্ত

অবশ্যই এটি ধরে নিয়েছে যে আপনার আরডিবিএমএস প্রথমে সূচিযুক্ত ভিউ সমর্থন করে supported
বিলি ওনিল

1
এই ধরণের ক্রস-টেবিল সীমাবদ্ধতা কার্যকর করার সহজ উপায় হ'ল সুপার-টাইপ সারণীতে একটি পার্টিশন বৈশিষ্ট্য অন্তর্ভুক্ত করা। তারপরে প্রতিটি উপ-প্রকারটি এটি কেবলমাত্র সুপার-টাইপের সাথে সম্পর্কিত যেখানে উপযুক্ত পার্টিশন বৈশিষ্ট্যযুক্ত মান রয়েছে তা পরীক্ষা করতে পারে। এটি এক বা একাধিক অন্যান্য সাব-টাইপ সারণী দেখে সংঘর্ষের পরীক্ষাটি করা সংরক্ষণ করে।
জোয়েল ব্রাউন 21

1
@ জোয়েল - সুতরাং, উদাহরণস্বরূপ, আমরা typeপ্রতিটি উপ-ধরণের টেবিলের সাথে একটি কলাম যুক্ত করি যা সীমাবদ্ধতার মধ্য দিয়ে CHECKসীমাবদ্ধ একটি মান (সেই টেবিলের ধরণ) রাখে। তারপরে, আমরা সুপার-টেবিলের উপ-টেবিলের বিদেশী কীগুলি উভয় uidএবং মিশ্রিতগুলিতে তৈরি করি type। এটা বুদ্ধিমান।
নিক চ্যামাস

5

তাদের নাম দেওয়া হবে

  1. একক টেবিল উত্তরাধিকার
  2. ক্লাস টেবিল উত্তরাধিকার
  3. কংক্রিট টেবিল উত্তরাধিকার

এবং সকলের তাদের বৈধ ব্যবহার রয়েছে এবং কয়েকটি গ্রন্থাগার দ্বারা এটি সমর্থন করে। কোনটি সবচেয়ে উপযুক্ত তা আপনাকে খুঁজে বের করতে হবে।

একাধিক সারণী থাকা আপনার অ্যাপ্লিকেশন কোডে ডেটা ম্যানেজমেন্টকে আরও গ্রহণ করতে পারে তবে অব্যবহৃত স্থানের পরিমাণ হ্রাস করবে।


2
"ভাগ করে নেওয়া প্রাথমিক কী" নামে একটি অতিরিক্ত কৌশল রয়েছে technique এই কৌশলটিতে, সাবক্লাস টেবিলগুলিতে স্বতন্ত্রভাবে নির্ধারিত প্রাথমিক কী আইডি নেই। পরিবর্তে, সাবক্লাস টেবিলগুলির পিকে হ'ল এফকে যা সুপারক্লাসের সারণিকে উল্লেখ করে। এটি বেশ কয়েকটি সুবিধা সরবরাহ করে, মূলত এটি আইএস-এ সম্পর্কের এক-এক-এক প্রকৃতির প্রয়োগ করে। এই কৌশলটি ক্লাস টেবিল উত্তরাধিকার হিসাবে একটি অ্যাড।
ওয়াল্টার মিট্টি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.