Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Armazenando dados codificados em base64 como tipo de dados BLOB ou TEXT

Não se deve armazenar dados codificados em Base64 no banco de dados...


Base64 é uma codificação na qual dados binários arbitrários são representados usando apenas caracteres de texto imprimíveis:foi projetado para situações em que esses dados binários precisam ser transferidos por meio de um protocolo ou meio que pode lidar apenas com texto imprimível (por exemplo, SMTP/email). Aumenta o tamanho dos dados (em 33%) e adiciona o custo computacional de codificação/decodificação, portanto, deve ser evitado, a menos que seja absolutamente necessário.

Por outro lado, todo o ponto de BLOB colunas é que elas armazenam strings binárias opacas . Então vá em frente e armazene suas coisas diretamente em seu BLOB colunas sem primeiro codificá-las em Base64. (Dito isso, se o MySQL tiver um tipo mais adequado para os dados específicos que estão sendo armazenados, você pode usar isso:por exemplo, arquivos de texto como fontes JavaScript podem se beneficiar de serem armazenados em TEXT colunas para as quais o MySQL rastreia nativamente metadados específicos de texto - mais sobre isso abaixo).

A ideia (errônea) de que bancos de dados SQL exigem codificações de texto imprimíveis como Base64 para lidar com dados binários arbitrários foi perpetuada por um grande número de tutoriais mal informados. Essa ideia parece estar baseada na crença errônea de que, como o SQL compreende apenas texto imprimível em outros contextos, certamente também deve exigi-lo para dados binários (pelo menos para transferência de dados, se não para armazenamento de dados). Isso simplesmente não é verdade:o SQL pode transmitir dados binários de várias maneiras, incluindo literais de string simples (desde que sejam devidamente citados e escapados como qualquer outra string); é claro, a maneira preferida de passar dados (de qualquer tipo) para seu banco de dados é através de consultas parametrizadas, e os tipos de dados de seus parâmetros podem facilmente ser strings binárias brutas como qualquer outra coisa.

...a menos que seja armazenado em cache por motivos de desempenho...


A única situação em que pode haver algum benefício de armazenar dados codificados em Base64 é quando eles são geralmente transmitidos por um protocolo que exige tal codificação (por exemplo, por anexo de e-mail) imediatamente após sendo recuperado do banco de dados - nesse caso, armazenar a representação codificada em Base64 evitaria a necessidade de executar a operação de codificação nos dados brutos em cada busca.

No entanto, observe que o armazenamento codificado em Base64 está apenas agindo como um cache , muito parecido com o armazenamento de dados desnormalizados por motivos de desempenho.

... nesse caso deve ser TEXT não BLOB


Como mencionado acima:a única diferença entre TEXT e BLOB colunas é que, para TEXT colunas, o MySQL também rastreia metadados específicos de texto (como codificação de caracteres e coleção ) para você. Esses metadados adicionais permitem que o MySQL converta valores entre conjuntos de caracteres de armazenamento e conexão (quando apropriado) e execute operações de comparação/classificação de strings sofisticadas.

De um modo geral:se dois clientes trabalhando em conjuntos de caracteres diferentes devem ver os mesmos bytes , então você quer um BLOB coluna; se eles virem os mesmos caracteres então você quer um TEXT coluna.

Com Base64, esses dois clientes devem descobrir que os dados decodificam para os mesmos bytes; mas eles devem ver que os dados armazenados/codificados têm os mesmos caracteres . Por exemplo, suponha que se deseja inserir a codificação Base64 de 'Hello world!' (que é 'SGVsbG8gd29ybGQh' ). Se o aplicativo de inserção estiver funcionando no conjunto de caracteres UTF-8, ele enviará a sequência de bytes 0x53475673624738676432397962475168 ao banco de dados.

  • se essa sequência de bytes estiver armazenada em um BLOB coluna e posteriormente recuperado por um aplicativo que está funcionando em UTF-16, os mesmos bytes será retornado—que representa '升噳扇㡧搲㥹扇全' e não o valor codificado em Base64 desejado; enquanto que

  • se essa sequência de bytes estiver armazenada em um TEXT coluna e posteriormente recuperado por um aplicativo que está trabalhando em UTF-16, o MySQL irá transcodificar dinamicamente para retornar a sequência de bytes 0x0053004700560073006200470038006700640032003900790062004700510068 —que representa o valor original codificado em Base64 'SGVsbG8gd29ybGQh' como desejado.

Claro, você pode usar BLOB colunas e rastrear a codificação de caracteres de alguma outra forma - mas isso apenas reinventaria a roda desnecessariamente, com complexidade de manutenção adicional e risco de introdução de erros não intencionais.