ডাটাবেস ডিজাইন: কীভাবে "সংরক্ষণাগার" সমস্যাটি পরিচালনা করবেন?


18

আমি নিশ্চিত যে প্রচুর অ্যাপ্লিকেশন, সমালোচনামূলক অ্যাপ্লিকেশন, ব্যাংক এবং প্রতিদিনের ভিত্তিতে এটি করে।

তার পিছনে ধারণাটি হ'ল:

  • সমস্ত সারি একটি ইতিহাস থাকতে হবে
  • সমস্ত লিঙ্ক সুসংগত থাকতে হবে
  • "বর্তমান" কলামগুলি পেতে অনুরোধ করা সহজ হওয়া উচিত
  • অপ্রচলিত জিনিস কিনেছে এমন ক্লায়েন্টদের এখনও এই পণ্যটি ক্যাটালগের অংশ না হলেও তারা কী কিনেছিল তা দেখতে হবে

ইত্যাদি।

আমি যা করতে চাই তা এখানেই রয়েছে এবং আমি যে সমস্যার মুখোমুখি হচ্ছি তা ব্যাখ্যা করব।

আমার সমস্ত টেবিলে সেই কলামগুলি থাকবে:

  • id
  • id_origin
  • date of creation
  • start date of validity
  • start end of validity

এবং এখানে সিআরইউডি অপারেশন সম্পর্কিত ধারণা রয়েছে:

  • id_origin= id, date of creation= এখন, start date of validity= এখন, end date of validity= নাল (= এর অর্থ এটি বর্তমান সক্রিয় রেকর্ড) দিয়ে নতুন সারিটি সন্নিবেশ করান
  • আপডেট =
    • end date of validity== নাল দিয়ে সমস্ত রেকর্ড পড়ুন
    • এখনই "বর্তমান" রেকর্ড end date of validity= নাল সাথে আপডেট করুনend date of validity
    • নতুন মান সহ একটি নতুন তৈরি করুন এবং end date of validity= নাল (= এর অর্থ এটি বর্তমান সক্রিয় রেকর্ড)
  • মুছে ফেলুন = "বর্তমান" রেকর্ডটি আপডেট করুন = এখন = end date of validityসাথে নালend date of validity

সুতরাং এখানে আমার সমস্যা: বহু থেকে বহু সংঘের সাথে। মানগুলির সাথে একটি উদাহরণ নেওয়া যাক:

  • সারণি এ (আইডি = 1, আইডি_রিগিন = 1, শুরু = এখন, শেষ = নাল)
  • সারণী এ_বি (এখনই শুরু = শেষ, নাল, আইডি_এ = 1, আইডি_বি = 48)
  • সারণি বি (id = 48, id_origin = 48, শুরু = এখন, শেষ = নাল)

এখন আমি টেবিল এ আপডেট করতে চাই, আইডি = 1 রেকর্ড করুন

  • আমি এখন = শেষের সাথে রেকর্ড আইডি = 1 চিহ্নিত করি
  • আমি টেবিল এ এবং ... একটি নতুন মান সন্নিবেশ করলাম যদি আমি সম্পর্কটিকে নকল না করি তবে আমি আমার সম্পর্ক এ_বি হারিয়ে ফেলেছি ... এটি কোনও টেবিলে শেষ হবে:

  • সারণি এ (আইডি = 1, আইডি_রিগিন = 1, শুরু = এখন, শেষ = এখন + 8 মিলিয়ন)

  • সারণি এ (আইডি = 2, আইডি_রিগিন = 1, শুরু = এখন +8 মিলিয়ন, শেষ = নাল)
  • সারণী এ_বি (এখনই শুরু = শেষ, নাল, আইডি_এ = 1, আইডি_বি = 48)
  • সারণী এ_বি (এখনই শুরু = শেষ, নাল, আইডি_এ = 2, আইডি_বি = 48)
  • সারণি বি (id = 48, id_origin = 48, শুরু = এখন, শেষ = নাল)

এবং ... ভাল আমার আর একটি সমস্যা আছে: সম্পর্ক A_B: আমি কি (আইডি_এ = 1, আইডি_বি = 48) অপ্রচলিত হিসাবে চিহ্নিত করব বা না (এ - আইডি = 1 অপ্রচলিত, তবে বি - 48 নয়)?

কিভাবে এটি মোকাবেলা?

আমাকে এটি একটি বড় আকারে ডিজাইন করতে হবে: পণ্য, অংশীদার এবং আরও অনেক কিছু।

এ সম্পর্কে আপনার অভিজ্ঞতা কী? আপনি কীভাবে করবেন (আপনি কীভাবে করেছেন)?

- সম্পাদনা করুন

আমি এই খুব আকর্ষণীয় নিবন্ধটি পেয়েছি , তবে এটি "ক্যাসকেডিং অপ্রচলতা" (= আমি আসলে যা বলছি) সাথে সঠিকভাবে মোকাবেলা করে না


ইতিহাসের লিঙ্কিত তালিকাকে id_hist_prev ক্ষেত্রের সাথে রেখে নতুন আইডি দিয়ে নতুন করে আপডেট করার আগে আপডেট করার রেকর্ডের ডেটা অনুলিপি করার বিষয়ে কীভাবে। সুতরাং বর্তমান রেকর্ডের আইডি কখনই পরিবর্তিত হয় না

বরং যে চাকাটি পুনরায় উদ্ভাবন করছে, আপনি কী ওড়াকলে ফ্ল্যাশব্যাক ডেটা সংরক্ষণাগার ব্যবহারের কথা বিবেচনা করেছেন ?
জ্যাক ডগলাস

উত্তর:


4

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

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

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

আছে HTH।


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

1
বেশিরভাগ ডাটাবেসে আমি ডিজাইন করি সমস্ত 'প্রধান' টেবিলের মতো পণ্যের নামের একটি উপসর্গ থাকে LP_এবং প্রতিটি গুরুত্বপূর্ণ টেবিলের সমতুল্য থাকে LH_, সন্নিবেশ, আপডেট, মোছার ক্ষেত্রে ট্রিগারগুলি historicalতিহাসিক সারি সন্নিবেশ করে। এটি সমস্ত ক্ষেত্রে কাজ করে না তবে এটি আমি করি তার জন্য এটি একটি দৃ model় মডেল।

আমি সম্মত হই - যদি বেশিরভাগ ক্যোয়ারীগুলি "বর্তমান" সারিগুলির জন্য হয় তবে আপনি সম্ভবত ইতিহাস থেকে দুটি সারণীতে বিভাজন করে পারফেক্ট সুবিধা পাবেন। একটি দৃশ্য তাদের সুবিধার্থে একত্রিত করতে পারে। এই পদ্ধতিতে বর্তমান সারিগুলির সাথে ডেটা পৃষ্ঠাগুলি সমস্ত একসাথে রয়েছে এবং সম্ভবত আরও ভাল ক্যাশে থাকতে হবে এবং আপনাকে তারিখের যুক্তি সহ বর্তমান ডেটার জন্য ক্রমাগত কোয়ালিফাই করতে হবে না।
onupdatecascade

1
@ ইউনুপডেটেক্যাসেকেড: নোট করুন (কমপক্ষে কিছু আরডিবিএমএসে) আপনি সেই UNIONদৃশ্যে সূচকগুলি রাখতে পারেন , যা আপনাকে শীতল জিনিসগুলি যেমন বর্তমান এবং historicalতিহাসিক উভয় রেকর্ড জুড়েই একটি অনন্য বাধা প্রয়োগ করতে দেয়।
সমস্ত ট্রেডের

৫ বছর পরে, আমি প্রচুর জিনিস করেছি এবং আমি আপনার ধারণাটি ফিরে পেয়েছি। আমি কেবল পরিবর্তন করেছি যে ইতিহাসের টেবিলগুলিতে আমার একটি কলাম " id" এবং " id_ref" রয়েছে। id_refসারণীর আসল ধারণার একটি রেফারেন্স। উদাহরণ: personএবং person_h। মধ্যে person_hআমি "আছে id", এবং " id_ref" কোথায় id_ref'সঙ্গে সম্পর্কযুক্ত person.id' তাই আমি একই সাথে অনেক সারি থাকতে পারে person.id(= একজন সারি যখন personরুপান্তরিত করা হয়েছে) এবং সমস্ত id'আমার সব টেবিল গুলি autoinc হয়।
অলিভিয়ার পন্স

2

এটি কার্যকরী প্রোগ্রামিংয়ের সাথে কিছুটা ওভারল্যাপ রয়েছে; বিশেষত অপরিবর্তনীয়তা ধারণা।

আপনার কাছে একটি টেবিল রয়েছে PRODUCTএবং অন্যটি কল PRODUCTVERSIONবা অনুরূপ। আপনি যখন কোনও পণ্য পরিবর্তন করেন আপনি কোনও আপডেট করেন না, আপনি কেবল একটি নতুন PRODUCTVERSIONসারি .োকান। সর্বশেষটি পেতে, আপনি সংস্করণ নম্বর (ডেস্ক), টাইমস্ট্যাম্প (ডেস্ক) দ্বারা সারণিটি সূচক করতে পারেন, বা আপনার একটি পতাকা থাকতে পারে ( LatestVersion)।

এখন যদি আপনার কাছে এমন কিছু থাকে যা কোনও পণ্যের উল্লেখ করে তবে আপনি এটি নির্ধারণ করতে পারবেন যে এটি কোন সারণিকে নির্দেশ করেছে। এটি কী PRODUCTসত্তা (সর্বদা এই পণ্যটিকে বোঝায়) বা PRODUCTVERSIONসত্তাকে নির্দেশ করে (কেবলমাত্র পণ্যের এই সংস্করণটিকে বোঝায়)?

এটা জটিল হয়ে যায়। আপনার যদি পণ্যের ছবি থাকে? তাদের সংস্করণ টেবিলের দিকে ইঙ্গিত করতে হবে, কারণ এগুলি পরিবর্তন করা যেতে পারে তবে অনেক ক্ষেত্রে তারা তা করবে না এবং আপনি অকারণে ডেটা নকল করতে চান না। তার অর্থ আপনার একটি PICTUREটেবিল এবং PRODUCTVERSIONPICTUREএকাধিক থেকে অনেকের সম্পর্ক দরকার।


1

আমি আমার সমস্ত টেবিলে থাকা 4 টি ক্ষেত্রের সাথে এখান থেকে সমস্ত জিনিস প্রয়োগ করেছি :

  • আইডি
  • date_creation
  • date_validity_start
  • date_validity_end

প্রতিবার রেকর্ডটি সংশোধন করতে হবে, আমি এটিকে সদৃশ করব, সদৃশ রেকর্ডটিকে "পুরানো" হিসাবে চিহ্নিত করুন = date_validity_end=NOW()এবং বর্তমানটিকে ভাল date_validity_start=NOW()এবং হিসাবে চিহ্নিত করুন date_validity_end=NULL

কৌতুকটি অনেকের কাছে এবং একের সাথে অনেক সম্পর্কে: এটি তাদের স্পর্শ না করে কাজ করে! এটি এত জটিল যেগুলি সম্পর্কিত প্রশ্নগুলি: একটি সুনির্দিষ্ট তারিখে একটি রেকর্ড অনুসন্ধান করতে (= এখনই নয়), আমার প্রতিটি যোগদানের জন্য, এবং প্রধান সারণীর জন্য, এই সীমাবদ্ধতাগুলি যুক্ত করার জন্য:

WHERE (
  (date_validity_start<=:dateparam AND date_validity_end IS NULL)
  OR
  (date_validity_start<=:dateparam AND date_validity_start>=:dateparam)
)

সুতরাং পণ্য এবং গুণাবলী (অনেকের সাথে অনেকগুলি সম্পর্কিত):

SELECT p.*,a.*

FROM products p

JOIN products_attributes pa
ON pa.id_product = p.id
AND (
  (pa.date_validity_start<=:dateparam AND pa.date_validity_end IS NULL)
  OR
  (pa.date_validity_start<=:dateparam AND pa.date_validity_start>=:dateparam)
)

JOIN attributes a
ON a.id = pa.id_attribute
AND (
  (a.date_validity_start<=:dateparam AND a.date_validity_end IS NULL)
  OR
  (a.date_validity_start<=:dateparam AND a.date_validity_start>=:dateparam)
)

WHERE (
  (p.date_validity_start<=:dateparam AND p.date_validity_end IS NULL)
  OR
  (p.date_validity_start<=:dateparam AND p.date_validity_start>=:dateparam)
)

0

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


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