রিভিশনগুলির জন্য ডেটাবেস ডিজাইন?


125

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

যেমন "কর্মচারী" সত্তার জন্য

ডিজাইন 1:

-- Holds Employee Entity
"Employees (EmployeeId, FirstName, LastName, DepartmentId, .., ..)"

-- Holds the Employee Revisions in Xml. The RevisionXML will contain
-- all data of that particular EmployeeId
"EmployeeHistories (EmployeeId, DateModified, RevisionXML)"

ডিজাইন 2:

-- Holds Employee Entity
"Employees (EmployeeId, FirstName, LastName, DepartmentId, .., ..)"

-- In this approach we have basically duplicated all the fields on Employees 
-- in the EmployeeHistories and storing the revision data.
"EmployeeHistories (EmployeeId, RevisionId, DateModified, FirstName, 
      LastName, DepartmentId, .., ..)"

এই জিনিস করার অন্য কোন উপায় আছে?

"ডিজাইন 1" এর সমস্যাটি হ'ল আপনার যখন ডেটা অ্যাক্সেস করার দরকার হয় তখন প্রতিবারই আমাদের এক্সএমএল পার্স করতে হয়। এটি প্রক্রিয়াটি ধীর করবে এবং কিছু সীমাবদ্ধতা যুক্ত করবে যেমন আমরা সংশোধন ডেটা ক্ষেত্রগুলিতে যোগ দিতে পারি না।

এবং "ডিজাইন 2" এর সমস্যাটি হ'ল আমাদের সমস্ত সত্তার প্রতিটি ক্ষেত্রের নকল করতে হবে (আমাদের প্রায় 70-80 সত্তা রয়েছে যার জন্য আমরা সংশোধনগুলি বজায় রাখতে চাই)।


3
সম্পর্কিত: stackoverflow.com/questions/9852703/…
কাই

1
এফওয়াইআই: কেবলমাত্র এটির ক্ষেত্রে .SQL সার্ভার ২০০৮ এবং তারপরে প্রযুক্তি রয়েছে যা টেবিলের পরিবর্তনের ইতিহাস দেখায়..জমিজাল টাল্ক .com/ sql/ learn- sql- server /… আরও জানতে এবং আমি নিশ্চিত যে ডিবি'র ওরাকল এর মত এরকমও কিছু থাকবে।
দুরাই আমুথান.এইচ

মনে রাখবেন যে কিছু কলাম XML বা JSON নিজেই সঞ্চয় করতে পারে। যদি এখন এটি না হয় তবে ভবিষ্যতে এটি ঘটতে পারে। আরও নিশ্চিত হয়ে নিন যে আপনার আর একটিতে এই জাতীয় ডেটা বাসাতে হবে না।
jakubiszon

উত্তর:


38
  1. না না এটা সব এক টেবিলে একটি IsCurrent discriminator অ্যাট্রিবিউটের সাথে করা। এটি কেবল লাইনের নীচে সমস্যা সৃষ্টি করে, সারোগেট কীগুলি এবং অন্যান্য সমস্ত ধরণের সমস্যা দরকার।
  2. ডিজাইন 2 এর স্কিমা পরিবর্তনগুলির সাথে সমস্যা আছে। আপনি যদি কর্মচারীদের সারণী পরিবর্তন করেন তবে আপনাকে কর্মচারী ইতিহাসের টেবিল এবং এর সাথে সম্পর্কিত সমস্ত সম্পর্কিত স্প্রোকগুলি পরিবর্তন করতে হবে। সম্ভাব্যত আপনার স্কিমা পরিবর্তন প্রচেষ্টা দ্বিগুণ।
  3. ডিজাইন 1 ভালভাবে কাজ করে এবং যদি সঠিকভাবে করা হয় তবে পারফরম্যান্স হিটের ক্ষেত্রে খুব বেশি খরচ হয় না। সম্ভাব্য পারফরম্যান্স সমস্যার জন্য আপনি একটি এক্সএমএল স্কিমা এবং এমনকি সূচি ব্যবহার করতে পারেন। এক্সএমএল পার্স করার বিষয়ে আপনার মন্তব্য বৈধ তবে আপনি সহজেই এক্সকোয়ারি ব্যবহার করে একটি ভিউ তৈরি করতে পারেন - যা আপনি কোয়েরিতে অন্তর্ভুক্ত থাকতে পারেন এবং এতে যোগদান করতে পারেন। এটার মতো কিছু...
CREATE VIEW EmployeeHistory
AS
, FirstName, , DepartmentId

SELECT EmployeeId, RevisionXML.value('(/employee/FirstName)[1]', 'varchar(50)') AS FirstName,

  RevisionXML.value('(/employee/LastName)[1]', 'varchar(100)') AS LastName,

  RevisionXML.value('(/employee/DepartmentId)[1]', 'integer') AS DepartmentId,

FROM EmployeeHistories 

25
কেন আপনি বলছেন যে ইসকর্ন্ট ট্রিগার সহ এটি সমস্ত এক টেবিলে সংরক্ষণ করবেন না। আপনি কি আমাকে এমন কয়েকটি উদাহরণের দিকে নির্দেশ করতে পারেন যেখানে এটি সমস্যাযুক্ত হবে।
নাথান ডাব্লু

@ সিমন মুনরো একটি প্রাথমিক কী বা ক্লাস্টার কী কী হবে? অনুসন্ধানটি ত্বরান্বিত করার জন্য আমরা ডিজাইন 1 ইতিহাসের সারণিতে কী কী যুক্ত করতে পারি?
getqn

আমি SELECT * FROM EmployeeHistory WHERE LastName = 'Doe'একটি পূর্ণ টেবিল স্ক্যানের একটি সাধারণ ফলাফল অনুমান করি । কোনও অ্যাপ্লিকেশন স্কেল করার জন্য সেরা ধারণা নয়।
Kaii

54

আমার মনে হয় এখানে জিজ্ঞাসার মূল প্রশ্নটি হ'ল 'ইতিহাস / কে ব্যবহার করবে?'

যদি এটি বেশিরভাগ ক্ষেত্রে / মানব পাঠযোগ্য ইতিহাসের রিপোর্টিংয়ের জন্য হয়ে থাকে তবে আমরা অতীতে এই স্কিমটি প্রয়োগ করেছি ...

'অডিট্রেইল' নামে একটি সারণী তৈরি করুন বা এমন কিছু আছে যা নিম্নলিখিত ক্ষেত্রগুলি আছে ...

[ID] [int] IDENTITY(1,1) NOT NULL,
[UserID] [int] NULL,
[EventDate] [datetime] NOT NULL,
[TableName] [varchar](50) NOT NULL,
[RecordID] [varchar](20) NOT NULL,
[FieldName] [varchar](50) NULL,
[OldValue] [varchar](5000) NULL,
[NewValue] [varchar](5000) NULL

তারপরে আপনি আপনার সমস্ত টেবিলগুলিতে একটি 'লাস্টআপডেটেডবাইজারআইডিআইডি' কলাম যুক্ত করতে পারেন যা প্রতিবার আপনি টেবিলে আপডেট / সন্নিবেশ করার সময় সেট করা উচিত।

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

সারণীর মূল ক্ষেত্রটির মান আপডেট হওয়ার জন্য আমরা রেকর্ডআইডি ফিল্ডটি ব্যবহার করি। যদি এটি একটি সম্মিলিত কী হয় তবে আমরা কেবল ক্ষেত্রগুলির মধ্যে একটি '~' দিয়ে একটি স্ট্রিং কনটেনটেশন করি।

আমি নিশ্চিত যে এই সিস্টেমে ত্রুটি থাকতে পারে - ভারী আপডেট হওয়া ডাটাবেসের জন্য পারফরম্যান্সটি হিট হতে পারে তবে আমার ওয়েব-অ্যাপ্লিকেশনটির জন্য আমরা লেখার চেয়ে আরও অনেক বেশি পাঠ পেয়েছি এবং মনে হয় এটি বেশ ভাল পারফর্ম করছে। এমনকি আমরা টেবিলের সংজ্ঞাগুলির ভিত্তিতে ট্রিগারগুলি স্বয়ংক্রিয়ভাবে লিখতে একটি সামান্য ভিবি.এনইটি ইউটিলিটি লিখেছি।

শুধু একটি ভাবনা!


5
নিউভ্যালু সংরক্ষণ করার দরকার নেই, যেহেতু এটি নিরীক্ষিত সারণীতে সঞ্চিত রয়েছে।
পেট্রাস থেরন

17
কড়া কথা বলতে গেলে, এটা সত্য। কিন্তু - যখন সময়ের সাথে সাথে একই ক্ষেত্রে বেশ কয়েকটি পরিবর্তন হয়, তখন নতুন মান সংরক্ষণ করা যেমন 'ব্রায়ানের তৈরি সমস্ত পরিবর্তন আমাকে দেখান' যেমন একটি আপডেট সম্পর্কিত সমস্ত তথ্য রাখা হয় ততই প্রশ্নগুলি তৈরি করে qu একটি রেকর্ড শুধু একটি ভাবনা!
ক্রিস রবার্টস

1
আমি মনে করি sysnameযে টেবিল এবং কলামের নামগুলির জন্য আরও উপযুক্ত ডেটা টাইপ হতে পারে।
স্যাম

2
@ সিম ব্যবহার করে স্যাম কোনও মান যুক্ত করে না; এটা এমনকি বিভ্রান্তিকর হতে পারে ... stackoverflow.com/questions/5720212/...
Jowen

19

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

সম্পাদন করা

ইন ইতিহাস টেবিল রচনা, লেখক ( কেনেথ উন্মুক্ত বিস্তৃত উচ্চভূমি ), অন্তত সাত কলাম একটি ইতিহাস টেবিল বজায় রাখার বিশেষ পরামর্শ দেওয়া হচ্ছে:

  1. পরিবর্তনের টাইমস্ট্যাম্প,
  2. ব্যবহারকারী যে পরিবর্তন করেছে,
  3. রেকর্ডটি চিহ্নিত করা হয়েছে যা চিহ্নিত করা হয়েছে (যেখানে ইতিহাসকে বর্তমান রাষ্ট্র থেকে পৃথকভাবে বজায় রাখা হয়) চিহ্নিত করার লক্ষণ
  4. পরিবর্তনটি কোনও সন্নিবেশ, আপডেট, বা মোছা ছিল কিনা,
  5. পুরানো মান,
  6. নতুন মান,
  7. বদ্বীপ (সংখ্যার মানগুলিতে পরিবর্তনের জন্য)।

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

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


14

ক্রিস রবার্টস প্রস্তাবিত সমাধানের অনুরূপ একটি সমাধান আমরা কার্যকরভাবে প্রয়োগ করেছি এবং এটি আমাদের পক্ষে বেশ কার্যকর।

কেবল পার্থক্য হ'ল আমরা কেবলমাত্র নতুন মান সঞ্চয় করি। পুরানো মানটি পূর্ববর্তী ইতিহাসের সারিতে সব পরে সঞ্চিত হয়

[ID] [int] IDENTITY(1,1) NOT NULL,
[UserID] [int] NULL,
[EventDate] [datetime] NOT NULL,
[TableName] [varchar](50) NOT NULL,
[RecordID] [varchar](20) NOT NULL,
[FieldName] [varchar](50) NULL,
[NewValue] [varchar](5000) NULL

বলুন আপনার কাছে 20 টি কলাম সহ একটি টেবিল রয়েছে। এইভাবে আপনাকে কেবল সঠিক কলামটি সংরক্ষণ করতে হবে যা পুরো সারিটি সংরক্ষণ করার পরিবর্তে পরিবর্তিত হয়েছে।


14

ডিজাইন 1 এড়ান; একবারে আপনাকে রেকর্ডগুলির পুরানো সংস্করণগুলিতে রোলব্যাকের প্রয়োজন হবে - স্বয়ংক্রিয়ভাবে বা "ম্যানুয়ালি" অ্যাডমিনিস্ট্রেটরদের কনসোল ব্যবহার করে এটি একবার খুব কার্যকর হবে না।

আমি সত্যিই ডিজাইন 2 এর অসুবিধাগুলি দেখতে পাচ্ছি না I আমার মনে হয় দ্বিতীয়টি, ইতিহাস সারণীতে প্রথম, রেকর্ডস সারণীতে উপস্থিত সমস্ত কলাম থাকা উচিত। উদাহরণস্বরূপ, মাইএসকিএলে আপনি অন্য টেবিলের মতো কাঠামোগুলি সহ সহজেই টেবিল তৈরি করতে পারেন ( create table X like Y)। এবং, আপনি যখন আপনার লাইভ ডাটাবেসে রেকর্ড সারণির কাঠামো পরিবর্তন করতে চলেছেন, আপনাকে যে alter tableকোনও উপায়ে কমান্ড ব্যবহার করতে হবে - এবং আপনার ইতিহাস সারণির জন্যও এই কমান্ডগুলি চালানোর ক্ষেত্রে কোনও বড় প্রচেষ্টা নেই।

মন্তব্য

  • রেকর্ডস সারণীতে কেবল সর্বশেষতম সংশোধন রয়েছে;
  • ইতিহাস সারণীতে রেকর্ড সারণীতে রেকর্ডগুলির পূর্ববর্তী সমস্ত সংশোধনী রয়েছে;
  • ইতিহাস সারণীর প্রাথমিক কীটি যুক্ত RevisionIdকলাম সহ রেকর্ডস টেবিলের একটি প্রাথমিক কী ;
  • অতিরিক্ত সহায়তার ক্ষেত্রগুলির মতো চিন্তা করুন ModifiedBy- যে ব্যবহারকারী বিশেষ সংস্করণ তৈরি করেছেন। DeletedByকে নির্দিষ্ট সংস্করণ মুছে দিয়েছে তা ট্র্যাক করার জন্য আপনার একটি ক্ষেত্রও থাকতে পারে।
  • এর DateModifiedঅর্থ কী হবে তা নিয়ে ভাবুন - এটির অর্থ হল এই নির্দিষ্ট সংশোধনটি কোথায় তৈরি করা হয়েছিল, বা এর অর্থ যখন এই নির্দিষ্ট সংশোধনকে অন্য একটি দ্বারা প্রতিস্থাপন করা হয়েছিল। প্রাক্তনটির ক্ষেত্রটি রেকর্ডস সারণীতে থাকা দরকার এবং এটি প্রথম দর্শনে আরও স্বজ্ঞাত বলে মনে হয়; দ্বিতীয় সমাধানটি মুছে ফেলা রেকর্ডগুলির জন্য আরও কার্যকর বলে মনে হচ্ছে (এই নির্দিষ্ট সংশোধনটি মোছার তারিখ)। আপনি যদি প্রথম সমাধানের জন্য যান তবে আপনার সম্ভবত দ্বিতীয় ক্ষেত্রের DateDeletedপ্রয়োজন হবে (কেবল যদি আপনার অবশ্যই প্রয়োজন হয়)। আপনার উপর নির্ভর করে এবং আপনি আসলে কী রেকর্ড করতে চান।

ডিজাইন 2 এ অপারেশনগুলি খুব তুচ্ছ:

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

আপনি যদি ডিজাইন 2 এর জন্য যান তবে এটি করার জন্য প্রয়োজনীয় সমস্ত এসকিউএল কমান্ড খুব সহজেই হবে, পাশাপাশি রক্ষণাবেক্ষণও! সম্ভবত, আপনি রেকর্ড সারণীতে সহায়ক কলামগুলি ( RevisionId, DateModified) ব্যবহার করেও - এটি উভয় টেবিলকে ঠিক একই কাঠামোতে রাখার জন্য (অনন্য কী বাদে) অনেক সহজ হবে! এটি সাধারণ এসকিউএল কমান্ডগুলির জন্য মঞ্জুরি দেয়, যা কোনও ডাটা স্ট্রাকচার পরিবর্তনের ক্ষেত্রে সহনশীল হবে:

insert into EmployeeHistory select * from Employe where ID = XX

লেনদেন ব্যবহার করতে ভুলবেন না!

স্কেলিংয়ের ক্ষেত্রে , এই সমাধানটি খুব কার্যকরী, যেহেতু আপনি XML থেকে কোনও উপাত্ত পিছনে পিছনে রূপান্তরিত করেন না, কেবল পুরো টেবিল সারিগুলি অনুলিপি করে - খুব সাধারণ প্রশ্নগুলি, সূচকগুলি ব্যবহার করে - খুব দক্ষ!


12

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

কোনও সরঞ্জাম তৈরি করা মোটামুটি সোজা ward যা কোনও টেবিলে সিস্টেম ডেটা অভিধান পড়বে এবং একটি চিত্রনাট্য তৈরি করবে যা ছায়ার টেবিল তৈরি করবে এবং এটি তৈরি করতে ট্রিগারগুলির একটি সেট তৈরি করবে।

এর জন্য এক্সএমএল ব্যবহার করার চেষ্টা করবেন না, এক্সএমএল স্টোরেজ দেশীয় ডাটাবেস টেবিল স্টোরেজ যা এই ধরণের ট্রিগার ব্যবহার করে তার চেয়ে অনেক কম দক্ষ।


3
সরলতার জন্য +1! কিছু পরে পরিবর্তনের ভয়ে অতিরিক্ত প্রকৌশলী হবে, বেশিরভাগ সময় আসলে কোনও পরিবর্তন ঘটে না! অধিকন্তু, কোনও টেবিলের মধ্যে ইতিহাসের ইতিহাস এবং অন্য কয়েকটিতে সত্যিকারের রেকর্ডগুলি পরিচালনা করা আরও কিছু সহজ যা কিছু পতাকা বা স্থিতি সহ সমস্ত টেবিলে (দুঃস্বপ্ন) রাখে। একে 'কেআইএসএস' বলা হয় এবং সাধারণত দীর্ঘমেয়াদে আপনাকে পুরস্কৃত করে।
5ch9

+1 সম্পূর্ণরূপে একমত, আমার উত্তরে আমি যা বলি ঠিক তেমন ! সরল ও শক্তিশালী!
টিএমএস

8

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

Employee (Id, Name, ... , IsActive)  

যেখানে ইসএ্যাকটিভ হ'ল সর্বশেষতম সংস্করণের একটি চিহ্ন

আপনি যদি সংশোধনগুলির সাথে কিছু অতিরিক্ত তথ্য যুক্ত করতে চান তবে আপনি সেই তথ্য সম্বলিত পৃথক সারণী তৈরি করতে পারেন এবং এটি পিকে \ এফকে সম্পর্ক ব্যবহার করে সত্তার টেবিলের সাথে যুক্ত করতে পারেন।

এইভাবে আপনি কর্মীদের সমস্ত সংস্করণ এক টেবিলের মধ্যে সঞ্চয় করতে পারেন। এই পদ্ধতির পেশাদাররা:

  • সাধারণ ডেটা বেস কাঠামো
  • কেবল সারণী পরিশিষ্ট হিসাবে সংঘর্ষ হয় না
  • আপনি কেবল ইস্যাকটিভ ফ্ল্যাগ পরিবর্তন করে পূর্ববর্তী সংস্করণে রোলব্যাক করতে পারেন
  • বস্তুর ইতিহাস পেতে যোগ দেওয়ার দরকার নেই No

মনে রাখবেন যে আপনার প্রাথমিক কীটি অনন্য হতে দেওয়া উচিত।


6
আমি আইস্যাকটিভের পরিবর্তে বা এর পরিবর্তে একটি "রিভিশননাম্বার" বা "রিভিশনডেট" কলামটি ব্যবহার করব, যাতে আপনি সমস্ত সংশোধন ক্রম দেখতে পারেন।
Sklivvz

আমি একটি "প্যারেন্টরউআইআইডি" ব্যবহার করব কারণ এটি আপনাকে পূর্ববর্তী সংস্করণগুলিতে সহজে অ্যাক্সেসের পাশাপাশি বেস এবং শেষ দুটি দ্রুত সন্ধান করার ক্ষমতা দেয়।
chacham15

6

অতীতে আমি যেভাবে এটি দেখেছি তা হ'ল

Employees (EmployeeId, DateModified, < Employee Fields > , boolean isCurrent );

আপনি এই টেবিলটিতে কখনই "আপডেট" করতে পারবেন না (কেবলমাত্র আসরটির বৈধ পরিবর্তন ছাড়া) কেবল নতুন সারি inোকান। যে কোনও প্রদত্ত কর্মচারী আইডির জন্য, কেবলমাত্র 1 টি সারিতে ইসক্রেন = = 1 থাকতে পারে।

এটি বজায় রাখার জটিলতা দর্শনগুলি দ্বারা লুকানো যেতে পারে এবং "ট্রিগার" এর পরিবর্তে (ওরাকলে, আমি অন্যান্য আরডিবিএমএসের অনুরূপ জিনিসগুলি অনুমান করি), আপনি যদি টেবিলগুলি খুব বেশি বড় করেন এবং সূচকগুলি দ্বারা পরিচালনা করতে না পারেন তবে আপনি প্রকৃত দৃষ্টিভঙ্গিতেও যেতে পারেন) ।

এই পদ্ধতিটি ঠিক আছে তবে আপনি কিছু জটিল প্রশ্নের সাথে শেষ করতে পারেন।

ব্যক্তিগতভাবে, আমি আপনার ডিজাইনটি এটি করার 2 উপায় খুব পছন্দ করি যা আমি অতীতেও এটি করেছি। এটি বোঝার জন্য সহজ, প্রয়োগ করা সহজ এবং বজায় রাখা সহজ।

এটি ডেটাবেস এবং অ্যাপ্লিকেশনটির জন্য খুব সামান্য ওভারহেড তৈরি করে, বিশেষত যখন পড়ার প্রশ্নগুলি সম্পাদন করে, তখন সম্ভবত আপনি 99% সময় যা করছেন।

ইতিহাস সারণী এবং ট্রিগারগুলি বজায় রাখতে স্বয়ংক্রিয়ভাবে তৈরি করা বেশ সহজ হবে (ধরে নিবেন এটি ট্রিগারগুলির মাধ্যমে সম্পন্ন হবে)।


4

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


4

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

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

এই উদাহরণে আমাদের কর্মচারী নামে একটি সত্তা রয়েছে । ব্যবহারকারী সারণীটি আপনার ব্যবহারকারীর রেকর্ড এবং সত্তা এবং অস্তিত্ব_প্রেমীকরণ এমন দুটি টেবিল যা আপনার সিস্টেমে থাকা সমস্ত সত্তার প্রকারের জন্য পুনর্বিবেচনার ইতিহাস রাখে। এই নকশাটি কীভাবে কাজ করে তা এখানে:

এর দুটি ক্ষেত্র ENTITY_ID এবং REVISION_ID

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

সত্তা_প্রেমীকরণ টেবিলের মধ্যে একটি রাষ্ট্রের ক্ষেত্রও রয়েছে যা পুনর্বিবেচনার অবস্থাটি নির্দেশ করে। এটি তিনটি রাজ্যের এক হতে পারে latest, obsoleteবা deleted(পুনর্বিবেচনা তারিখ উপর নির্ভর না আপনি একটি মহান চুক্তি আপনার প্রশ্ন অনুমোদন করতে সাহায্য করে)।

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

সন্নিবেশ

প্রতিটি কর্মচারীর জন্য যা আপনি ডাটাবেসে সন্নিবেশ করতে চান, আপনি সত্তা এবং সত্তা_প্রেমিতে একটি রেকর্ড যুক্ত করবেন । এই শেষ দুটি রেকর্ড আপনাকে কখন এবং কখন একটি ডেটাবেসে একটি রেকর্ড sertedোকানো হয়েছে তা ট্র্যাক রাখতে সহায়তা করবে।

হালনাগাদ

বিদ্যমান কর্মচারী রেকর্ডের জন্য প্রতিটি আপডেট দুটি সন্নিবেশ হিসাবে প্রয়োগ করা হবে, একটি কর্মচারী টেবিলে এবং একটি সত্তা_প্রেমীকরণে। দ্বিতীয়টি আপনাকে কখন এবং কবে রেকর্ড আপডেট হয়েছে তা জানতে সহায়তা করবে।

মুছে যাওয়া

কোনও কর্মচারীকে মুছে ফেলার জন্য, সারণি_পরিষ্কারে একটি রেকর্ড সন্নিবেশ করানো হয়েছে উল্লেখ করে এবং সম্পন্ন করা হয়েছে।

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

[হালনাগাদ]

নতুন মাইএসকিউএল সংস্করণগুলিতে সমর্থিত পার্টিশন থাকার পরে, আমি বিশ্বাস করি যে আমার নকশাটিও সেরা পারফরম্যান্সগুলির সাথে আসে। একটি ভাগ করতে entityব্যবহার টেবিল typeযখন পার্টিশন ক্ষেত্র entity_revisionতার ব্যবহার stateক্ষেত্র। এটি নকশাটিকে SELECTসহজ এবং পরিষ্কার রাখার সময় প্রশ্নগুলিকে আরও বেশি বাড়িয়ে তুলবে ।


3

যদি সত্যিই আপনার নিরীক্ষণের পথচিহ্নের প্রয়োজন হয় তবে আমি অডিট টেবিল সমাধানের দিকে ঝুঁকতাম (অন্যান্য টেবিলগুলিতে গুরুত্বপূর্ণ কলামের ডেনারামালাইজড কপিগুলি সহ সম্পূর্ণ করুন UserName) , যেমন । তবে মনে রাখবেন যে এই তিক্ত অভিজ্ঞতাটি ইঙ্গিত দেয় যে একক নিরীক্ষণের টেবিলটি রাস্তার নিচে একটি বিশাল বাধা হয়ে দাঁড়াবে; আপনার সমস্ত নিরীক্ষিত টেবিলগুলির জন্য পৃথক নিরীক্ষণ টেবিলগুলি তৈরি করার প্রচেষ্টাটি সম্ভবত মূল্যবান worth

যদি আপনাকে প্রকৃত historicalতিহাসিক (এবং / অথবা ভবিষ্যত) সংস্করণগুলি ট্র্যাক করতে হয় তবে স্ট্যান্ডার্ড সমাধানটি হ'ল স্টার্ট, শেষ এবং সময়কাল মানগুলির সংমিশ্রণ সহ একাধিক সারি সহ একই সত্তাকে ট্র্যাক করা। আপনি বর্তমান মানগুলি অ্যাক্সেসকে সুবিধাজনক করার জন্য একটি ভিউ ব্যবহার করতে পারেন। যদি আপনি এই পদ্ধতিকে গ্রহণ করেন তবে আপনার সংস্করণযুক্ত ডেটা যদি পরিবর্তনীয় তবে রূপান্তরিত ডেটা উল্লেখ করে তবে আপনি সমস্যার মধ্যে পড়তে পারেন।


3

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

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

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


2

কেমন:

  • কর্মচারী আইডি
  • DateModified
    • এবং / অথবা আপনি কীভাবে এটি ট্র্যাক করতে চান তার উপর নির্ভর করে সংশোধন নম্বর
  • ModifiedByUSerId
    • প্লাস আপনি ট্র্যাক করতে চান অন্য কোনও তথ্য
  • কর্মচারী ক্ষেত্র

আপনি প্রাথমিক কী (কর্মচারী, তারিখরূপিত) তৈরি করেন এবং "বর্তমান" রেকর্ড (গুলি) পেতে আপনি প্রতিটি কর্মচারীর জন্য কেবলমাত্র ম্যাক্স (ডেটমোডিফায়েড) নির্বাচন করেন select ইসকুরেন্ট সংরক্ষণ করা খুব খারাপ ধারণা, কারণ সবার আগে এটি গণনা করা যায় এবং দ্বিতীয়ত, ডেটা সিঙ্ক থেকে বেরিয়ে আসা খুব সহজ।

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


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

2

আপনি যদি ইতিহাসের তথ্যের উপর নির্ভর করতে চান (কারণগুলির কারণের জন্য) আপনার কাঠামোটি এরকম কিছু ব্যবহার করা উচিত:

// Holds Employee Entity
"Employees (EmployeeId, FirstName, LastName, DepartmentId, .., ..)"

// Holds the Employee revisions in rows.
"EmployeeHistories (HistoryId, EmployeeId, DateModified, OldValue, NewValue, FieldName)"

বা প্রয়োগের জন্য বিশ্বব্যাপী সমাধান:

// Holds Employee Entity
"Employees (EmployeeId, FirstName, LastName, DepartmentId, .., ..)"

// Holds all entities revisions in rows.
"EntityChanges (EntityName, EntityId, DateModified, OldValue, NewValue, FieldName)"

আপনি আপনার রিভিশনগুলি এক্সএমএলেও সংরক্ষণ করতে পারেন, তারপরে একটি সংশোধনীর জন্য আপনার কাছে কেবল একটি রেকর্ড রয়েছে। এটির মতো দেখাবে:

// Holds Employee Entity
"Employees (EmployeeId, FirstName, LastName, DepartmentId, .., ..)"

// Holds all entities revisions in rows.
"EntityChanges (EntityName, EntityId, DateModified, XMLChanges)"

1
আরও ভাল: ইভেন্ট সোর্সিং ব্যবহার করুন :)
ডারিওল

1

আমাদের অনুরূপ প্রয়োজনীয়তা রয়েছে এবং আমরা যা পেয়েছি তা হ'ল প্রায়শই ব্যবহারকারী কেবল কী পরিবর্তন করা হয়েছে তা দেখতে চান , অগত্যা কোনও পরিবর্তন ব্যাক করে না।

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

যখনই ব্যবহারকারী তাদের পরিবর্তনগুলি সংরক্ষণ করে আমরা পুরানো অবজেক্টটি পুনরায় লোড করি, একটি তুলনা চালাই, পরিবর্তনগুলি রেকর্ড করি এবং সত্তাটি সংরক্ষণ করি (কোনও সমস্যা হওয়ার ক্ষেত্রে সমস্ত একক ডাটাবেসের লেনদেনে সম্পন্ন হয়)।

এটি আমাদের ব্যবহারকারীর জন্য খুব ভালভাবে কাজ করে বলে মনে হয় এবং আমাদের ব্যবসায়িক সত্তার মতো একই ক্ষেত্রগুলির সাথে একটি সম্পূর্ণ পৃথক নিরীক্ষণ টেবিল থাকার মাথা ব্যথা বাঁচায়।


0

দেখে মনে হচ্ছে আপনি সময়ের সাথে নির্দিষ্ট সত্তায় পরিবর্তনগুলি ট্র্যাক করতে চান, যেমন আইডি 3, "বব", "123 মূল স্ট্রিট", তারপরে অন্য আইডি 3, "বব" "234 এলএম স্ট" এবং আরও কিছুটা, সংক্ষিপ্তসার সক্ষম হয়ে প্রতিটি ঠিকানা "বব" দেখানো হয়েছে এমন একটি পুনর্বিবেচনার ইতিহাস বের করতে হবে।

এটি করার সর্বোত্তম উপায় হ'ল প্রতিটি রেকর্ডে একটি "বর্তমান" ক্ষেত্র এবং (সম্ভবত) একটি তারিখ / সময় সারণীতে একটি টাইমস্ট্যাম্প বা এফকে রাখা।

সন্নিবেশকে তারপরে "বর্তমানটি বর্তমান" সেট করতে হবে এবং পূর্ববর্তী "বর্তমানটি বর্তমান" রেকর্ডটিতে "বর্তমান বর্তমান" আনসেট করতে হবে। প্রশ্নগুলি "ইতিহাস বর্তমান" নির্দিষ্ট করতে হবে, যদি না আপনি সমস্ত ইতিহাস চান।

এটি যদি খুব বড় টেবিল হয় বা বিপুল সংখ্যক সংশোধনী প্রত্যাশিত হয় তবে এটিতে আরও টুইট রয়েছে তবে এটি মোটামুটি স্ট্যান্ডার্ড পদ্ধতির।

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