SQL Standard حدد السجلات الحالية من سؤال سجل التدقيق

StackOverflow https://stackoverflow.com/questions/1146004

  •  16-09-2019
  •  | 
  •  

سؤال

ذاكرتي فشلتني. لدي جدول سجل مراجعة بسيط يعتمد على الزناد:

هوية شخصيةint (الهوية، PK)
هوية الزبونإتجاه
اسمفارشار (255)
عنوانفارشار (255)
AuditDateTime.DateTime.
AuditCode.شار (1)


لديها بيانات مثل هذا:

هوية شخصيةهوية الزبوناسمعنوانAuditDateTime.AuditCode. 1  123        بوب.123 طريق الإنترنت2009-07-17 13:18:06.353أنا 2  123        بوب.123 طريق الإنترنت2009-07-17 13:19:02.117د 3  123        جيري123 طريق الإنترنت2009-07-17 13:36:03.517أنا 4  123        بوب.123 طريقة التحرير2009-07-17 13:36:08.050U. 5  100        أرنولد100 Skynet Way.2009-07-17 13:36:18.607أنا 6  100        نيكي100 نجمة2009-07-17 13:36:25.920U. 7  110        شقراء110 طريقة أخرى2009-07-17 13:36:42.313أنا 8  113        سالي113 طريقة أخرى2009-07-17 13:36:57.627أنا


ما سيكون البيان المختار الفعال هو الحصول على معظم السجلات الحالية بين وقت البدء والنهاية؟ FYI: أنا لإدراج، D للحذف، وأنت للتحديث.

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

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

المحلول

طريقة أخرى (أفضل؟) طريقة للحفاظ على سجل التدقيق هو استخدام عمود "Startdate" و "EndDate" بدلا من AuditDateTime وعمود AuditCode. غالبا ما يكون هذا هو النهج في تتبع التغييرات من النوع 2 (إصدارات جديدة من الصف) في مستودعات البيانات.

يتيح لك ذلك تحديد الصفوف الحالية بشكل مباشر (حيث يكون الوصفات المعدلة فارغة)، ولن تحتاج إلى علاج التحديثات بشكل مختلف عن إدراج أو حذف. لديك ببساطة ثلاث حالات:

  • إدراج: انسخ الصف الكامل مع تاريخ البدء وتاريخ نهاية فارغة
  • حذف: تعيين تاريخ انتهاء الصف الحالي الحالي (IDDate Null)
  • تحديث: قم بحذف ثم إدراج

سيكون لديك ستعمل ببساطة:

select * from AuditTable where endDate is NULL

على أي حال، إليك استفستي لمخططك الحالي:

declare @from datetime
declare @to datetime

select b.* from (
  select
    customerId
    max(auditdatetime) 'auditDateTime'
  from
    AuditTable
  where
    auditcode in ('I', 'U')
    and auditdatetime between @from and @to
  group by customerId
  having 
    /* rely on "current" being defined as INSERTS > DELETES */
    sum(case when auditcode = 'I' then 1 else 0 end) > 
    sum(case when auditcode = 'D' then 1 else 0 end)
) a
cross apply(
  select top 1 customerId, name, address, auditdateTime
  from AuditTable
  where auditdatetime = a.auditdatetime and customerId = a.customerId
) b

مراجع

أ كريبشيت لمستودعات البيانات, ، ولكن لديه قسم جيد حول التغييرات من النوع 2 (ما تريد تتبعه)

صفحة MSDN ON. تخزين البيانات

نصائح أخرى

حسنا، بضعة أشياء لجداول سجل التدقيق.

بالنسبة لمعظم التطبيقات، نريد أن تكون الجداول المراجعة سريعة للغاية على الإدراج.

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

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

create unique clustered index idx_mytable on mytable(AuditDateTime, ID)

سيسمح ذلك باستفسارات اختيار فعالة للغاية عند تشغيل AuditatTime O (سجل N)، و O (1) الإدراج.

إذا كنت ترغب في البحث عن جدول التدقيق الخاص بك على أساس CustomerId، فستحتاج إلى حل وسط.

يمكنك إضافة فهرس غير منقطق (CustomerID، AuditDateTime)، والتي ستسمح بإجراء بحث O (LOG N) الخاص بتاريخ مراجعة العملاء، ولكن ستكون التكلفة هي صيانة هذا الفهرس غير العنكبوت عند الإدراج - ستكون هذه الصيانة س ( سجل ن) على العكس.

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


بالإضافة إلى ذلك: إذا كنت تتطلع إلى تقييد إطار زمني معين، فإن الشيء الأكثر أهمية أولا وقبل كل شيء هو الفهرس عند AuditDateTime. وجعلها متجمعة كما كنت تدرج في ترتيب AuditDateTe. هذا هو أكبر شيء يمكنك القيام به لجعل الاستعلام الخاص بك فعال من البداية.

بعد ذلك، إذا كنت تبحث عن أحدث تحديث لجميع Customer Customersid في بعض الوقت المحدد، فالمسح الضوئي الكامل للبيانات، مقيد عن طريق تاريخ الإدراج، مطلوب.

ستحتاج إلى القيام بعملية فرعية على طاولة التدقيق الخاصة بك، بين النطاق،

select CustomerID, max(AuditDateTime) MaxAuditDateTime 
from AuditTrail 
where AuditDateTime >= @begin and Audit DateTime <= @end

ثم دمج ذلك في الاستعلام المحدد الخاص بك مناسبة، على سبيل المثال.

select AuditTrail.* from AuditTrail
inner join 
    (select CustomerID, max(AuditDateTime) MaxAuditDateTime 
     from AuditTrail 
     where AuditDateTime >= @begin and Audit DateTime <= @end
    ) filtration
    on filtration.CustomerID = AuditTrail.CustomerID and 
       filtration.AuditDateTime = AuditTrail.AuditDateTime

نهج آخر يستخدم اختيار الفرعية

select a.ID
       , a.CustomerID 
       , a.Name
       , a.Address
       , a.AuditDateTime
       , a.AuditCode
from   myauditlogtable a,
       (select s.id as maxid,max(s.AuditDateTime) 
                 from myauditlogtable as s 
                 group by maxid) 
        as subq
where subq.maxid=a.id;

بداية ونهاية الوقت؟ على سبيل المثال كما هو الحال في ما بين 1 صباحا إلى 3:00
أو بداية ونهاية الوقت؟ على سبيل المثال في 2009-07-17 13:36 إلى 2009-07-18 13:36

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