Estou trabalhando com um banco de dados SQL no momento e isso sempre me deixou curioso, mas as pesquisas no Google não aparecem muito: por que os tipos de dados estritos?
Entendo por que você teria alguns tipos de dados diferentes, por exemplo, como é importante a diferenciação entre dados binários e dados de texto sem formatação . Em vez de armazenar os 1s e 0s dos dados binários como texto sem formatação, agora entendo que é mais eficiente armazenar os dados binários como seu próprio formato.
Mas o que não entendo é qual é o benefício de ter tantos tipos diferentes de dados:
- Porque
mediumtext
,longtext
etext
? - Porque
decimal
,float
eint
? - etc.
Qual é o benefício de informar ao banco de dados "Só haverá 256 bytes de dados de texto sem formatação nas entradas desta coluna". ou "Esta coluna pode ter entradas de texto de até 16.777.215 bytes"?
É um benefício de desempenho? Em caso afirmativo, por que saber o tamanho da entrada antecipadamente ajuda no desempenho? Ou melhor, é algo completamente diferente?
fonte
decimal
,float
eint
tipos, o que você esperaria1 / 3
que fazer? Que tal1.0 / 3.0
? Você poderia ter certeza de que, ao se dividircolumnA
,columnB
obterá os resultados esperados?Respostas:
SQL é uma linguagem de tipo estaticamente . Isso significa que você precisa saber que tipo de variável (ou campo, nesse caso) é antes de poder usá-la. É o oposto de linguagens de tipo dinâmico, onde esse não é necessariamente o caso.
Em sua essência, o SQL foi projetado para definir dados ( DDL ) e acessar dados ( DML ) em um mecanismo de banco de dados relacional . A digitação estática apresenta vários benefícios sobre a digitação dinâmica para esse tipo de sistema.
Os índices , usados para acessar rapidamente registros específicos, funcionam muito bem quando o tamanho é fixo. Considere uma consulta que utilize um índice, possivelmente com vários campos: se os tipos e tamanhos de dados forem conhecidos antecipadamente, posso comparar rapidamente meu predicado (cláusula WHERE ou critério JOIN) com os valores no índice e encontrar os registros desejados mais rapidamente .
Considere dois valores inteiros . Em um sistema de tipo dinâmico, eles podem ter tamanho variável (pense em Java
BigInteger
, ou inteiros de precisão arbitrária internos do Python). Se eu quiser comparar os números inteiros, primeiro preciso saber o tamanho dos bits. Esse é um aspecto da comparação de números inteiros, que é amplamente oculto pelas linguagens modernas, mas é muito real no nível da CPU. Se os tamanhos forem fixos e conhecidos com antecedência, uma etapa inteira será removida do processo. Novamente, os bancos de dados devem ser capazes de processar zilhões de transações o mais rápido possível. A velocidade é rei.O SQL foi projetado nos anos 70. Nos primeiros dias da microcomputação, a memória era um prêmio. A limitação de dados ajudou a manter os requisitos de armazenamento sob controle. Se um número inteiro nunca ultrapassa um byte, por que alocar mais armazenamento para ele? Isso é espaço desperdiçado na era da memória limitada. Mesmo nos tempos modernos, esses bytes extras desperdiçados podem adicionar e prejudicar o desempenho do cache de uma CPU. Lembre-se, esses são mecanismos de banco de dados que podem atender centenas de transações por segundo, não apenas seu pequeno ambiente de desenvolvimento.
Na linha de armazenamento limitado, é útil poder ajustar um único registro em uma única página na memória. Depois de percorrer uma página, há mais falhas de página e mais acesso à memória lento. Os mecanismos mais recentes têm otimizações para tornar isso menos um problema, mas ele ainda está lá. Ao dimensionar os dados adequadamente, você pode atenuar esse risco.
Nos tempos modernos, o SQL é usado para conectar-se a outros idiomas via ORM ou ODBC ou alguma outra camada. Algumas dessas linguagens têm regras sobre a exigência de tipos estáticos fortes. É melhor estar em conformidade com os requisitos mais rigorosos, pois as linguagens de tipo dinâmico podem lidar com tipos estáticos mais facilmente do que o contrário.
O SQL suporta digitação estática porque os mecanismos de banco de dados precisam dela para desempenho, como mostrado acima.
É interessante notar que existem implementações de SQL que não são fortemente tipadas. O SQLite é provavelmente o exemplo mais popular desse mecanismo de banco de dados relacional. Por outro lado, ele foi projetado para uso de thread único em um único sistema, de modo que as preocupações de desempenho podem não ser tão pronunciadas quanto em, por exemplo, um banco de dados Oracle corporativo que atende milhões de solicitações por minuto.
fonte
Indexes
, mais basicamente afirmado: ter um tipo de dados permite que o mecanismo de banco de dados compreenda os dados e faça comparações (números maiores / menores, datas anteriores / posteriores, antes / depois no alfabeto), e, portanto, permite classificar e consultar .Primeiro: o texto simples é binário (nem mesmo os caracteres UTF8 ou ASCII "0" e "1" são os bits ativados / desativados)
Dito isto, alguns dos motivos são:
fonte
É assim que o código subjacente no qual o banco de dados está gravado pode alocar e usar registros de tamanho fixo, se souber que um campo específico pode conter de 0 a 256 caracteres de texto, ele poderá alocar um bloco de 256 bytes para armazená-lo.
Isso torna as coisas muito mais rápidas, por exemplo, você não precisa alocar armazenamento adicional à medida que o usuário digita, pois um determinado campo sempre inicia x bytes no registro, uma pesquisa ou seleção nesse campo sabe sempre verificar x bytes em cada registro, etc.
fonte
Quando as colunas de um banco de dados recebem tipos definidos, os tipos geralmente são definidos como tendo um certo tamanho em bits. Como um resultado:
1) quando o mecanismo de banco de dados está percorrendo as linhas em uma tabela, ele não precisa fazer nenhuma análise sofisticada para determinar onde cada registro termina, basta saber que cada linha consiste em, digamos, 32 bytes e, portanto, para obter o No próximo registro, é suficiente adicionar 32 bytes ao local atual dos registros.
2) ao procurar um campo dentro de uma linha, é possível conhecer um deslocamento exato para esse campo novamente sem analisar nada, para que as pesquisas de coluna sejam uma operação aritmética simples e não uma operação de processamento de dados potencialmente dispendiosa.
fonte
Você perguntou por que os DBMSs têm tipos de dados estáticos.
Velocidade de pesquisa. O objetivo de um DBMS é armazenar muito mais dados do que você poderia carregar em um programa. Pense em "todos os recibos de cartão de crédito gerados no mundo nos últimos dez anos". Para pesquisar esses dados com eficiência, tipos de dados de comprimento fixo são úteis. Isso é especialmente verdadeiro para dados estruturados, como carimbos de data e números de conta. Se você sabe com o que está lidando com antecedência, é mais fácil carregar em índices eficientes.
Integridade e restrições. É mais fácil manter os dados limpos se houver tipos de dados fixos.
História. Os RDBMSs começaram quando os computadores tinham apenas alguns megabytes de RAM e o armazenamento em escala de terabytes era muito caro. Salvar uma dúzia de bytes em cada linha de uma tabela pode economizar milhares de dólares e horas nessas circunstâncias.
A maldição da base de clientes. Hoje, os RDBMSs são pacotes de software muito complexos, altamente otimizados e estão em uso há décadas acumulando dados. Eles são maduros. Eles trabalham. Um travamento do RDBMS que resulta em perda de dados em larga escala é extremamente raro atualmente. Mudar para algo com um sistema de digitação de dados mais flexível não vale o custo ou o risco para a maioria das organizações.
Analogia: pode ser óbvio que os sistemas de metrô urbanos funcionariam melhor (mais silenciosos, mais rápidos, mais eficientes em termos de energia) em uma bitola mais estreita. Mas como você vai mudar todos os trilhos do sistema de metrô de Nova York para obter essas melhorias? Você não é, então você otimiza o que tem.
fonte
Em geral, quanto mais detalhes você informar ao banco de dados sobre o que está armazenando, mais ele poderá tentar otimizar várias métricas de desempenho relacionadas a esses dados, como quanto espaço alocar no disco ou quanta memória alocar ao recuperá-lo. .
Não tenho certeza de qual banco de dados você está usando, então vou ter que adivinhar: eu acho que dois desses tipos de dados têm limites superiores, um deles não. O uso de tipos de dados para texto com limites superiores informa ao banco de dados quanto espaço de armazenamento será necessário para cada registro. Também é possível que alguns bancos de dados possuam maneiras diferentes de armazenar texto grande (possivelmente ilimitado) versus texto pequeno de tamanho fixo (isso pode variar de acordo com o banco de dados, consulte o manual para ver o seu).
Diferentes níveis de precisão requerem diferentes quantidades de armazenamento, e nem todo uso exige os mais altos graus de precisão. Por exemplo, consulte aqui: https://docs.oracle.com/cd/B28359_01/server.111/b28286/sql_elements001.htm#SQLRF50950
A Oracle possui vários tipos numéricos diferentes, com diferentes requisitos de armazenamento e recursos diferentes em termos de nível de precisão e tamanho do número que pode ser representado.
fonte
Até certo ponto, é histórico.
Era uma vez, dados tabulares eram armazenados em arquivos compostos por registros de comprimento fixo, por sua vez compostos por campos predefinidos, de modo que um determinado campo era sempre do mesmo tipo e no mesmo local de todos os registros. Isso tornou o processamento eficiente e limitou a complexidade da codificação.
Adicione alguns índices a esse arquivo e você terá o início de um banco de dados relacional.
À medida que os bancos de dados relacionais evoluíram, eles começaram a introduzir mais tipos de dados e opções de armazenamento, incluindo texto de tamanho variável ou campos binários. Porém, isso introduziu registros de tamanho variável e interrompeu a capacidade de localizar consistentemente registros via cálculo ou campos por meio de um deslocamento fixo. Não importa, as máquinas são muito mais poderosas hoje do que eram naquela época.
Às vezes, é útil definir um tamanho específico para um campo para ajudar a impor um pouco da lógica comercial - digamos 10 dígitos para um número de telefone norte-americano. Na maioria das vezes, é apenas um pouco do legado da computação.
fonte
Se um banco de dados usar registros de tamanho fixo, qualquer registro no banco de dados continuará a se ajustar, no mesmo local, mesmo que seu conteúdo seja alterado. Por outro lado, se um banco de dados tenta armazenar registros usando exatamente a quantidade de armazenamento necessária para seus campos, alterar o nome de Emma Smith para Emma Johnson pode fazer com que seu registro seja muito grande para caber no local atual. Se o registro for movido para algum lugar com espaço suficiente, qualquer índice que rastreie sua localização precisará ser atualizado para refletir o novo local.
Existem várias maneiras de reduzir o custo associado a essas atualizações. Por exemplo, se o sistema mantiver uma lista de números de registros e locais de dados, essa lista será a única coisa que precisaria ser atualizada se um registro se mover. Infelizmente, essas abordagens ainda têm um custo significativo (por exemplo, manter um mapeamento entre números e locais de registros exigiria que a recuperação de registros exigisse uma etapa extra para recuperar os dados associados a um determinado número de registro). O uso de registros de tamanho fixo pode parecer ineficiente, mas torna as coisas muito mais simples.
fonte
Para muito do que você faz como desenvolvedor da Web, não há necessidade de entender o que está acontecendo "oculto". Há momentos, no entanto, quando isso ajuda.
Como você suspeita, o motivo é a eficiência. As abstrações vazam . Uma consulta como
SELECT author FROM books
pode ser executada rapidamente quando o tamanho de todos os campos da tabela é conhecido.Como Joel diz,
Na maioria das vezes, você está trabalhando longe o suficiente dos fundamentos básicos para não precisar se preocupar com isso. Como um desenvolvedor da Web baseado em PHP, você se importa com quantas instruções de CPU seu código usa? Na maioria das vezes, não, na verdade não. Mas, às vezes, é útil saber, por dois motivos: pode explicar as decisões tomadas pelas suas bibliotecas; e às vezes você precisa se preocupar com a velocidade em seu próprio código.
fonte