سؤال

لدينا شرط في مشروع لتخزين جميع التنقيحات(يتغير التاريخ) الكيانات في قاعدة البيانات.حاليا لدينا 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" هو أن لدينا تحليل XML في كل مرة عندما كنت في حاجة للوصول إلى البيانات.هذا وسوف تبطئ عملية و أيضا إضافة بعض القيود مثل أننا لا يمكن إضافة ينضم بشأن التنقيحات حقول البيانات.

و المشكلة مع "تصميم 2" هو أن لدينا لتكرار كل مجال على جميع الكيانات (لدينا حوالي 70-80 الكيانات التي نريد الحفاظ على المراجعات).

هل كانت مفيدة؟

المحلول

  1. هل لا وضع كل ذلك في طاولة واحدة مع IsCurrent مميز السمة.هذا فقط يسبب مشاكل أسفل الخط ، يتطلب بديلة مفاتيح جميع أنواع المشاكل الأخرى.
  2. تصميم 2 هل لديك مشاكل مع التغييرات المخطط.إذا قمت بتغيير جدول الموظفين لديك لتغيير EmployeeHistories الجدول و كل ذات sprocs التي تذهب معها.يحتمل أن يضاعف لك مخطط تغيير الجهد.
  3. تصميم 1 يعمل بشكل جيد إذا فعلت بشكل صحيح لا تكلف كثيرا من حيث الأداء ضرب.يمكنك استخدام مخطط xml و حتى فهارس للحصول على أداء ممكن المشاكل.تعليقك حول تحليل xml صالح ولكن يمكنك بسهولة إنشاء عرض باستخدام xquery - التي يمكن أن تدرج في الاستفسارات الانضمام إلى.شيء من هذا القبيل...
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 

نصائح أخرى

أعتقد أن السؤال هنا هو الذي / ما هو ذاهب إلى استخدام التاريخ'?

إذا سيكون في الغالب للإبلاغ / الإنسان للقراءة التاريخ ، لقد نفذت هذه الخطة في الماضي...

إنشاء جدول يسمى 'AuditTrail' أو شيء من هذا الذي يحتوي على الحقول التالية...

[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

ثم يمكنك إضافة 'LastUpdatedByUserID' عمود إلى جميع الجداول التي يجب أن يتم تعيين كل مرة كنت تفعل تحديث / أدخل على الطاولة.

ثم يمكنك إضافة تؤدي إلى كل طاولة للقبض على أي إدراج / تحديث يحدث ويخلق الدخول في هذا الجدول لكل حقل تغيرت.لأن الجدول أيضا أن يتم توفيرها مع 'LastUpdateByUserID' لكل تحديث / إدراج ، يمكنك الوصول إلى هذه القيمة في الزناد واستخدامها عند إضافة إلى مراجعة الجدول.

نحن نستخدم RecordID حقل لتخزين قيمة في حقل المفتاح من الجدول تحديث.إذا كان الجمع بين رئيسي, ونحن لا مجرد سلسلة سلسلة مع '~' بين الحقول.

أنا متأكد من أن هذا النظام قد يكون من عيوب عن كاهل تحديث قواعد بيانات الأداء قد يكون ضرب, ولكن بالنسبة لي التطبيق على شبكة الإنترنت, حصلنا على العديد من يقرأ أكثر مما يكتب و يبدو أن أداء جيد جدا.حتى كتب قليلا VB.NET الأداة تلقائيا كتابة مشغلات استنادا إلى تعريفات الجدول.

مجرد فكرة!

على تاريخ الجداول المادة في قاعدة بيانات مبرمج بلوق قد يكون من المفيد - يغطي بعض النقاط التي أثيرت هنا ويناقش تخزين دلتا.

تحرير

في تاريخ الجداول مقال الكاتب (كينيث داونز) بأن الحفاظ على تاريخ الجدول ما لا يقل عن سبعة أعمدة:

  1. الطابع الزمني من التغيير ،
  2. المستخدم التي جعلت التغيير ،
  3. رمز لتحديد السجل الذي تم تغييره (حيث ويحتفظ التاريخ بشكل منفصل عن التيار الدولة) ،
  4. ما إذا كان التغيير إدراج أو تحديث أو حذف ،
  5. القيمة القديمة ،
  6. القيمة الجديدة ،
  7. دلتا (على التغييرات في القيم العددية).

الأعمدة التي لا تتغير أبدا ، أو التاريخ الذي هو غير مطلوب ، ينبغي أن تتبع في تاريخ الجدول لتجنب سخام.تخزين دلتا القيم العددية يمكن أن تجعل الاستعلامات اللاحقة أسهل ، على الرغم من أنها يمكن أن تكون مستمدة من القيم القديمة والجديدة.

تاريخ الجدول يجب أن تكون آمنة مع عدم نظام منع المستخدمين من إدراج أو تحديث أو حذف صفوف.فقط الدوري تطهير يجب أن تكون معتمدة للحد من حجم إجمالي (و إذا سمحت حالة استخدام).

قمنا بتنفيذ الحل مشابهة جدا إلى حل كريس روبرتس يوحي ، وأنه يعمل بشكل جيد جدا بالنسبة لنا.

الفرق الوحيد هو أننا فقط تخزين القيمة الجديدة.القيمة القديمة بعد كل المخزنة في التاريخ السابق التوالي

[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 الأعمدة.بهذه الطريقة يكون لديك فقط لتخزين الدقيق العمود الذي تغير بدلا من الحاجة إلى تخزين الصف بأكمله.

تجنب تصميم 1;ليس في متناول يدي عندما كنت سوف تحتاج على سبيل المثال العودة إلى الإصدارات القديمة من السجلات - إما تلقائيا أو "يدويا" باستخدام للمسؤولين التحكم.

لا أرى عيوب التصميم 2.أعتقد الثانية ، تاريخ الجدول يجب أن يحتوي على كل الأعمدة الموجودة في أول سجلات الجدول.E. g.في الخلية يمكنك بسهولة إنشاء الجدول مع نفس هيكل آخر الجدول (create table X like Y).و عندما كنت على وشك تغيير هيكل من سجلات الجدول في قاعدة بيانات حية ، alter table الأوامر على أي حال - لا يوجد جهد كبير في تشغيل هذه الأوامر أيضا من أجل التاريخ الجدول.

ملاحظات

  • سجلات الجدول يحتوي فقط على أحدث مراجعة ؛
  • تاريخ الجدول يحتوي على جميع التنقيحات السابقة من الوثائق في سجلات الجدول ؛
  • تاريخ الجدول المفتاح الأساسي هو المفتاح الأساسي من جدول الأرقام القياسية مع إضافة RevisionId العمود ؛
  • التفكير في مساعدة إضافية المجالات مثل ModifiedBy - المستخدم الذي قام بإنشاء خاصة إلى تنقيح.قد تحتاج أيضا إلى حقل DeletedBy إلى المسار الذي حذف خاصة إلى تنقيح.
  • التفكير في ما DateModified ينبغي أن يعني إما أنه يعني أين هذا الخصوص مراجعة أنشئت من أجلها ، أو أنه يعني عند هذا الخصوص مراجعة محله آخر.يتطلب السابق الميدان في سجلات الجدول ، ويبدو أن تكون أكثر سهولة في أول البصر ؛ الحل الثاني ومع ذلك يبدو أن عملية حذف السجلات (تاريخ هذا الخصوص تنقيح تم حذفها).إذا كنت تذهب الحل الأول, سوف تحتاج على الأرجح الثاني الميداني DateDeleted (إلا إذا كنت في حاجة إليها بالطبع).يعتمد على ما كنت فعلا تريد تسجيل.

العمليات في التصميم 2 هي تافهة جدا:

تعديل
  • نسخ سجل من سجلات الجدول إلى تاريخ الجدول ، بل RevisionId (إذا لم تكن موجودة بالفعل في سجلات الجدول) ، التعامل مع DateModified (يعتمد على كيفية تفسير ذلك ، انظر الملاحظات أعلاه)
  • الذهاب مع التحديث العادي من سجل في سجلات الجدول
حذف
  • تفعل بالضبط نفس كما في الخطوة الأولى من عملية تعديل.التعامل مع DateModified/DateDeleted وبناء على ذلك ، اعتمادا على التفسير الذي اخترته.
الحذف (أو التراجع)
  • تأخذ أعلى (أو بعض معين؟) مراجعة من تاريخ الجدول نسخ إلى سجلات الجدول
قائمة مراجعة التاريخ سجل خاص
  • اختر من الجدول التاريخ و سجلات الجدول
  • أعتقد بالضبط ما كنت تتوقع من هذه العملية ؛ فإنه من المحتمل تحديد ما هي المعلومات التي تحتاجها من DateModified/DateDeleted المجالات (انظر الملاحظات أعلاه)

إذا كنت تذهب تصميم 2, جميع أوامر SQL في حاجة للقيام بذلك سيكون من السهل جدا جدا, وكذلك الصيانة!ربما سيكون من الأسهل بكثير إذا كنت تستخدم المساعدة الأعمدة (RevisionId, DateModified) أيضا في سجلات الجدول للحفاظ على كلا الجدولين في نفس هيكل (باستثناء مفاتيح فريدة من نوعها)!هذا سوف يسمح بسيطة أوامر SQL التي سوف يكون متسامحا إلى أي هيكل البيانات التغيير:

insert into EmployeeHistory select * from Employe where ID = XX

لا تنسى أن استخدام المعاملات!

أما بالنسبة التحجيم, هذا الحل فعال جدا, منذ كنت لا تحويل أي البيانات من XML ذهابا وإيابا, مجرد نسخ كاملة صفوف الجدول - بسيطة جدا الاستعلامات باستخدام المؤشرات - فعالة جدا!

إذا كان لديك لتخزين التاريخ, جعل الظل الجدول مع نفس المخطط كما الطاولة كنت تتبع و 'مراجعة التاريخ" و "تنقيح نوع' عمود (مثلا ، 'حذف', 'تحديث').الكتابة (أو توليد - انظر أدناه) مجموعة من مشغلات لملء مراجعة الجدول.

انها واضحة إلى حد ما لجعل أداة من شأنها أن قراءة بيانات نظام القاموس على طاولة وتوليد السيناريو الذي يخلق الظل طاولة ومجموعة من المشغلات إلى ملء ذلك.

لا تحاول استخدام XML هذا XML تخزين الكثير أقل كفاءة من الأم جدول قاعدة البيانات تخزين هذا النوع من الزناد الاستخدامات.

راميش ، وقد شاركت في تطوير نظام يقوم على النهج الأول.
اتضح أن تخزين التنقيحات كما XML يؤدي إلى قاعدة بيانات ضخمة نمو كبير في تباطؤ الأمور.
توجهي أن يكون جدول واحد لكل كيان:

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

حيث IsActive هو علامة على أحدث إصدار

إذا كنت ترغب في ربط بعض المعلومات الإضافية مع التنقيحات يمكنك إنشاء جدول منفصل التي تحتوي على المعلومات التي وربطه مع الكيان الجداول باستخدام PK\FK العلاقة.

بهذه الطريقة يمكنك تخزين كل نسخة من الموظفين في جدول واحد.إيجابيات هذا النهج:

  • بسيطة هيكل قاعدة البيانات
  • لا الصراعات منذ الجدول يصبح إلحاق فقط
  • يمكنك العودة إلى الإصدار السابق ببساطة عن طريق تغيير IsActive العلم
  • لا حاجة ينضم إلى الحصول على كائن التاريخ

لاحظ أنه يجب السماح المفتاح الأساسي إلى عدم فريدة من نوعها.

الطريقة التي رأيت هذا يحدث في الماضي هو

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

لم "تحديث" على هذا الجدول (باستثناء تغيير صالحة من isCurrent) فقط إدراج صفوف جديدة.أي EmployeeId, فقط 1 الصف يمكن أن يكون isCurrent == 1.

تعقيد من الحفاظ على هذا يمكن أن تكون مخفية من قبل وجهات النظر "بدلا من" المشغلات (في أوراكل ، أفترض أشياء مماثلة أخرى RDBMS) ، يمكنك الذهاب حتى إلى العروض المادية إذا كانت الجداول كبيرة جدا و لا يمكن التعامل معها من قبل الفهارس).

هذا الأسلوب هو موافق ، ولكن يمكنك في نهاية المطاف مع بعض الاستعلامات المعقدة.

شخصيا, أنا مولعا جدا من التصميم الخاص بك 2 طريقة للقيام بذلك ، وهو كيف فعلت ذلك في الماضي كذلك.بسيطة لفهم وبسيطة لتنفيذ وبسيطة للحفاظ على.

كما يخلق القليل جدا من الحمل على قاعدة البيانات و التطبيق ، وخاصة عند إجراء قراءة الاستعلامات, والتي من المرجح ماذا عليك أن تفعل 99 ٪ من الوقت.

كما أنه سيكون من السهل جدا التلقائي إنشاء التاريخ الجداول يؤدي إلى الحفاظ على (على افتراض أنه سوف يتم عن طريق مشغلات).

أنا ذاهب لأطلعكم على تصميمي و هو مختلف عن كل التصاميم في أنه يتطلب جدول واحد لكل نوع الكيان.لقد وجدت أن أفضل طريقة لوصف أي تصميم قاعدة البيانات من خلال ERD ، الألغام هنا:

enter image description here

في هذا المثال لدينا كيان اسمه الموظف. المستخدم الجدول يحمل المستخدمين السجلات الكيان و entity_revision نوعان من الجداول التي تحمل تاريخ مراجعة لجميع أنواع الكيانات التي سيكون لديك في النظام الخاص بك.هنا كيف يعمل هذا التصميم:

اثنين من المجالات entity_id و revision_id

كل كيان في النظام الخاص بك سوف يكون لها كيان فريد معرف من تلقاء نفسها.الكيان الخاص بك قد تذهب من خلال المراجعات ولكن entity_id لا تزال هي نفسها.تحتاج إلى الحفاظ على هذا الكيان id في جدول الموظفين (مثل المفاتيح الخارجية).يجب عليك أيضا تخزين نوع من الكيان الخاص بك في الكيان الجدول (مثلا ، 'موظف').الآن بالنسبة revision_id ، كما يدل اسمه ، تتبع الكيان التنقيحات.أفضل طريقة وجدتها على هذا هو استخدام employee_id كما revision_id.وهذا يعني سيكون لديك تكرار مراجعة معرفات أنواع مختلفة من الكيانات ولكن هذا لا علاج لي (أنا غير متأكد حول قضيتك).فقط ملاحظة هامة هي أن الجمع بين entity_id و revision_id يجب أن تكون فريدة من نوعها.

هناك أيضا الدولة الميدانية داخل entity_revision الجدول الذي أشار إلى حالة المراجعة.فإنه يمكن أن يكون واحدة من ثلاث دول: latest, obsolete أو deleted (لا تعتمد على تاريخ التنقيحات يساعدك على قدر كبير لتعزيز الاستفسارات الخاصة بك).

ملاحظة أخيرة على revision_id لم تخلق الأجنبية الرئيسية التي تربط employee_id إلى revision_id لأننا لا نريد تغيير entity_revision جدول لكل نوع الكيان أننا قد تضيف في المستقبل.

الإدراج

لكل الموظف التي تريد إدراجها في قاعدة البيانات ، يمكنك أيضا إضافة سجل إلى الكيان و entity_revision.هذه الأخيرة اثنين من السجلات سوف تساعدك على الحفاظ على المسار من قبل ومتى سجل تم إدراجها في قاعدة البيانات.

التحديث

كل تحديث القائمة سجل الموظف سيتم تنفيذها في اثنين إدراج واحد في الجدول موظف واحد في entity_revision.ثانية واحدة سوف تساعدك على معرفة من الذي عندما سجل تم تحديث.

الحذف

حذف موظف سجل يتم إدراجها في entity_revision تفيد الحذف و القيام به.

كما يمكنك أن ترى في هذا التصميم أي بيانات من أي وقت مضى تغييرها أو إزالتها من قاعدة بيانات والأهم من كل نوع الكيان يتطلب جدول واحد فقط.شخصيا أجد هذا التصميم حقا مرنة وسهلة للعمل مع.ولكن أنا لست متأكدا من أنك الاحتياجات الخاصة بك قد تكون مختلفة.

[تحديث]

بعد أن دعمت أقسام في الخلية الجديدة إصدارات اعتقد ان التصميم كما يأتي مع واحدة من أفضل العروض أيضا.يمكن للمرء أن التقسيم entity الجدول باستخدام type ميدان بينما القسم entity_revision باستخدام state الحقل.وهذا سيعزز SELECT استعلامات حتى الآن في حين تبقى تصميم بسيط ونظيف.

إذا كان الواقع لمراجعة الحسابات هو كل ما تحتاجه كنت تميل نحو مراجعة الجدول الحل (كاملة مع denormalized نسخ من أهم الأعمدة في الجداول الأخرى ، على سبيل المثال ، UserName).نضع في اعتبارنا ، على الرغم من أن التجربة المريرة تشير إلى أن واحد مراجعة الجدول سوف تكون ضخمة عنق الزجاجة الطريق ؛ ربما يستحق كل هذا الجهد لخلق الفردية مراجعة الجداول لجميع مراجعة الجداول.

إذا كنت بحاجة إلى تتبع التاريخية الفعلية (و/أو المستقبل) الإصدارات ، ثم معيار الحل هو أن تتبع نفس الجهة مع صفوف متعددة باستخدام مزيج من بداية, نهاية, و مدة القيم.يمكنك استخدام طريقة عرض إلى جعل الوصول إلى القيم الحالية مريحة.إذا كان هذا هو النهج لك تشغيل في مشاكل إذا كان لديك إصدار بيانات المراجع قابلة للتغيير ولكن unversioned البيانات.

تنقيحات البيانات هو جانب من جوانب 'صالحة الوقت'مفهوم الزمانية قاعدة البيانات الخاصة بنا.الكثير من البحوث وقد ذهب إلى هذا كثير من أنماط التوجيهية ظهرت.كتبت مطولة الرد مع مجموعة من المراجع هذا سؤال للمهتمين.

إذا كنت تريد أن تفعل أول واحد قد ترغب في استخدام XML جدول الموظفين أيضا.معظم أحدث قواعد البيانات تتيح لك الاستعلام إلى XML المجالات وهذا ليس دائما مشكلة.و قد يكون أبسط لديك طريقة واحدة للوصول إلى بيانات الموظف بغض النظر إذا كان أحدث نسخة أو إصدار سابق.

وأود أن محاولة النهج الثاني على الرغم من.هل يمكن تبسيط هذا من خلال وجود واحد فقط من جدول الموظفين مع DateModified المجال.EmployeeId + DateModified سيكون المفتاح الأساسي و يمكنك تخزين تنقيح جديد فقط عن طريق إضافة صف واحد.هذه طريقة أرشفة الإصدارات القديمة و استعادة الإصدارات من الأرشيف هو أسهل جدا.

طريقة أخرى للقيام بذلك يمكن أن يكون datavault نموذج دان Linstedt.أنا عملت مشروع الهولندية مكتب الإحصاءات التي تستخدم هذا النموذج يعمل بشكل جيد جدا.ولكن أنا لا أعتقد أنه مباشرة من المفيد يوما بعد يوم استخدام قاعدة البيانات.قد تحصل على بعض الأفكار من قراءة أوراقه على الرغم من.

ماذا عن:

  • EmployeeID
  • DateModified
    • و/أو رقم المراجعة ، اعتمادا على كيفية كنت تريد أن تتبع ذلك
  • ModifiedByUSerId
    • بالإضافة إلى أي معلومات أخرى تريد أن تتبع
  • الموظف المجالات

يمكنك جعل المفتاح الأساسي (EmployeeId, DateModified) و "التيار" record(s) فقط حدد ماكس(DateModified) لكل employeeid.تخزين IsCurrent هو فكرة سيئة للغاية ، لأنه أولا وقبل كل شيء ، ويمكن أن تكون محسوبة ، وثانيا ، فمن السهل جدا للحصول على البيانات للحصول على متزامنة.

يمكنك أيضا عرض هذه القوائم فقط أحدث السجلات و تستخدم في الغالب أنه في حين أن العمل في التطبيق الخاص بك.الشيء الجميل في هذا النهج هو أن لم يكن لديك نسخ من البيانات و ليس لديك لجمع البيانات من مكانين مختلفين (الحالي في الموظفين ، المؤرشفة في EmployeesHistory) للحصول على كل التاريخ أو التراجع ، إلخ).

إذا كنت تريد أن تعتمد على تاريخ البيانات (الإبلاغ عن الأسباب) يجب عليك استخدام هيكل شيئا من هذا القبيل:

// 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)"

يمكنك حفظ الخاص بك التنقيحات أيضا في XML ، ثم لديك سجل واحد فقط من أجل تنقيح واحد.وسوف يكون هذا يبدو مثل:

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

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

لدينا متطلبات مماثلة ، ما وجدناه هو أن في كثير من الأحيان المستخدم يريد فقط أن انظر ما قد تغير ، وليس بالضرورة دحر أي تغييرات.

لست متأكدا ما استخدامك القضية, ولكن ما قمنا به هو إنشاء ومراجعة الجدول الذي يتم تلقائيا تحديث مع التغييرات إلى كيان تجاري ، بما في ذلك اسم مألوف من أي المراجع الأجنبية الرئيسية والتعدادات.

عندما يقوم المستخدم بحفظ التغييرات الخاصة بهم ونحن تحديث القديم الكائن تشغيل مقارنة ، سجل التغييرات وحفظ كيان (كل ما يتم القيام به في قاعدة بيانات واحدة الصفقة في حالة وجود أي مشاكل).

ويبدو أن تعمل بشكل جيد جدا للمستخدمين و يحفظ لنا الصداع من وجود منفصل تماما مراجعة الجدول مع نفس الحقول كما لدينا كيان تجاري.

يبدو أنك تريد أن تعقب التغييرات إلى كيانات معينة مع مرور الوقت ، على سبيل المثالمعرف 3 ، "بوب", "123 الشارع الرئيسي" ، ثم آخر معرف 3 ، "بوب" "234 elm st" ، وهلم جرا ، في جوهرها القدرة على تقيؤ مراجعة تاريخ عرض كل عنوان "بوب" في.

أفضل طريقة للقيام بذلك هو أن يكون هناك "الحالي" على كل سجل ، و (ربما) زمني أو FK إلى تاريخ/وقت الجدول.

إدراج يكون ثم تعيين "الحالي" كما ضبطه "الحالي" في السابق "الحالي" سجل.استفسارات لديك لتحديد "الحالي", إلا إذا كنت تريد كل من التاريخ.

هناك المزيد من القرص إلى هذا إذا كان جدول كبير جدا ، أو عدد كبير من المراجعات المتوقعة ، ولكن هذا هو المعيار إلى حد ما النهج.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top