ইতিমধ্যে বিদ্যমান সারণীতে বিদেশী কী বাধা সহ একটি কলাম কীভাবে যুক্ত করবেন?


11

আমার কাছে নিম্নলিখিত সারণী রয়েছে,

CREATE TABLE users (id int PRIMARY KEY);

-- already exists with data
CREATE TABLE message ();

আমি কীভাবে এমন messagesটেবিল পরিবর্তন করব ,

  1. নামক একটি নতুন কলাম এতে senderযুক্ত হয়
  2. যেখানে senderএকটি বিদেশী কী উল্লেখ করছে usersটেবিল

এটি কাজ করে না

# ALTER TABLE message ADD FOREIGN KEY (sender) REFERENCES users;
ERROR:  column "sender" referenced in foreign key constraint does not exist

এই বিবৃতিটি কলামটিও তৈরি করে না?


3
আপনার কলামটি উল্লেখ করার আগে আপনাকে এটি তৈরি করতে হবে। আমি এখানে অল্টার টেবিলের জন্য ডকুমেন্টেশনগুলিও পড়তে চেষ্টা করব এবং উদাহরণগুলিতে খুব মনোযোগ দিয়েছি pay
ক্যাসানড্রি

হাসান, আমি ডিডিএল ব্যবহার করার জন্য এই প্রশ্নটি পরিষ্কার করে দিয়েছি এবং যে জিনিসগুলি কাজ করছে না তা সরিয়েছি। এই প্রশ্নের উত্তর দেয় কিনা দেখুন: dba.stackexchange.com/a/202564/2639 । এই সম্পাদনাগুলির যে কোনও একটি অস্বীকার করতে নির্দ্বিধায়, আমি কেবল উত্তরসূরির জন্য এটি পরিষ্কার করতে চেয়েছিলাম।
ইভান ক্যারল

উত্তর:


18

তুলনামূলকভাবে সহজ কী - আপনাকে কেবল আরও একটি পদক্ষেপ যুক্ত করতে হবে।

FOREIGN KEYকলাম অস্তিত্ব রয়েছে যাতে এটা একটি করার জন্য FK। আমি নিম্নলিখিতগুলি ( এখানে এবং ডকুমেন্টেশন থেকে ) করেছি:

CREATE TABLE x(t INT PRIMARY KEY);

CREATE TABLE y(s INT);

ALTER TABLE y ADD COLUMN z INT;    

ALTER TABLE y
  ADD CONSTRAINT y_x_fkey FOREIGN KEY (z)
      REFERENCES x (t)
      ON UPDATE CASCADE ON DELETE CASCADE;

কয়েকটি বিষয় লক্ষ্য করুন:

সর্বদা আপনার বিদেশী কীগুলি অর্থপূর্ণ নাম দেয়। "SYS_C00308108" কীটি লঙ্ঘন করা হচ্ছে তা বলা খুব বেশি কার্যকর নয়। এই পরিস্থিতিতে ওরাকল এর আচরণের জন্য এখানে ফ্রেডটি দেখুন মূল নামটি ফিডল থেকে আলাদা হয়ে যায় তবে এটি কিছুটা নির্বিচারে স্ট্রিং যা SYS _... দিয়ে শুরু হয়)

আপনার বক্তব্য বিবেচনা:

ALTER TABLE message ADD FOREIGN KEY (sender) REFERENCES users;

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

কমপক্ষে পোস্টগ্রাইএসকিউএল যুক্তিসঙ্গত কিছু করার চেষ্টা করে - এটি টেবিলের নাম, FOREIGN KEYক্ষেত্রের নাম _fkeyএবং এমনকি DETAIL: Key (sender_id)=(56) is not present in table "user_".কিছু এমন কিছু দেয় যা মানুষের কাছে বোধগম্য হতে পারে - এখানে ফ্রেড দেখুন ।


2
আমি আমার বিদেশী চাবিগুলির নাম রাখি না। তারা স্বায়ত্তশাসিত হয় এবং এগুলি সাধারণত বেশ কার্যকর। উদাহরণস্বরূপ, সেই প্রসঙ্গে ডিফল্ট নাম "y_z_fkey"। আমি যে চেয়ে ভাল নাম তর্ক করা চাই y_x_fkey, কারণ আপনার লঙ্ঘন কি তোমাদেরকে বলিনি নেই কলাম তুমি ঢোকাতে মধ্যে যে ত্রুটি ঘটাচ্ছে না। এটি কোথায় ইশারা করছে সে সম্পর্কে আমি কম যত্ন করি। একটি সাধারণ নিয়ম হিসাবে, আপনার নিজের fkeys নাম কখনও করা উচিত নয় এবং PostgreSQL এর ডিফল্ট এটি পরিচালনা করতে দেয়।
ইভান ক্যারল

এছাড়াও, আপনি ON UPDATE CASCADE ON DELETE CASCADE;কোনও উদাহরণের ডিফল্টগুলিকে ওভাররাইড করতে নাও চান , বিশেষত কারণ ছাড়াই। এটি উদাহরণটিকে আরও জটিল করে তুলেছে এবং আপনি এটি কী তা ব্যাখ্যা করে বিরক্ত করবেন না। আমি একজনের পক্ষে সাধারণত ক্যাসকেডে মুছতে চাই না।
ইভান ক্যারল

1
সংস্থা / প্রকল্প সিদ্ধান্ত নিয়েছে যে কনভেনশন অনুসারে আমি সর্বদা এফকে নাম রাখি। এটা কোন ব্যাপার অনেক যদি তা না হয় না y_x_fkeyবা y_z_fkeyবা x__y_FK, যতদিন এটা সামঞ্জস্যপূর্ণ হিসাবে।
ypercubeᵀᴹ

যদি আপনি চুক্তি করে থাকেন তবে আমি এটির সাথে একমত হতে চাই - একটি কনভেনশন বাছাই করুন এবং এটির সাথে লেগে থাকুন এবং / অথবা নিশ্চিত হয়ে নিন যে আপনি পূর্বে সিস্টেমের সাথে / ব্যবহৃত কনভেনশন (গুলি) মেনে চলছিলেন।
ভ্রেস

@ ইভানক্রোল - যদি পোস্টগ্রিসএসকিউএল এর কনভেনশনটি প্রকল্পটি হয় বা পোস্টগ্র্রেএসকিউএল নাও হতে পারে এমন কোনও সিস্টেমের আগে সিদ্ধান্ত নিয়েছে - কোনও সিস্টেম ভালভাবে শুরু হয়ে গেছে, বলুন, ওরাকল বা অন্য সিস্টেমের পোস্টগ্র্রেএসকিউএল এর কনভেনশন (গুলি) নাও থাকতে পারে। আপনি তর্ক করতে পারেন যে x_y_z_fk একটি ত্রুটি ঘটলে সর্বাধিক সম্ভাব্য তথ্য দিতে পারে! কিছু এবং চয়ন করুন লাঠি (তা সে যত ভাল) আপনার জন্য নিয়মাবলী সিদ্ধান্ত নেন আমার নীতিবাক্য হল এটি, কিন্তু এক RDBMS দেবেন না!
ভেরেস

8

আমি নিশ্চিত না যে কেন সবাই আপনাকে বলছে যে আপনাকে এটি দুটি পদক্ষেপে করতে হবে। আসলে, আপনি না । আপনি একটি যুক্ত করার চেষ্টা করেছিলেন FOREIGN KEYযা অনুমান করে, নকশা করে কলামটি সেখানে রয়েছে এবং কলামটি না থাকলে ত্রুটিটি ছুঁড়ে ফেলেছে। আপনি যদি যোগ করেন তবে COLUMNআপনি স্পষ্ট করে এটিকে FOREIGN KEYতৈরির সাথে এটি তৈরি করতে পারবেন REFERENCES,

ALTER TABLE message
  ADD COLUMN sender INT
  REFERENCES users;  -- or REFERENCES table(unique_column)

ভাল কাজ করবে। আপনি এখানে সিনট্যাক্স দেখতে পারেন ,ALTER TABLE

ALTER TABLE [ IF EXISTS ] [ ONLY ] name [ * ]
action [, ... ]

সঙ্গে "ACTION" হিসাবে,

ADD [ COLUMN ] [ IF NOT EXISTS ] column_name data_type [ COLLATE collation ] [ column_constraint [ ... ] ]

এই উদাহরণগুলি ডক্সেও রয়েছে,

ALTER TABLE distributors
  ADD CONSTRAINT distfk
  FOREIGN KEY (address)
  REFERENCES addresses (address);

ALTER TABLE distributors
  ADD CONSTRAINT distfk
  FOREIGN KEY (address)
  REFERENCES addresses (address)
  NOT VALID;

তবে এগুলি প্রয়োজনীয় নয় কারণ আমরা স্বায়ত্তশাসন এবং প্রাথমিক-কী রেজোলিউশনে নির্ভর করতে পারি (যদি কেবল সারণীর নাম নির্দিষ্ট করা থাকে তবে আপনি প্রাথমিক কীটি উল্লেখ করছেন)।


0

CASE1: নতুন টেবিল তৈরি করার সময় আপনার যদি বিদেশী কী তৈরি করতে হয়

CREATE TABLE table1(
id SERIAL PRIMARY KEY,
column1 varchar(n) NOT NULL,
table2_id SMALLINT REFERENCES table2(id)
); 

উপরের কমান্ডগুলি 'টেবিল 1' এবং 'আইডি' (প্রাথমিক কী) নামের তিনটি কলাম, 'কলাম 1', 'টেবিল 2_আইডি' (টেবিল 2 এর আইডি কলামের উল্লেখ করে যে টেবিল 1 এর বিদেশী কী) নামের একটি সারণী তৈরি করবে।

DATATYPE 'সিরিয়াল' কলামটি তৈরি করবে যা এই ডেটাটাইপটি একটি স্বয়ংক্রিয়ভাবে উত্পাদিত কলাম হিসাবে ব্যবহার করবে, যখন সারণীতে মান সন্নিবেশ করানোর সময় আপনার এই কলামটি উল্লেখ করার দরকার নেই, বা আপনি মান স্থানে উদ্ধৃতি ছাড়াই 'ডিফল্ট' দিতে পারেন।

একটি প্রাথমিক কী কলামটি সর্বদা সারণীর সূচীতে 'টেবিলের নাম_পকি' যুক্ত থাকে।

যদি টেবিল তৈরির সময় বিদেশী কী যুক্ত করা হয় তবে '(বর্তমান_সারণযোগ্য_নাম) _ (বিদেশী_কি_আইডি_নাম) _ফকি' প্যাটার্ন সহ একটি চুক্তি যুক্ত করা হয়।

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

CASE 2: আপনি যদি বিদ্যমান কলামে বিদ্যমান সারণীতে বিদেশী কী চান

ALTER TABLE table1
ADD CONSTRAINT table1_table2_id_id_fkey
FOREIGN KEY (table2_id) REFERENCES table2(id);

দ্রষ্টব্য: বন্ধনী '()' বিদেশী কী এবং রেফারেন্সগুলির পরে টেবিল 2 বাধ্যতামূলক বা অন্যথায় পোস্টগ্রাস ত্রুটি ছুঁড়ে দেবে।


0

আমি সমস্যা জানি। কলামের নাম আলাদা। সম্ভবত একটি কলামে, আপনার কলামের নামের পরে একটি যুক্ত স্থান রয়েছে, তাই দয়া করে সাবধানতার সাথে নিশ্চিত করুন যে আপনার কলামের নামগুলি ঠিক একই নামকরণ করা হয়েছিল।


1
ওপিকে জিজ্ঞাসা করা হয়েছিল: এই বিবৃতিটি কলামটিও তৈরি করে না? সুতরাং এটি স্পষ্ট যে তিনি প্রত্যাশা করেছিলেন যে তা ঘটবে।
লরেঞ্জ আলবে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.