Banco de Dados

18 fev, 2019

Otimização em banco de dados – Tabela horários de funcionamento

Publicidade

Na área de modelagem de banco de dados, a otimização existe para construir o modelo mais eficiente no quesito de armazenamento, busca e tratamento dos dados, considerando velocidade, segurança, confiabilidade e vários outros padrões de qualidade específicos para a área.

Dentre tantas necessidades comuns, por mais simples que possa parecer, uma delas é o armazenamento de dias e horários de funcionamento de estabelecimentos comerciais. Qualquer tabela e modelo tem condições de guardar esses e muitos outros dados no banco e disponibilizá-los para consultas, mas o diferencial e o benefício está naqueles que conseguem fazer isso da forma mais otimizada possível.

Até então, para o momento da busca e para a infraestrutura do banco de dados considerando espaço de armazenamento, tipos de dados e controle de redundâncias de modelo lógico e físico.

O modelo que iremos ver e desenvolver para validar e solucionar essa necessidade, se baseará em um modelo relacional para a infraestrutura de banco de dados SQL Server, que se usa do Transact-SQL (T-SQL) para a programação de suas funcionalidades e propriedades.

Na lógica do modelo de negócios, um estabelecimento comercial pode ter vários horários de funcionamento, considerando dias da semana e paradas para folga durante o próprio dia, assim como determinado horário de funcionamento pode se aplicar a vários estabelecimentos.

Figura 1 — Representação de relacionamento entre horário de funcionamento e estabelecimento comercial
  • Temos, portanto, um relacionamento de muitos para muitos.

Agora, como melhor organizar os tipos de dados que iremos guardar, e quais serão eles necessariamente?

Em nossa entidade, para tratar esses registros de horários de funcionamento podemos ter como identificação o nome “horario_funcionamento”.

Como dias da semana já podemos contar sete atributos nessa entidade. Contabilizando os atributos que guardarão o horário de abertura e de fechamento desses dias, já podemos totalizar nove atributos para o nosso modelo.

Iniciando pelos horários de abertura e fechamento, podemos nomeá-los como “hora_abre” e “hora-fecha”, e como estamos trabalhando com o SQL Server, nesse sistema de banco de dados há um tipo de dado chamado “time”, ótimo para o nosso caso de armazenamento dessa informação de tempo.

Baseado apenas na necessidade de horas e minutos, podemos definir como parâmetro desse tipo de dado a escala de segundos fracionários com o valor 3.

Assim, cada um dos atributos de horário de abertura e fechamento armazenará apenas 3 bytes fixos de comprimento por guardar apenas as horas, os minutos e os segundos fracionários do registro, sem se preocupar com o espaço de armazenamento e as informações desnecessárias para o nosso caso de dia, mês e ano.

Não temos a necessidade de conhecer em qual segundo daquele minuto o estabelecimento abre ou fecha, mas como é o mínimo que esse tipo de dado suporta na ferramenta, não há outras alternativas para essa modelagem e nem preocupações para considerar.

Quanto aos dias da semana, podemos nomeá-los de forma final numérica e identificá-los como os dias da semana por meio da associação:

  • dia_semana_0 — Domingo
  • dia_semana_1 — Segunda-feira
  • dia_semana_2 — Terça-feira
  • dia_semana_3 — Quarta-feira
  • dia_semana_4 — Quinta-feira
  • dia_semana_5 — Sexta-feira
  • dia_semana_6 — Sábado
Figura 2 – Representação de atributos da tabela horario_funcionamento

À respeito desses atributos, uma característica muito bacana que o SQL Server implementa é o tipo dado “bit” que funciona como um booleano, um verdadeiro ou falso, armazenando apenas 0, 1 ou NULL internamente para a nossa checagem se aquele horário de abertura ou fechamento se aplica a um determinado dia da semana.

O diferencial desse tipo bit em relação a outros tipos de dados do mesmo ou de outros SGBDs é a adequação interna no SQL Server para seu espaço de armazenamento total em relação à sua quantidade. Com esse tipo de dado, o armazenamento se dá apenas por 1 único byte para cada conjunto de até 8 colunas com esse tipo de dado no modelo físico.

E se temos definidos sete atributos com esse tipo de dado que se tornarão sete colunas, o armazenamento total de todas elas preenchidas ou não, será unicamente de 1 byte.

Poderíamos, sem problemas, utilizar tipos de dados inteiros como o “tinyint”, o menor tipo de dado inteiro no SQL Server que armazena apenas 1 byte por coluna de dia da semana, ou mesmo um tipo de dado de caractere como o “CHAR” que identificaria um Y para Yes ou um N para No nessa checagem de verdadeiro ou falso para a atribuição do horário e que armazenaria apenas 1 byte para cada letra registrada.

Entretanto, pensando na otimização de nosso modelo e performance de todo o projeto, cada coluna com esses tipos de dados armazenaria 1 byte cada, e se definirmos 1, 3 ou 8 atributos com o tipo bit, o armazenamento final será unicamente de 1 byte para o conjunto completo de nossas sete colunas, assim como se definirmos de 9 a 16, o espaço ocupado será o dobro do valor, e assim sucessivamente.

Com esses atributos definidos em nossa entidade horario_funcionamento, seu funcionamento completo pode ser explicado como um checklist. Para cada registro de horário de funcionamento, o que pode ser extraído é o horário de abertura, o horário de fechamento e em que dias da semana esses horários se aplicam.

Figura 3 — Representação da tabela horario_funcionamento preenchida

Tudo isso de uma forma muito fácil de ser entendida e buscada pelo homem e pela máquina, armazenando apenas 7 bytes por registro. Isso sem contabilizar o peso do próprio atributo identificador exclusivo da ocorrência com o valor de 2 bytes para o tipo smallint, 4 bytes para o int comum e 8 bytes para o bigint, cada um com aplicação variável dependendo do intervalo de registros exclusivos que se planeja armazenar no projeto.

Aplicando esse modelo podemos atender a casos em que um determinado estabelecimento, por exemplo, funcione de segunda a sexta-feira, das 8h às 17h, e que também de sexta-feira e sábado funcione das 19h às 23h, atendendo à pausas durante o dia e a horários distintos para diferentes dias.

Como essa entidade de horário de funcionamento pode se relacionar com vários estabelecimentos comerciais, e esses estabelecimentos comerciais podem se ligar a vários horários de funcionamento e compartilhar muitos deles pela maioria dos estabelecimentos funcionarem nas mesmas variações de horário comercial, em nossa entidade de interseção para resolução desse relacionamento de muitos para muitos entre horario_funcionamento e estabelecimento, podemos guardar no que chamaremos de “estabelecimento_horario_funcionamento” as identificações exclusivas das ocorrências relacionadas, mantendo então o funcionamento e a integridade sem redundâncias da aplicação de um mesmo horário para vários estabelecimentos e a possibilidade de um estabelecimento funcionar em vários horários diferentes entre um ou mais dias da semana.

Figura 4 — Representação da tabela de intersecção estabelecimento_horario_funcionamento preenchida
Figura 5 — Representação do modelo final do relacionamento normalizado entre as entidades

Essa foi a otimização para a modelagem desse tipo de necessidade. Claro que para cada necessidade comum há formas de tratamento que se distinguem entre as organizações e as próprias ferramentas, mas em um específico meio e modelo, vários refinamentos podem ser executados pensando na melhor utilização e manutenção de um produto considerando o benefício de todas as partes interessadas.