অডিট লগিং জন্য ডেটাবেস ডিজাইন


151

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

এই সম্পর্কে এখানে ইতিমধ্যে কিছু প্রশ্ন জিজ্ঞাসা করা হয়েছে, তবে আমি সম্মত হই না যে সমস্ত পরিস্থিতিতে একক জন্য সর্বোত্তম পদ্ধতির রয়েছে:

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

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

  • ডাটাবেস স্কিমাটির পরিপক্কতা
  • লগগুলি কীভাবে অনুসন্ধান করা হবে
  • সম্ভাব্যতা এটি রেকর্ড পুনরায় তৈরি করা প্রয়োজন হবে
  • আরও গুরুত্বপূর্ণ কী: লিখুন বা পড়ুন পারফরম্যান্স
  • লগ করা হচ্ছে এমন মানগুলির প্রকৃতি (স্ট্রিং, সংখ্যা, ব্লব)
  • সঞ্চয় স্থান উপলব্ধ

যে পদ্ধতিগুলি আমি জানি সেগুলি হ'ল:

1. তৈরি এবং পরিবর্তিত তারিখ এবং ব্যবহারকারীর জন্য কলাম যুক্ত করুন

সারণীর উদাহরণ:

  • আইডি
  • মান_1
  • মান_2
  • value_3
  • তৈরীর তারিখ
  • পরিবর্তিত তারিখ
  • দ্বারা সৃষ্টি
  • modified_by

মেজর কনস: আমরা পরিবর্তনগুলির ইতিহাস হারিয়েছি। কমিট করার পরে রোলব্যাক করতে পারবেন না।

2. কেবল সারণী সন্নিবেশ করান

সারণীর উদাহরণ :

  • আইডি
  • মান_1
  • মান_2
  • value_3
  • থেকে
  • প্রতি
  • মুছে ফেলা (বুলিয়ান)
  • ব্যবহারকারী

মেজর কনস: বিদেশী কীগুলি আপ টু ডেট রাখবেন? বিশাল জায়গা দরকার

৩. প্রতিটি টেবিলের জন্য পৃথক ইতিহাসের টেবিল তৈরি করুন

ইতিহাসের সারণির উদাহরণ:

  • আইডি
  • মান_1
  • মান_2
  • value_3
  • value_4
  • ব্যবহারকারী
  • মুছে ফেলা (বুলিয়ান)
  • টাইমস্ট্যাম্প

প্রধান কনস: সমস্ত নিরীক্ষিত টেবিলগুলি নকল করা দরকার। যদি স্কিমা পরিবর্তন হয় তবে এটি সমস্ত লগগুলিকেও স্থানান্তরিত করতে হবে।

৪. সমস্ত টেবিলের জন্য একীভূত ইতিহাসের সারণী তৈরি করুন

ইতিহাসের সারণির উদাহরণ:

  • TABLE_NAME
  • ক্ষেত্র
  • ব্যবহারকারী
  • NEW_VALUE
  • মুছে ফেলা (বুলিয়ান)
  • টাইমস্ট্যাম্প

প্রধান কনস: সহজে প্রয়োজন হলে আমি কি রেকর্ডগুলি (রোলব্যাক) পুনরায় তৈরি করতে সক্ষম হব? নতুন_মূল্য কলামটি একটি বিশাল স্ট্রিং হওয়া দরকার যাতে এটি সমস্ত বিভিন্ন কলামের প্রকারকে সমর্থন করতে পারে।


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

1
এবং টেবিলের পরিবর্তে ইতিহাসের ডাটাবেস ব্যবহার সম্পর্কে কী?
জোওয়ান

হতে পারে আপনি github.com/airblade/paper_trail
zx1986

সমস্ত (প্রয়োজনীয়) ক্যোয়ারী যেমন হয় তেমন লগ করা কি খারাপ ধারণা?
দিনুশান

উত্তর:


87

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

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

সুযোগগুলি
সুযোগ_সূচি (বা এরকম কিছু)

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

এখানে একটি সাধারণ উদাহরণ:

CREATE TABLE dbo.Page(  
    ID int PRIMARY KEY,  
    Name nvarchar(200) NOT NULL,  
    CreatedByName nvarchar(100) NOT NULL, 
    CurrentRevision int NOT NULL, 
    CreatedDateTime datetime NOT NULL

এবং বিষয়বস্তু:

CREATE TABLE dbo.PageContent(
    PageID int NOT NULL,
    Revision int NOT NULL,
    Title nvarchar(200) NOT NULL,
    User nvarchar(100) NOT NULL,
    LastModified datetime NOT NULL,
    Comment nvarchar(300) NULL,
    Content nvarchar(max) NOT NULL,
    Description nvarchar(200) NULL

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

SELECT * FROM Page
JOIN PageContent ON CurrentRevision = Revision AND ID = PageID

সেখানে কিছু ত্রুটি থাকতে পারে ... এটি আমার মাথার উপরের অংশটি। যদিও এটি আপনাকে বিকল্প প্যাটার্নের ধারণা দেয়।


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

11
যদি প্রতিটি টেবিলের জন্য স্ক্রিপ্টগুলি লিখতে এবং বজায় রাখা কোনও সংস্থার জন্য উদ্বেগ হয়ে থাকে যা নিরীক্ষিত ডাটাবেস পরিচালনা করতে চায় তবে আমি স্বাভাবিকভাবেই সুপারিশ করব যে তারা অভিজ্ঞ ডিবিএ বা উচ্চ-নমনীয় এবং অত্যন্ত অভিজ্ঞ সফ্টওয়্যার-ইঞ্জিনিয়ারকে নিখরচায় ডেটাবেস তৈরির পর্যাপ্ত অভিজ্ঞতা সহ নিয়োগ করুন recommend ।
হার্ড্রিভ 17

1
এটি কি ঠিক যে PageContent.PageIDএফকে টু Page.IDএবং Page.CurrentRevisionএফকে থেকে PageContent.Revision? এই নির্ভরতা কি আসলেই বিজ্ঞপ্তি?

2
আমি উল্লেখ করেছি যেহেতু এটি উল্লিখিত বিকল্পগুলিকে সম্বোধন করে না। এটি অন্য একটি বিকল্প দেয় যা খুব নির্দিষ্ট ব্যবহারের ক্ষেত্রে খুব নির্দিষ্ট সমাধান। কিন্তু আমি প্রস্তাব নকশা ফযীলত দেখতে পাচ্ছ
acteon

1
আমি খুব কম কয়েকটি ক্ষেত্রের কথা ভাবতে পারি যা আমি আত্মবিশ্বাসের সাথে বলতে পারি যে প্রতিটি সত্তার জন্য সমস্ত "প্রধান" সারণী সবেমাত্র শেষ হবে id, revision_id; একটি জংশন টেবিল আরও, সত্যিই। এটি আমার কাছে কিছুটা দুর্গন্ধযুক্ত লাগে। ওপিতে 3 পদ্ধতির (নিরীক্ষিত টেবিলের জন্য ইতিহাস সারণী) এর থেকে এর কী সুবিধা রয়েছে?
কেনমোর 4

14

আপনি যদি এসকিউএল সার্ভার ২০০৮ ব্যবহার করেন তবে আপনার সম্ভবত ডেটা ক্যাপচারটি পরিবর্তন বিবেচনা করা উচিত। এটি ২০০৮ সালের জন্য নতুন এবং আপনার যথেষ্ট পরিমাণে কাজ বাঁচাতে পারে।


এসকিউএল ২০১২ পরিবর্তন ট্র্যাকিং তথ্যের লিঙ্কটি এখানে। এমএসডিএন.মাইক্রোসফট.এইন.উস / লিবারি/bb933994.aspx +1 কার্যক্ষমতায় অন্তর্নির্মিত ব্যবহারের জন্য, হুইলটি পুনরায় উদ্ভাবনের কোনও দরকার নেই।
ক্রিস

4
@ ক্রিস আপনি কি নিজে নিজে এটি ব্যবহার করেছেন? প্রকৃতপক্ষে, এটি সমস্ত কিছু ট্র্যাক করে ... তবে এর থেকে দরকারী তথ্য পেতে সক্ষম হওয়া সম্পূর্ণ অন্য গল্প। আমার বাইকের জন্য ট্র্যাক্টর হুইল ব্যবহার করতে পারি না।
জোওয়ান

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

6

আমি কোনও রেফারেন্স সম্পর্কে জানি না, তবে আমি নিশ্চিত যে কেউ কিছু লিখেছেন।

তবে, যদি উদ্দেশ্যটি হয় যা ঘটেছিল তার একটি রেকর্ড রাখা an নিরীক্ষণের লগটির সর্বাধিক সাধারণ ব্যবহার to তবে কেন সব কিছু সহজভাবে রাখবেন না:

timestamp
username
ip_address
procedureName (if called from a stored procedure)
database
table
field
accesstype (insert, delete, modify)
oldvalue
newvalue

সম্ভবত এটি একটি ট্রিগার দ্বারা বজায় রাখা হয়।


আমি ডাটাবেস সার্ভারের মধ্যে এটি পাওয়ার কোনও উপায় জানি না, তবে অবশ্যই এটি বাইরে থেকে খুব সহজেই করা যায়।
wallyk

5
আমার কাছে মনে হচ্ছে এটি মূল প্রশ্নে প্রদর্শিত চতুর্থ বিকল্পের মতো একই নকশার প্যাটার্ন।
givanse

3

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

blog: একটি অনন্য পোস্ট আইডি, শিরোনাম, সামগ্রী এবং একটি মুছে ফেলা সংরক্ষণ করে। audit: রেকর্ড আইডি, ব্লগ পোস্ট আইডি, পরিবর্তনের ধরণ (নতুন, সম্পাদনা বা মোছা) এবং সেই পরিবর্তনের তারিখ / সময় দিয়ে historicalতিহাসিক পরিবর্তনের একটি মৌলিক সেট সংরক্ষণ করে। নিম্নলিখিত এসকিউএল blogমুছে ফেলা কলামটি তৈরি করে এবং সূচি দেয়:

CREATE TABLE `blog` (
    `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
    `title` text,
    `content` text,
    `deleted` tinyint(1) unsigned NOT NULL DEFAULT '0',
    PRIMARY KEY (`id`),
    KEY `ix_deleted` (`deleted`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='Blog posts';

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

CREATE TABLE `audit` (
    `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
    `blog_id` mediumint(8) unsigned NOT NULL,
    `changetype` enum('NEW','EDIT','DELETE') NOT NULL,
    `changetime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`),
    KEY `ix_blog_id` (`blog_id`),
    KEY `ix_changetype` (`changetype`),
    KEY `ix_changetime` (`changetime`),
    CONSTRAINT `FK_audit_blog_id` FOREIGN KEY (`blog_id`) REFERENCES `blog` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

2

আমি মনে করি সিদ্ধান্ত গাছের মতো কিছুই নেই। যেহেতু কিছু উপকারিতা এবং কনস (বা প্রয়োজনীয়তা) সত্যই গণনাযোগ্য নয়। উদাহরণস্বরূপ আপনি পরিপক্কতা কীভাবে পরিমাপ করবেন?

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

এবং আশ্বস্ত হন, আপনি কীভাবে সিদ্ধান্ত নেবেন তা বিবেচ্য নয়, সর্বদা এমন কেউ আছেন যে মনে করে আপনি ভুল সিদ্ধান্ত নিয়েছেন। তবে আপনি নিজের গৃহকর্মটি করেছেন এবং আপনি নিজের সিদ্ধান্তকে ন্যায়সঙ্গত করেছেন।

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