数据库重复值问题(基于先前的值进行过滤)
本周早些时候,我问一个有关在运行时按顺序过滤出重复值的问题。虽然有一些好的答案,但是我要遍历的数据量太慢且不可行。
当前在我们的数据库中,事件值未过滤。结果是重复的数据值(带有不同的时间戳)。我们需要在运行时处理该数据,并在数据库级别对其进行处理,这将导致代价高昂的查询时间(并且无法将其拉入代码,因为它在存储的proc中使用了很多)。我们需要一个可以查询的数据结构,该数据结构已过滤掉该数据存储,以便在运行时不需要其他过滤。
目前在我们的数据库中
- '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'
这看似微不足道,但是我们的问题是,我们从无线设备获取了这些数据,导致数据包乱序,并且网关是多线程的,因此我们无法保证所获取的值是正确的。可能会在4秒钟前出现" 1",在2秒钟前出现" 0",但是我们已经处理了" 1",因为它是第一个进入的。我们一直在努力实现它。我们无法将数据与数据库中的最新值进行比较,因为实际上可能还没有最新数据,因此将这些数据丢弃会被搞砸,而且序列可能会完全关闭。因此,当前我们存储所有传入的值,并且数据库会根据时间进行随机排序..但是单元可以发送1,1,1,0及其有效值,因为事件仍处于活动状态,但是我们只想存储打开和关闭状态(打开状态1,0,1,0,1,0的第一次出现)..我们考虑了一个触发器,但是每次出现新值时,我们都必须重新整理数据可能早于最后一条消息,并且它可以更改整个顺序(插入会很慢)。
有任何想法吗?
询问我们是否需要任何进一步的信息。
[编辑] PK不起作用,问题在于我们的单位实际发送了不同的时间戳。因此PK无效,因为1,1,1相同..但是时间戳不同。它的类似事件在时间1发生,事件仍在时间2发生,它将不同的时间发送回给我们。
解决方案
如果我理解正确,那么我们要做的就是防止重复对象进入数据库。如果是这样,为什么不在前两列中定义PK(或者唯一索引),并让数据库为我们完成繁重的工作。根据我们定义的PK或者AK,重复插入将失败。然后,我们就是代码(或者存储的proc),只需优雅地处理该异常即可。
这是一个更新解决方案。性能将根据索引而有所不同。
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
不难想象基于此的过滤解决方案。它仅取决于我们要查找每个记录的上一个记录的频率(每次查询或者不定期查询)。