Câmeras, portas giratórias, elevadores, sensores de temperatura, alarmes – todos esses dispositivos produzem um grande número de sinais interconectados relacionados a eventos que acontecem ao nosso redor. Agora imagine que você é a pessoa que precisa rastrear status, produzir relatórios em tempo real e fazer previsões com base em todos esses dados de sinal. Para fazer isso, primeiro você precisa armazenar esses dados. Um modelo de dados que suporte esse processamento de sinal é o tópico do artigo de hoje.
A maneira mais simples de armazenar sinais de entrada seria simplesmente armazenar uma representação textual deles em uma lista enorme. Essa abordagem nos permitiria realizar inserções rapidamente, mas as atualizações seriam problemáticas. Além disso, tal modelo não seria normalizado e, portanto, não iremos nessa direção.
Vamos criar um modelo de dados normalizado que pode ser usado para armazenar os dados gerados por diferentes dispositivos e também definir como os dispositivos estão relacionados. Esse modelo armazenaria com eficiência tudo o que precisamos e também poderia ser usado para análise e análise preditiva.
Modelo de dados
O modelo de dados de processamento de sinal
O modelo consiste em três áreas temáticas:
Complexes
Installations & Devices
Signals & Events
Descreveremos cada uma dessas áreas de assunto na ordem em que estão listadas.
Complexos
Ao criar esse modelo de dados, parti do pressuposto de que o usaremos para rastrear o que está acontecendo em complexos maiores. Complexos variam em tamanho de um único quarto para um shopping center. É importante que todo complexo tenha pelo menos um dispositivo/sensor, mas provavelmente terá muitos mais.
Antes de descrever os complexos, precisamos definir as tabelas que tratam de países e cidades. Estes fornecerão uma descrição bastante detalhada da localização de cada complexo.
Para cada
country
, armazenaremos seu country_name
EXCLUSIVO; para cada city
, armazenaremos a combinação ÚNICA de postal_code
, city_name
e country_id
. Não entrarei em detalhes aqui e vamos supor que cada cidade tenha apenas um código postal. Na realidade, a maioria das cidades terá mais de um código postal; nesse caso, podemos usar o código principal para cada cidade. Um
complex
é o edifício ou local real onde os dispositivos geradores de dados estão instalados. Como dito anteriormente, os complexos podem variar desde um único cômodo ou uma estação de medição até lugares muito maiores como estacionamentos, shoppings, cinemas, etc. Eles são o objeto de nossa análise. Queremos poder acompanhar o que está acontecendo no nível complexo em tempo real e, posteriormente, produzir relatórios e análises. Para cada complexo, definiremos um:complex_code
– Um identificador ÚNICO para cada complexo. Embora tenhamos um atributo de chave primária separado (id
) para esta tabela, podemos esperar que herdaremos outro código de identificação para cada complexo de outro sistema.complex_name
– Um nome usado para descrever esse complexo. No caso de shopping centers e cinemas, esse pode ser seu nome real e conhecido; para uma estação de medição, podemos usar um nome genérico.city_id
– Uma referência à cidade onde o complexo está localizado.address
– O endereço físico desse complexo.position
– A posição do complexo (ou seja, coordenadas geográficas) definida em formato textual.description
– Uma descrição textual que descreva mais de perto esse complexo.ts_inserted
– Um carimbo de data/hora quando este registro foi inserido.is_active
– Um valor booleano indicando se este complexo ainda está ativo ou não.
Instalações e dispositivos
Agora estamos nos aproximando do coração do nosso modelo. Provavelmente teremos vários dispositivos instalados em cada complexo. Também quase certamente agruparemos esses dispositivos com base em sua finalidade - por exemplo, poderíamos colocar câmeras, sensores de porta e um motor usado para abrir e fechar uma porta em um grupo porque eles trabalham juntos.
Em nosso modelo, os dispositivos que trabalham juntos em um complexo são agrupados em instalações. Podem ser portas dianteiras, escadas rolantes, sensores de temperatura etc. Para cada instalação, armazenaremos os seguintes detalhes na
installation
tabela:installation_code
– Um código ÚNICO usado para denotar essa instalação.installation type_id
– Uma referência aoinstallation_type
dicionário. Este dicionário armazena apenas umtype_name
ÚNICO atributo que descreve o tipo, por exemplo, escada rolante, elevador.complex_id
– Uma referência aocomplex
a que a instalação pertence.position
– As coordenadas, em formato textual, dessa instalação dentro do complexo.description
– Uma descrição textual dessa instalação.current_status_id
– Uma referência ao status atual (doinstallation_status
table) dessa instalação.ts_inserted
– Um carimbo de data/hora quando este registro foi inserido em nosso sistema.
Já mencionamos os status de instalação. Uma lista de todos os status possíveis é armazenada no
installation_status
dicionário. Cada status é definido EXCLUSIVAMENTE por seu status_name
. Além disso, armazenaremos sinalizadores indicando se esse status, quando usado, implica que a instalação is_broken
, is_inactive
, is_maintenance
, ou is_active
. Apenas um desses sinalizadores deve ser definido por vez. Já atribuímos um status atual à instalação. Se vamos rastrear o que está acontecendo com o dispositivo, também precisamos armazenar seu histórico. Para fazer isso, usaremos mais uma tabela,
installation_status_history
. Para cada registro aqui, armazenaremos referências à instalação e status relacionados, bem como o momento (ts_inserted
) quando esse status foi atribuído. As instalações fazem parte dos nossos complexos. Embora cada instalação seja uma entidade única, ela ainda pode estar relacionada a outras instalações. (Por exemplo, um sistema de vídeo na entrada da frente de um shopping está obviamente relacionado às portas da frente do shopping – as pessoas serão vistas pela câmera primeiro e depois as portas se abrirão.) Se quisermos acompanhar esses relacionamentos, vamos armazená-los na
related_installation
tabela. Observe que esta tabela contém apenas pares ÚNICOS de duas chaves, ambas referenciando a installation
tabela. A mesma lógica é usada para armazenar dispositivos. Os dispositivos são peças únicas de hardware que produzem os sinais nos quais estamos interessados. Enquanto as instalações pertencem aos complexos, os dispositivos pertencem às instalações. Para cada
device
, armazenaremos:device_code
– Uma maneira ÚNICA de denotar cada dispositivo.device_name
– Um nome para este dispositivo.installation_id
– Uma referência à instalação à qual este dispositivo pertence.current_status_id
– O status atual do dispositivo.ts_inserted
– Um carimbo de data/hora quando este registro foi inserido.
Os status são tratados da mesma maneira. Usaremos o
device_status
table para armazenar uma lista de todos os status possíveis do dispositivo. Esta tabela tem a mesma estrutura que installation_status
e os atributos são usados da mesma maneira. A razão para ter os dois dicionários de status separados é que os dispositivos e suas instalações podem ter status diferentes – pelo menos no nome. O status atual é armazenado no
device.current_status_id
atributo e o histórico de status é armazenado no device_status_history
tabela. Para cada registro aqui, armazenaremos as relações com o dispositivo e o status, bem como o momento em que esse registro foi inserido. A última tabela nesta área de assunto é o
related_device
tabela. Embora seja bastante óbvio que todos os dispositivos dentro da mesma instalação estão intimamente relacionados, quero ter a opção de relacionar dois dispositivos pertencentes a qualquer instalação. Faremos isso armazenando seus dois IDs de dispositivo nesta tabela. Sinais e eventos
Agora estamos prontos para o coração de todo o modelo.
Dispositivos geram sinais. Todos os dados do sinal são mantidos no
signal
tabela. Para cada sinal, armazenaremos o:device_id
– Uma referência ao dispositivo que gerou esse sinal.value
– O valor numérico desse sinal.description
– Um valor textual que pode conter quaisquer parâmetros adicionais (por exemplo, tipo de sinal, valores, unidade de medida usada) relacionados a esse único sinal. Esses dados são armazenados em um formato semelhante ao JSON.ts
– Um carimbo de data/hora quando este sinal foi inserido na tabela.
Podemos esperar que esta tabela tenha um uso extremamente pesado, com um grande número de inserções executadas por segundo. Portanto, a manutenção do banco de dados deve se concentrar no rastreamento do tamanho dessa tabela.
A última coisa que quero fazer é adicionar eventos ao nosso modelo de dados. Os eventos podem ser gerados automaticamente por um sinal ou inseridos manualmente. Um evento gerado automaticamente pode ser “porta aberta por 5 minutos”, enquanto um evento inserido manualmente pode ser “o dispositivo teve que ser desligado por causa desse sinal”. A ideia é armazenar ações que ocorreram como resultado do comportamento do dispositivo. Mais tarde, poderíamos usar esses eventos ao realizar uma análise do comportamento do dispositivo.
Os eventos serão granulados por
event_type
. Cada tipo é definido EXCLUSIVAMENTE por seu type_name
. Todos os eventos gerados automaticamente ou inseridos manualmente são registrados no
event
tabela. Para cada registro aqui, armazenaremos:event_type_id
– Uma referência ao tipo de evento relacionado.description
– Uma descrição textual desse evento.signal_id
– Uma referência ao sinal, se houver, que causou o evento.inserted_manually
– Um sinalizador indicando se este registro foi inserido manualmente ou não.event_ts
ets_inserted
–Timestamps quando este evento realmente aconteceu e quando um registro dele foi inserido. Esses dois podem diferir, especialmente quando os registros de eventos são inseridos manualmente.
A última tabela em nosso modelo é o
event_device
tabela. Esta tabela é utilizada para relacionar eventos com todos os dispositivos que estiveram envolvidos. Para cada registro, armazenaremos o par ÚNICO event_id
– device_id
e o carimbo de data/hora em que o registro foi inserido. O que você acha do nosso modelo de dados de processamento de sinal?
Hoje, analisamos um modelo de dados simplificado que poderíamos usar para rastrear sinais de um conjunto de dispositivos instalados em diferentes locais. O modelo em si deve ser suficiente para armazenar tudo o que precisamos para rastrear status e realizar análises. Ainda assim, muitas melhorias são possíveis. O que poderíamos acrescentar? Por favor, conte-nos nos comentários abaixo.