বাল্ক সন্নিবেশ এম: পোস্টগ্রিজ এসকিউএল-এ সম্পর্ক


9

আমাকে কিছুটা ভিন্ন কাঠামো সহ একটি পুরানো ডাটাবেস থেকে নতুন একটিতে আমদানি করা দরকার need উদাহরণস্বরূপ, পুরানো ডাটাবেসে, একটি টেবিল রেকর্ডিং কর্মচারী এবং তাদের সুপারভাইজার রয়েছে:

CREATE TABLE employee (ident TEXT PRIMARY KEY, name TEXT, supervisor_name TEXT)

এখন, নতুন ডাটাবেসটি নিম্নরূপ:

CREATE TABLE person (id BIGSERIAL PRIMARY KEY, name TEXT, old_ident TEXT);
CREATE TABLE team (id BIGSERIAL PRIMARY KEY);
CREATE TABLE teammember (person_id BIGINT, team_id BIGINT, role CHAR(1));

তা হ'ল, তাদের সুপারভাইজারদের নাম সহ কর্মচারীদের সরল টেবিলের পরিবর্তে, নতুন (আরও জেনেরিক) ডাটাবেসটি মানুষের দল তৈরি করতে সক্ষম করে। কর্মীরা ভূমিকা সহ সদস্য, ভূমিকা 'e'সহ সুপারভাইজার 's'

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

employee: ('abc01', 'John', 'Dave'), ('abc02', 'Kyle', 'Emily')

হিসাবে স্থানান্তরিত করা হয়

person: (1, 'John', 'abc01'), (2, 'Dave', NULL), (3, 'Kyle', 'abc02'), (4, 'Emily', NULL)
team: (1), (2)
teammember: (1, 1, 'e'), (2, 1, 's'), (3, 2, 'e'), (4, 2, 's')

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

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

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


3
আমি নতুন টেবিলগুলিতে কিছু অস্থায়ী শনাক্তকারী যুক্ত করার পরামর্শ দেব। পুরাতন সংযোগ থাকা অবস্থায় আপনি এইভাবে তাদের মধ্যে ডেটা canোকাতে পারেন - তারপরে আপনি পুরানো টেবিল থেকে প্রয়োজনীয় সারিগুলি আনতে এবং সেগুলি পরবর্তী টেবিলে সন্নিবেশ করতে পারেন can এর জন্য, আমি পৃথক এসকিউএল স্টেটমেন্ট ব্যবহার করব, জটিল সিটিই বা প্রক্রিয়াগত ফাংশনের প্রয়োজন নেই for
dezso

@ ডেজো এই পরামর্শের জন্য ধন্যবাদ। কোনও অস্থায়ী শনাক্তকারী যুক্ত করা teamযাতে কোনও ব্যক্তির আইডি ধারণ করে যার জন্য দলটি তৈরি হয়েছিল তা সমস্যার সমাধান করবে। যদিও এর চেয়ে আরও মার্জিত (অর্থাত্ কোনও ডিডিএল ব্যবহার না করা) সমাধান রয়েছে কিনা তা নিয়ে আমি এখনও আগ্রহী।
ওন্দেজ বৌদা

@ অ্যান্ডেজবৌদা সিটিই কোয়েরি হিসাবে টেবিলগুলি তৈরি করা সম্ভব হতে পারে তবে এটি বেশ জটিল হয়ে উঠতে পারে। (অস্থায়ী) সারণী সমাধানটি আপনাকে উদাহরণস্বরূপ সারি গণনা পরীক্ষা করে পৃথকভাবে পদক্ষেপগুলি পরীক্ষা করার বিলাসিতা দেয়।
dezso

উত্তর:


1

4 টি সন্নিবেশ বিবৃতি সহ পুরাতনটি থেকে নতুন ডাটাবেস তৈরি করার জন্য আপনার প্রয়োজনীয় সমস্ত তথ্য রয়েছে:

create table team_ids (id serial, name TEXT)

insert into team_ids (name)
select distinct supervisor_name from employee

-- now supervisors have ids assigned by "serial" type

insert into person (id, name, old_ident)
select ident, name, ident from employee
union
select ident, supervisor_name, ident from employee

insert into team (id) -- meh
select id from team_ids

insert into teammember (person_id, team_id, role)
select e.ident, t.id, 'e')
from employee as e, join team_ids as t
on t.name = e.supervisor_name
union -- and, I guess
select t.id, t.id, 'm')
from team_ids as t

আপনার স্বাদে সামঞ্জস্য হতে পারে। আমি কর্মী ধরে নিচ্ছি ident এটি বাদে এটি কেবলমাত্র বেসিক এসকিউএল, অভিনব কিছুই নয় এবং অবশ্যই কোনও লুপ নেই।

অতিরিক্ত ভাষ্য:

  • 'দল' টেবিলটি (আরও প্রচলিত) বিভাগে নতুন নামকরণ করা যেতে পারে ।
  • SERIAL(এর 2 বিলিয়ন সম্ভাবনা সহ) প্রচুর পরিমাণে হওয়া উচিত, এর প্রয়োজন নেই BIGSERIAL
  • দলে ম্যানেজারের 1: 1 কার্ডিনালিটি প্রয়োগ করার জন্য কোনও ডাটাবেস ব্যবস্থা নেই বলে মনে হয়। সংজ্ঞা অনুসারে প্রত্যেক দলের কি নেতার দরকার নেই? টিম মেম্বার.রোলে কোনও বাধা CHECKবা FOREIGN KEYবাঁধা নেই? সম্ভবত প্রশ্নটি এই বিবরণগুলি সরল করে দিয়েছে।
  • "টিম মেম্বার" টেবিলের নামটিতে প্রচলিতভাবে একটি শব্দের সীমানা থাকতে পারে, উদাহরণস্বরূপ TeamMember বা Team_member।

1
এইভাবে আপনার personটেবিলে সদৃশ আইডি থাকবে ।
ডিজেসো

0

PL / PgSQL কাজটি করবে।

DO $$
DECLARE
  _e record;
  _personid bigint;
  _suppersonid bigint;
  _teamid bigint;
BEGIN
  FOR _e IN
    SELECT ident, name, supervisor_name FROM employee
  LOOP
    -- insert person record for employee
    INSERT INTO person (name, old_ident)
      SELECT _e.name, _e.ident
      RETURNING id INTO _personid;
    -- lookup or insert person record for supervisor
    SELECT id INTO _suppersonid FROM person
      WHERE p.name = _e.supervisor_name;
    IF _suppersonid IS NULL THEN
      INSERT INTO person (name) SELECT _e.supervisor_name
        RETURNING id INTO _suppersonid;
    END IF;
    -- lookup team by supervisor or insert new team
    SELECT team_id INTO _teamid FROM teammember tm
      WHERE tm.person_id = _suppersonid AND tm.role = 's';
    IF _teamid IS NULL THEN
      -- new supervisor: insert new team and supervisor
      INSERT INTO team (id) VALUES(DEFAULT) RETURNING id INTO _teamid;
      INSERT INTO teammember (person_id, team_id, role) SELECT _suppersonid, _teamid, 's';
    END IF;
    -- insert team member (non-supervisor) record
    INSERT INTO teammember (person_id, team_id, role) SELECT _personid, _teamid, 'e';
  END LOOP;
END; $$;
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.