مشكلة القيمة المكررة لقاعدة البيانات (التصفية بناءً على القيمة السابقة)

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

سؤال

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

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

حاليا في قاعدة البيانات لدينا

  • 'F07331E4-26EC-41B6-BEC5-002AACA58337'، '1'، '2008-05-08 04:03:47.000'
  • 'F07331E4-26EC-41B6-BEC5-002AACA58337'، '0'، '2008-05-08 10:02:08.000'
  • 'F07331E4-26EC-41B6-BEC5-002AACA58337'، '0'، '2008-05-09 10:03:24.000' (بحاجة إلى حذف هذا) **
  • 'F07331E4-26EC-41B6-BEC5-002AACA58337'، '1'، '2008-05-10 04:05:05.000'

ماذا نحتاج

  • 'F07331E4-26EC-41B6-BEC5-002AACA58337'، '1'، '2008-05-08 04:03:47.000'
  • 'F07331E4-26EC-41B6-BEC5-002AACA58337'، '0'، '2008-05-08 10:02:08.000'
  • 'F07331E4-26EC-41B6-BEC5-002AACA58337'، '1'، '2008-05-10 04:51:05.000'

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

أيه أفكار؟

اسأل إذا كنت بحاجة إلى أي معلومات إضافية.

[تحرير] PK لن يعمل - المشكلة هي أن وحداتنا ترسل بالفعل طوابع زمنية مختلفة.لذلك لن يعمل PK لأن 1،1،1 هي نفسها ..ولكن هناك طوابع زمنية مختلفة.يبدو الأمر كما لو أن حدثًا استمر في الوقت المحدد 1، وما زال الحدث مستمرًا في الوقت المناسب 2، فهو يعيدنا إلى كليهما..نفس القيمة في وقت مختلف

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

المحلول

إليك حل التحديث.سيختلف الأداء حسب الفهارس.

DECLARE @MyTable TABLE
(
  DeviceName varchar(100),
  EventTime DateTime,
  OnOff int,
  GoodForRead int
)

INSERT INTO @MyTable(DeviceName, OnOff, EventTime)
SELECT 'F07331E4-26EC-41B6-BEC5-002AACA58337', 1, '2008-05-08 04:03:47.000' 
INSERT INTO @MyTable(DeviceName, OnOff, EventTime)
SELECT 'F07331E4-26EC-41B6-BEC5-002AACA58337', 0, '2008-05-08 10:02:08.000' 
INSERT INTO @MyTable(DeviceName, OnOff, EventTime)
SELECT 'F07331E4-26EC-41B6-BEC5-002AACA58337', 0, '2008-05-09 10:03:24.000'
INSERT INTO @MyTable(DeviceName, OnOff, EventTime)
SELECT 'F07331E4-26EC-41B6-BEC5-002AACA58337', 1, '2008-05-10 04:05:05.000' 

UPDATE mt
SET GoodForRead = 
CASE
  (SELECT top 1 OnOff
   FROM @MyTable mt2
   WHERE mt2.DeviceName = mt.DeviceName
     and mt2.EventTime < mt.EventTime
   ORDER BY mt2.EventTime desc
  )
  WHEN null THEN 1
  WHEN mt.OnOff THEN 0
  ELSE 1
END
FROM @MyTable mt
    -- Limit the update to recent data
--WHERE EventTime >= DateAdd(dd, -1, GetDate())

SELECT *
FROM @MyTable

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

نصائح أخرى

إذا فهمت بشكل صحيح، ما تريد القيام به هو ببساطة منع المغفلين من الدخول إلى قاعدة البيانات.إذا كان الأمر كذلك، فلماذا لا يتم تحديد PK (أو الفهرس الفريد) في العمودين الأولين وجعل قاعدة البيانات تقوم بالمهمة الثقيلة نيابةً عنك.ستفشل الإدخالات المكررة بناءً على PK أو AK الذي حددته.سيتعين على الكود الخاص بك (أو proc المخزن) التعامل مع هذا الاستثناء بأمان.

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