Por que armazenar sinalizadores / enumerações em um banco de dados como seqüências de caracteres em vez de números inteiros?

29

Estive pesquisando lixões SQL de alguns CMSes famosos, incluindo Drupal 7, Wordpress (alguma versão muito antiga) e algum aplicativo personalizado baseado em Python.

Todos esses despejos continham dados com sinalizadores de seqüência de caracteres em vez de números inteiros. Por exemplo, o status de um posto foi representado como published, closedou inheritem vez de 1, 2ou 3.

Tenho uma experiência bastante limitada no design de bancos de dados e nunca passei por SQLs simples, mas sempre fui ensinado que deveria usar sinalizadores numéricos / inteiros para dados como esse. É óbvio que tinyintconsome muito menos espaço em um banco de dados do que, por exemplo varchar(9).

Então o que estou perdendo? Isso não é um desperdício de armazenamento de dados e uma redundância de dados? A navegação, a pesquisa e a indexação não seriam um pouco mais rápidas se essas colunas usassem números inteiros em vez de strings?

trejder
fonte
7
Você tem certeza de que eles realmente não usam dev.mysql.com/doc/refman/5.0/en/enum.html, que se parecerá com uma string no dump. De qualquer maneira, acho que hoje em dia isso conta quase como uma micro otimização.
Esben Skov Pedersen
2
Esta questão é fundamentalmente um apelo à autoridade.
DeadMG
3
Não é uma resposta completa, mas ... você conhece a linguagem de script Lua? Reconhecido por ser direto e de alto desempenho, usado para escrever mecanismos de jogos inteiros, etc? Surpreendentemente, eles nunca se incomodaram em ter um tipo de número. Seu código de manipulação de strings é tão eficaz que eles podem adicionar números que são realmente strings, no código do mecanismo de jogo sensível ao tempo. Como o JavaScript, eles nem sequer têm objetos - apenas tabelas de hash muito sofisticadas. A visão do programador C de "uma enorme variedade de chars? Quão ineficiente!" está desatualizado em comparação com 2015.
Katana314
2
Editado para remover a parte "apelo à autoridade" e reaberto-votado, pois a pergunta sobre o uso de strings em vez de ints é perfeitamente sobre o tópico, desde que não seja especificamente sobre essas "autoridades".
Ixrec 23/05

Respostas:

45

Sim, armazenar seqüências de caracteres em vez de números pode usar mais espaço. A razão pela qual plataformas de alto perfil estão fazendo isso de qualquer maneira é que eles acham que os benefícios dessa solução são maiores que o custo.

Quais são os benefícios? Você pode ler facilmente um despejo de banco de dados e entender o que se trata sem memorizar as tabelas enum, e até as GUIs semioficiais podem simplesmente usar os valores como temas em vez de transformar o registro que recebem. (Essa é uma forma básica de troca de espaço em disco / tempo de processamento.)

E o custo? A capacidade de armazenamento de dados não é o gargalo do CMS há muito tempo, pois os discos ficaram tão grandes e baratos. O tempo do programador, por outro lado, geralmente fica mais caro - portanto, qualquer coisa que troque esforços de desenvolvimento por espaço em disco também é uma coisa boa, da perspectiva dos negócios.

Kilian Foth
fonte
7

Sim, armazenar coisas como yesou trueocupará mais espaço do que um pouquinho. Isso não deveria ser surpreendente. Ele também torna a indexação e, portanto, se junta menos eficiente ao banco de dados. Também tem a penalidade de possível confusão pelo valor correto ( yesvs y).

Entretanto, existem muitas abordagens que parecem semelhantes ao armazenamento de strings no banco de dados (em particular o MySQL) que são eficientes.

Primeiro, o MySQL tem um enumtipo ( docs ) que pode se parecer muito com um conjunto de strings booleano ou restrito quando configurado dessa maneira. Também impõe que apenas valores válidos sejam inseridos. Este é muitas vezes muito mais útil do que o armazenamento 1, 2ou 3como um valor que o significado é transmitido com a informação. A enumeração vem com a penalidade de que uma alteração de esquema é necessária para adicionar ou remover tipos.

Isso nos leva a uma tabela filho e chaves estrangeiras (aplicáveis ​​a todos os bancos de dados). Sim, você está armazenando algum valor como uma chave (de volta ao 1, 2ou 3) e o valor de published, closede inheritsão armazenados em outra tabela. Usando uma visualização ( docs ), é possível fazer com que pareça que a tabela contém a sequência e não a chave. Isso tem a vantagem de que nenhuma mudança de esquema é necessária para adicionar ou remover entradas da tabela filha.

Exatamente como as coisas são armazenadas, seria necessário examinar o DDL real do esquema para determinar qual método é usado e obter uma dica de quais trocas eles selecionaram.


fonte