Problema
Pretendo carregar um CSV com mais de 10 milhões de registros no PostgreSQL v12.1, uma de suas colunas tem valores "categóricos", então criar um tipo enumerado para ele parece ser uma boa escolha, mas contém 208 categorias.
O campo mais curto tem 2 e o mais longo tem 11 caracteres. A média de todos os campos é 2,4. A codificação de caracteres é UTF8, mas todos os caracteres são ASCII .
Perguntas:
Qual tipo devo usar enumerated ou varchar ?
informação adicional
Eu descarto char porque a documentação oficial do PostgreSQL diz o seguinte sobre char , varchar e text :
Dica: Não há diferença de desempenho entre esses três tipos, além do aumento do espaço de armazenamento ao usar o tipo com preenchimento em branco e alguns ciclos extras de CPU para verificar o comprimento ao armazenar em uma coluna com restrição de comprimento. Embora o caractere(n) tenha vantagens de desempenho em alguns outros sistemas de banco de dados, não existe tal vantagem no PostgreSQL; na verdade, character(n) é geralmente o mais lento dos três devido aos seus custos adicionais de armazenamento. Na maioria das situações, a variação de texto ou caractere deve ser usada.
Um valor enum no PostgreSQL ocupa 4 bytes no disco (consulte 8.7.4. Detalhes de implementação). Considerando isso e o comprimento médio de string de 2,4 usando o tipo enum , levaria a um uso de disco um pouco maior (stings curtos no PostgreSQL precisam de um espaço em disco extra de byte). Ainda tenho a intuição de que usar enum é uma escolha melhor, pois sua implementação torna muitas operações mais rápidas contra ele.
Com uma média de 2,4 caracteres (mais relevante: avg bytes - mas isso é o mesmo para todos os caracteres ASCII), eu não me incomodaria em usar enums. Esses ocupam 4 bytes no disco mais, possivelmente, preenchimento de alinhamento. (
text
não requer preenchimento de alinhamento.) Você nem está economizando armazenamento e obtém mais sobrecarga por isso.Com a maioria dos valores abaixo de 7 caracteres (= 8 bytes no disco), um índice em uma
text
coluna de categoria também será apenas um pouco maior que um em um arquivoenum
. (O espaço para dados é (normalmente) alocado em múltiplos de 8 bytes.)Para um número fixo de 208 categorias, uma
"char"
codificação (não confundir comchar
!) pode ser uma opção para economizar armazenamento. Ver:Mas, novamente, não vale a pena para essas pequenas cordas. Basta usar
text
. Talvez imponha a correção com uma restrição FK para umacategory
tabela como:Também é um bom lugar para armazenar informações adicionais por categoria. E você pode modificar facilmente o conjunto de categorias. Faça a restrição FK
ON UPDATE CASCADE
e você poderá alterar os nomes das categorias em um local central. Faça issoON DELETE SET NULL
e você pode remover facilmente uma categoria. etc.Relacionado:
Apoio totalmente a resposta de Erwin, mas queria adicionar um aviso contra enums.
Enums são uma boa escolha se você tiver um número fixo de valores possíveis que nunca podem ser alterados (pelo menos deve haver uma garantia de que nenhum valor teria que ser removido).
Em todos os outros casos, você não deve usar enums: é impossível remover um valor enum depois de adicioná-lo.
Por exemplo, ao escolher um tipo de dados para uma coluna que contém um estado dos EUA, eu não escolheria uma enumeração - por mais improvável que seja, pode ser que um estado se separe ou que dois estados se unam.
Com base em como você descreve os dados, eu não recomendaria enums no seu caso.