Pergunta

No início desta semana eu fazer uma pergunta sobre filtrando valores duplicados em seqüência em tempo de execução. Teve algumas boas respostas, mas a quantidade de dados que eu estava passando por cima era lento e não é viável.

Actualmente no nosso banco de dados, valores de evento não são filtrados. Resultando em valores de dados duplicados (com marcas de tempo diferentes). Precisamos processar os dados em tempo de execução e no nível de banco de dados é a vez caro (e não pode retirá-lo em código, porque isso é muito usado em procedimentos armazenados) resultando em tempos de altos consulta. Precisamos de uma estrutura de dados que podemos consulta que tem este armazenamento de dados filtrados de forma que nenhuma filtragem adicional é necessária em tempo de execução.

Actualmente no nosso DB

  • '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’ (necessidade de eliminar este) **
  • 'F07331E4-26EC-41B6-BEC5-002AACA58337', '1', '2008-05-10 04: 05: 05,000'

O que precisamos

  • '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'

Isto parece trivial, mas o nosso problema é que temos estes dados de dispositivos sem fio, resultando em pacotes fora de seqüência e nosso gateway é multithreaded por isso não podemos garantir os valores que recebemos estão em ordem. Algo pode entrar como um '1' durante 4 segundos atrás e um '0' durante 2 segundos atrás, mas temos o processo de '1' já porque ele foi o primeiro em. Que foram girando a cabeça sobre como implementar isso. Não podemos comparar os dados para o último valor no banco de dados porque o mais recente pode realmente não ter entrado ainda, então para jogar esses dados para fora estaríamos ferrados e nossa sequência pode ser completamente desligado. Assim, atualmente, armazenar cada valor que entra e o próprio embaralha banco de dados em torno baseados fora de tempo .. mas as unidades podem enviar 1,1,1,0 e sua válida porque o evento ainda está ativo, mas nós só queremos armazenar o dentro e fora do estado (primeira ocorrência de estado ligado 1,0,1,0,1,0) .. pensamos em um gatilho, mas teríamos de baralhar os dados em torno de cada vez que um novo valor entrou porque pode ser mais cedo, em seguida, a última mensagem e pode alterar a sequência inteira (inserções seria lenta).

Alguma idéia?

Pergunte se você precisar de mais informações.

[EDIT] PK não vai funcionar - o problema é que nossas unidades realmente enviar em diferentes marcas de tempo. de modo que o PK não trabalho seria porque 1,1,1 são o mesmo .. mas não têm diferentes selos de tempo. Sua evento como se passou no time1, evento ainda em pelo time2, envia-nos de volta tanto .. mesmo valor de tempo diferente.

Foi útil?

Solução

Aqui está uma solução de atualização. O desempenho irá variar dependendo índices.

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

Não é difícil imaginar uma solução de filtragem com base nesta. Só depende de quantas vezes você quiser procurar o recorde anterior para cada registro (cada consulta ou de vez em quando).

Outras dicas

Se bem entendi, o que você quer fazer é simplesmente impedir que os crédulos de mesmo ficando no banco de dados. Se for esse o caso, porque não têm um PK (ou índice exclusivo) definido nas duas primeiras colunas e ter o banco de dados fazer o trabalho pesado para você. inserções Dupe falharia baseado no PK ou AK você definiu. Você está código (ou proc armazenado), então, só tem que lidar com graciosamente que exceção.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top