বন্ধুত্বের জন্য আমার কীভাবে সম্পর্কের টেবিলটি ডিজাইন করা উচিত?


33

যদি Aতার বন্ধু হয় B, তবে আমি উভয় মান সংরক্ষণ করতে হবে ABএবং BA, বা একটি যথেষ্ট? উভয় পদ্ধতির সুবিধা এবং অসুবিধাগুলি কী কী।

এখানে আমার পর্যবেক্ষণ:

  • যদি আমি উভয় রাখি তবে কোনও বন্ধুর কাছ থেকে অনুরোধ পেলে আমাকে উভয় আপডেট করতে হবে।
  • আমি যদি উভয়ই রাখি না, তবে JOINএই টেবিলটি দিয়ে একাধিক করার সময় আমি অসুবিধা পেয়েছি ।

বর্তমানে আমি সম্পর্কটিকে একপথে রাখি।

এখানে চিত্র বর্ণনা লিখুন

তাহলে এই ক্ষেত্রে আমার কী করা উচিত? কোন পরামর্শ?


আপনি কি প্ল্যাটফর্মের প্রতি প্রতিশ্রুতিবদ্ধ, বা এটি একটি তাত্ত্বিক প্রশ্ন?
নিক চামাস

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

@ মাফানোয়েহেন - হ্যাঁ, গ্রাফের ডাটাবেসের জন্য আরও উপযুক্ত মনে হচ্ছে ।
নিক চামাস

@ নিকচ্যামাস: এটি তাত্ত্বিক প্রশ্ন নয়। আমি কাজ করছি mysqlযা আমাজনের মেঘে সঞ্চিত আছে।
চ্যান

1
@ চ্যান - আহ এর অর্থ এই যে আপনি সম্পর্ক প্রয়োগের জন্য চেক সীমাবদ্ধতাগুলি ব্যবহার করতে পারবেন না কেবল তখনই একটি উপায় সংরক্ষণ করা হয় (মাইএসকিউএল এগুলি প্রয়োগ করে না)
মার্টিন স্মিথ

উত্তর:


30

আমি এবি এবং বিএ সঞ্চয় করতাম। একটি বন্ধুত্ব সত্যিই একটি দ্বিপথ সম্পর্ক, প্রতিটি সত্তা অন্য জড়িত। যদিও স্বজ্ঞাতভাবে আমরা "বন্ধুত্বকে" দু'জনের মধ্যে একটি যোগসূত্র হিসাবে ভাবি, আপেক্ষিক দিক থেকে এটি "এ এর একটি বন্ধু বি আছে" এবং "বি একটি বন্ধু আছে এ" এর মতোই। দুটি সম্পর্ক, দুটি রেকর্ড।


3
অনেক ধন্যবাদ. আমি আপনার ধারণা সম্পর্কে সাবধানে চিন্তা করা প্রয়োজন! আমি এবি এবং বিএ সংরক্ষণ করা এড়ানোর কারণটি হ'ল স্টোরেজ, যেহেতু প্রতিবার আমার বন্ধুত্ব হয়, আমার টেবিল দ্বিগুণ হয়ে যায়।
চ্যান

1
আপনি স্টোরেজ সম্পর্কে ঠিক বলেছেন, তবে মনে রাখবেন যে যদি পূর্ণসংখ্যার হিসাবে সংরক্ষণ করা হয় তবে প্রতিটি বন্ধু-বান্ধব সম্পর্কের জন্য প্রায় 30 টি বাইস লাগবে (2 রেকর্ড এক্স 3 কলামে 4 4 বাইট প্রতি পূর্ণসংখ্যার = 24 বাইট এবং কিছু প্যাডিং)। 10 জন লোকের সাথে 1 মিলিয়ন লোক এখনও প্রায় 300MB ডেটা থাকবে।
ডেটাগোড

1
ডাটাগোড: ঠিক!
চ্যান

আমার টেবিলগুলিও ঠিক এভাবেই ডিজাইন করেছিলাম, এবি এবং বিএ।
kabuto178

2
এছাড়াও, এমন পরিস্থিতিতে যেখানে কেবল AB নেই এবং বিএ নয়, এটি 'মুলতুবি বন্ধুত্বের অনুরোধ' উপস্থাপন করতে পারে।
গ্রেগ

13

বন্ধুত্ব প্রতিসম হতে উদ্দেশ্যে করা হয়, তাহলে (অর্থাত এটা সম্ভব নয় A বন্ধুদের সাথে থাকতে Bতাহলে আমি ঠিক নিশ্চিত প্রতিটি সম্পর্ক শুধুমাত্র একটি উপায় প্রতিনিধিত্ব করা যাবে একটি চেক বাধ্যতা সঙ্গে ওয়ান ওয়ে সম্পর্ক সংরক্ষণ করবে কিন্তু বিপরীতভাবে)।

এছাড়াও আমি সারোগেট আইডিটি খনন করব এবং তার পরিবর্তে একটি সংমিশ্রিত পিকে (এবং সম্ভবত বিপরীত কলামগুলিতে একটি যৌগিক অনন্য সূচক) রাখতে পারি।

CREATE TABLE Friends
  (
     UserID1 INT NOT NULL REFERENCES Users(UserID),
     UserID2 INT NOT NULL REFERENCES Users(UserID),
     CONSTRAINT CheckOneWay CHECK (UserID1 < UserID2),
     CONSTRAINT PK_Friends_UserID1_UserID2 PRIMARY KEY (UserID1, UserID2),
     CONSTRAINT UQ_Friends_UserID2_UserID1 UNIQUE (UserID2, UserID1)
  ) 

আপনি যে প্রশ্নগুলি এটি কঠিন করে তোলে তা আপনি বলবেন না তবে আপনি সর্বদা একটি দৃশ্য তৈরি করতে পারেন

CREATE VIEW Foo
AS
SELECT UserID1,UserID2 
FROM Friends
UNION ALL
SELECT UserID2,UserID1 
FROM Friends

আমি জানি এটি বেশ পুরানো, তাই এটি খননের জন্য দুঃখিত sorry অপ্রয়োজনীয় এবং অপ্রয়োজনীয় অতিরিক্ত বোঝা চাপ না দেওয়ার জন্য, বিপরীত বন্ধুত্ব সূচকটি সংজ্ঞায়িত না করাই কি ভাল হবে ? যেহেতু আমরা আছে এবং যেহেতু একটি পি কে হয় , বিপরীত হয় কোন ব্যাপার কি। UNIQUEINSERTPRIMARY KEY (a,b)UNIQUEKEY (b,a)UNIQUE
tfrommen

1
@tf অনুমান যা কোয়েরি অপটিমাইজারের উপর নির্ভর করে। আপনি চিহ্নিত হিসাবে এটি কেবল একপথে চেক করা প্রয়োজন তাই সন্নিবেশ পরিকল্পনাটি যেভাবেই এটি করতে পারে। প্রশ্নটি মাইএসকিউএল ট্যাগ করা হয়েছে - এটি কীভাবে আচরণ করে তা কোনও ধারণা নেই।
মার্টিন স্মিথ

আমি জানি এটি একটি পুরানো উত্তর, তবে আমি এই ঘটনায় যে কাউকেই হোঁচট খাচ্ছি বলে ইঙ্গিত করতে চাই যে মাইএসকিউএল চেক সীমাবদ্ধতাগুলি পুরোপুরি উপেক্ষা করে (যদিও এটি তাদের সফলভাবে "পার্স" করবে) সুতরাং এই পদ্ধতির সম্ভবত সেই প্রযুক্তিটি নিয়ে যাওয়ার উপায় নয়।
মীখা

@ মিকাহ সত্য আমি 2012 সালে এটি সম্পর্কে অবগত ছিলাম না Still এখনও অন্য ডিবিএমএসগুলিতে কাজ করব ...
মার্টিন স্মিথ

এর জন্য একটি ভিউ বাস্তবায়নের জন্য +1। এবি এবং বিএ সংরক্ষণ করা অসঙ্গতি এনেছে (যদি সম্পর্ক দ্বি-দিকনির্দেশক না হয়) তবে এই পদ্ধতিটি আরও ভাল পদ্ধতির
imans77

7

একটি "বন্ধুত্ব" সর্বদা দ্বি-দ্বি / পারস্পরিক বলে ধরে নেওয়া, আমি সম্ভবত এটির মতো কিছু পরিচালনা করব।

CREATE TABLE person (
    person_id int IDENTITY(1,1) PRIMARY KEY,
    ...other columns...
)

CREATE TABLE friendship (
    friendship_id int IDENTITY(1,1) PRIMARY KEY,
    ...other columns, if any...
)

CREATE TABLE person_friendship (
    person_id int NOT NULL,
    friendship_id int NOT NULL
    PRIMARY KEY (person_id, friendship_id)
)

ফলাফলটি হ'ল আপনি একে একে "বহু লোক" থেকে "ব্যক্তি" থেকে "ব্যক্তি" থেকে "বন্ধুত্ব" করার জন্য বহু লোকের যোগ দিতে পরিবর্তন করেছেন। এটি যোগ দেয় এবং বাধাগুলি সরল করে দেবে, তবে একক "বন্ধুত্বের" ক্ষেত্রে দু'জনের বেশি লোককে অনুমতি দেওয়ার পার্শ্ব প্রতিক্রিয়া রয়েছে (যদিও অতিরিক্ত নমনীয়তা সম্ভাব্য সুবিধা হতে পারে)।


এটি মূলত একটি গ্রুপ / সদস্যপদ প্যাটার্ন। আকর্ষণীয় ধারণা, যদিও।
einSelbst

4

আপনার সারি সংখ্যা দ্বিগুণ করার পরিবর্তে বন্ধুত্বের আশপাশে সূচকগুলি সংজ্ঞায়িত করতে হতে পারে:

CREATE TABLE person
(
    person_id INT NOT NULL AUTO_INCREMENT,
    ...
    PRIMARY KEY (person_id)
);
CREATE TABLE friendship
(
    friend_of INT NOT NULL,
    friend_to INT NOT NULL,
    PRIMARY KEY (friend_of,friend_to),
    UNIQUE KEY friend_to (friend_to,friend_of)
);

এইভাবে, আপনি সূচীর জন্য সঞ্চয় দ্বিগুণ করেছেন তবে টেবিলের ডেটার জন্য নয়। ফলস্বরূপ, ডিস্কস্পেসে এটি 25% সঞ্চয় হওয়া উচিত। মাইএসকিউএল ক্যোয়ারী অপটিমাইজার কেবল সূচক পরিসীমা স্ক্যানগুলি সম্পাদন করতে পছন্দ করবে, এজন্য সূচকগুলি coveringেকে দেওয়ার ধারণাটি এখানে ভাল কাজ করে।

কভারিং সূচকগুলির কয়েকটি সুন্দর লিঙ্ক এখানে দেওয়া হয়েছে:

বিচারকার্য স্থগিত রাখার আদেশ

বন্ধুত্ব যদি পারস্পরিক না হয় তবে অন্য ধরণের সম্পর্কের ভিত্তি আপনার রয়েছে: অনুসরণ করুন

বন্ধু_ও যদি বন্ধুত্বের বন্ধু না হয়, আপনি কেবল সেই সম্পর্কটিকে টেবিলের বাইরে রেখে যেতে পারেন।

আপনি যদি সমস্ত ধরণের সম্পর্কের জন্য সংজ্ঞা দিতে চান তবে তা পারস্পরিক হোক বা না হোক, আপনি সম্ভবত নিম্নলিখিত টেবিল বিন্যাসটি ব্যবহার করতে পারেন:

CREATE TABLE person
(
    person_id INT NOT NULL AUTO_INCREMENT,
    ...
    PRIMARY KEY (person_id)
);
CREATE TABLE relationship
(
    rel_id INT NOT NULL AUTO_INCREMENT,
    person_id1 INT NOT NULL,
    person_id2 INT NOT NULL,
    reltype_id TINYINT,
    PRIMARY KEY (rel_id),
    UNIQUE KEY outer_affinity (reltype_id,person_id1,person_id2),
    UNIQUE KEY inner_affinity (reltype_id,person_id2,person_id1),
    KEY has_relationship_to (person1_id,reltype_id),
    KEY has_relationship_by (person2_id,reltype_id)
);
CREATE TABLE relation
(
    reltype_id TINYINT NOT NULL AUTO_INCREMENT,
    rel_name VARCHAR(20),
    PRIMARY KEY (reltype_id),
    UNIQUE KEY (rel_name)
);
INSERT INTO relation (relation_name) VALUES
('friend'),('follower'),('foe'),
('forgotabout'),('forsaken'),('fixed');

সম্পর্কের টেবিল থেকে, আপনি নিম্নলিখিতগুলি অন্তর্ভুক্ত করার জন্য সম্পর্কের ব্যবস্থা করতে পারেন:

  • বন্ধুদের পারস্পরিক হতে হবে
  • শত্রুরা পারস্পরিক হতে পারে বা নাও হতে পারে
  • অনুসারীরা পারস্পরিক হতে পারে বা নাও হতে পারে
  • অন্যান্য সম্পর্কগুলি ব্যাখ্যার সাপেক্ষে (ভুলে যাওয়া বা ত্যাগ করা বা প্রতিশোধ গ্রহণকারী দ্বারা নির্ধারিত)
  • পসিবির সম্পর্ক আরও বাড়ানো যেতে পারে

সম্পর্কটি পারস্পরিক হোক বা না হোক, সমস্ত সম্পর্কের ক্ষেত্রে এটি আরও দৃust় হওয়া উচিত।


হাই @rolandomysqldba, আমি আপনার উত্তরগুলির বড় অনুরাগী। এটি আমার পক্ষে সত্যই সহায়ক (এই ক্ষেত্রে প্রথম উদাহরণ)) এখন এখানে আমার জন্য একটি সাবধানবাণী, আমি চাই অনন্য সম্পর্ক। (উদাহরণস্বরূপ, যদি ব্যবহারকারী বি এর সাথে বন্ধু হয় তবে এ এর ​​সাথে বি বন্ধু গ্রহণযোগ্য নয়)) ট্রিগার দিয়ে আমার কি করা উচিত? এবং অভিনয় সম্পর্কে কি? কারণ আমার কাছে খুব বিশাল টেবিল রয়েছে (প্রায় 1 মিলিয়ন রেকর্ডস), এবং যদি আমি ব্যবহারকারীর এ এর ​​বন্ধুদের অনুসন্ধান করতে পারি (এ দুটি উভয় ক্ষেত্রে (ফ্রেন্ড_ফ, ফ্রেন্ড_টো)) এবং মাইএসকিএল কেবল একটি সূচক ব্যবহার করে থাকে তবে এটি খুব ধীর গতিতে চলছে। আমাকে অবশ্যই আমার টেবিলে সদৃশ এন্ট্রিগুলি সংরক্ষণ করতে হবে (উদাঃ- এ-> বি, বি-> এ) betterএর থেকে আরও ভাল বিকল্প?
মনীষ স্বপ্নাল

1

আপনি যদি অ্যাপ্লিকেশনটির মধ্যে নিয়ন্ত্রণ করতে পারেন যে এ এর ​​আইডি সর্বদা বি এর আইডির চেয়ে কম থাকে (A, B উপাদানগুলির পূর্বে অর্ডার দিন) আপনি কোনও ওআর ছাড়াই জিজ্ঞাসা করতে পারেন (যেখানে id_A = a এবং id_B = b জিজ্ঞাসা না করে (আইডি_এ = এ এবং আইডি_বি = বি) বা (আইডি_এ = বি এবং আইডি_বি = ক)) এবং অপরের আনুমানিকতার সাথে আপনার যে রেকর্ডের প্রয়োজন হবে তার অর্ধেক রক্ষণাবেক্ষণ করুন। তারপরে সম্পর্কের অবস্থা বজায় রাখতে আপনার অন্য ক্ষেত্রটি ব্যবহার করা উচিত (হ'ল বন্ধুরা, একটি-চাওয়া-বি-বি, বি-সলিসিটেড-টু-এ, প্রেমিক-ক, বন্ধু-খ) এবং আপনার কাজ শেষ হয়েছে s

এইভাবে আমি আমার বন্ধুত্ব ব্যবস্থাটি পরিচালনা করেছি এবং এটি সিস্টেমকে সহজ করে তোলে এবং আপনার অন্যান্য সিস্টেমগুলির সাথে আপনার অর্ধেক সারি ব্যবহার করতে হবে, কেবল এ বলা কোডের নীচের আইডি মানের সমান।

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