CHAR para VARCHAR

Há muito tempo, em uma galáxia muito, muito distante… lá na era do COBOL, os dados eram armazenados de forma tabular e os dados eram armazenados em uma tabela onde cada coluna ocupava espaços fixos nessa tabela. Assim, o CEP ocupava a posição de 1 a 7, o número de 8 a 12, o logradouro de 13 a 33 e assim por diante. Quando criaram os bancos de dados relacionais foram criados, criaram tipos de dados para strings com tamanho fixo que funcionam de forma semelhante, o CHAR. Infelizmenteo CHAR armazena desnecessariamente espaços em branco e foi substituido posteriormente pelo VARCHAR que são strings com tamanho variável bem mais flexível e se tornou padrão.
Por motivos que não vem ao caso, muita gente ainda usa CHAR em bancos de dados. Vou demonstrar aqui de forma simples, como converter numa simples tabela um campo CHAR para VARCHAR pode economizar imediatamente 40% do espaço da tabela:

SQL
CREATE TABLE t (n integer, v char(100));
INSERT INTO t SELECT n, repeat('x',round(random()*100)::integer)       
    FROM generate_series(1,1000000) n;
SELECT * FROM t limit 10;
n | v
--+-------------------------------------------------------------------------------------
1 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
2 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
3 | xxxxxxx
4 | xxxxxxxxxxxxxx
5 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
6 | xxxxx
7 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
8 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
9 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
10 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
(10 rows)

\dt+ t
                List of relations
Schema | Name | Type  | Owner    | Size   | Description
-------+------+-------+----------+--------+-------------
public | t    | table | postgres | 135 MB |
(1 row)

ALTER TABLE t ALTER v TYPE varchar(100);
\dt+ t
               List of relations
Schema | Name | Type | Owner     | Size  | Description
-------+------+-------+----------+-------+-------------
public | t    | table | postgres | 83 MB |
(1 row)

Como se vê, a tabela, mesmo sem índices, caiu de 135MB para 83MB. Agora eu montei um script rápido para listar as tabelas com colunas do tipo CHAR:

SQL
SELECT n.nspname, c.relname, a.attname, a.attnum, atttypmod
FROM
    pg_type t
    JOIN pg_attribute a ON a.atttypid = t.oid
    JOIN pg_class c ON c.oid = a.attrelid
    JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE
    t.typname = 'bpchar' AND
    n.nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema')
ORDER BY 1,2,3
;

Por fim, montei um script para alterar todos os campos CHAR para VARCHAR, tomando o cuidado para alterar vários campos num único ALTER TABLE para não ter que reescrever tabelas mais de uma vez:

SQL
SELECT 
    'ALTER TABLE ' || n.nspname || '.' || c.relname || 
      string_agg ($$ ALTER $$ || a.attname || $$ TYPE varchar($$ || a.attnum || $$)$$,',') ||
      ';'
FROM
    pg_type t
    JOIN pg_attribute a ON a.atttypid = t.oid
    JOIN pg_class c ON c.oid = a.attrelid
    JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE
    t.typname = 'bpchar' AND
    a.attnum > 1 AND
    n.nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema')
GROUP BY n.nspname, c.relname
ORDER BY n.nspname, c.relname
;

Vale a recomendação: teste antes de usar isso em produção!

Compartilhe

Você pode gostar

pg_hba.conf

Introdução O arquivo pg_hba.conf (PostgreSQL Host-Based Authentication) é uma peça fundamental na configuração de segurança de qualquer instância PostgreSQL. Ele define as regras de autenticação

Tuning de SO (no Linux)

Introdução Tuning refere-se ao processo de ajustar e otimizar o desempenho de um sistema, software ou aplicação. A otimização do sistema operacional é uma etapa

Tipos de cargas dos bancos de dados

Introdução Cargas de dados referem-se aos diferentes tipos de operações e transações que um banco de dados deve processar. Essas cargas variam conforme o tipo

plugins premium WordPress