A fascinação por sequences de BD x UUIDs

Atenção, este blog foi migrado para: http://brunopereira.org

Uns tempos atrás eu pude constatar um fenômeno curioso. Existem pessoas fascinadas, apaixonadas por sequences de bancos de dados!! Ok,vou contextualizar.Sequences de bancos de dados são muitos boas para fazer o que elas foram inventadas para fazer: gerar seqüências numéricas inteiras. Claro, estes valores numéricos seqüenciais não se repetirão, então eles também PODEM ser utilizados como identificadores únicos de tabelas de bancos de dados (chaves primárias).

A questão é: chaves primárias oficialmente são identificadores únicos de registros no banco de dados. Não há nada especificado quanto a eles serem numéricos e muito menos seqüenciais.

Algumas pessoas argumentam que o fato de os identificadores serem seqüenciais ajuda a saber a ordem de criação dos registros no servidor. Isso é verdade, mas eu considero isto uma meta-informação sobre o registro em questão. Esta meta-informação não precisa estar gravada na chave primária. Se esta meta-informação sobre a ordem de criação no banco de dados é relevante para quem precisar analisar os dados, porque não criar uma coluna registrando a data de criação, outra com data da última modificação, etc? Impossível ser mais preciso quanto ao momento de criação e de alteração do que gravar o instante em que as coisas foram feitas com precisão de milisegundos.

Esta contextualização toda foi para chegar no ponto em que eu queria. Você conhece UUIDs? Desde que eu conheci UUIDs, não soube de nada mais indicado para ser utilizado como identificadores únicos de entidades, e em decorrência, como chaves primárias. Os UUIDs são valores numéricos de 128 bits, que possuem uma representação textual, da forma 9c7b8ee2-6f22-4dad-bdec-1266bb533ac6.

Já ouvi algumas vezes a frase de que o IPv6 possui quantidade suficiente de IPs para endereçar cada grão de areia do mundo. Pois é, o IPv6 e o UUID possuem 128 bits, então se você tem identificadores suficientes para cada grão de areia do mundo, acho que dá pra usar UUIDs com aquela sua tabelinha, não dá não?😉

Bom, agora preciso explicar porque eu acho melhor usar UUIDs como chaves primárias do que sequences de BD. Pra começo de conversa, o acesso ao sequence para obter um ID é muuuuuito mais lento que a geração de um UUID. Eu não tinha a exata noção do peso de acessar uma sequence, mas o Silvano descobriu junto com o pessoal de BD da Globo que em boa parte dos casos a query na sequence para obter um ID a ser colocado em um INSERT é mais lenta do que o próprio INSERT. Além disso, para gerar um UUID a sua própria aplicação consegue gerar. Nada de comunicação remota com o banco de dados.

Além de ser muito mais eficiente em termos de performance, existe a questão da migração de dados. Sempre que é necessário migrar bases de dados corporativos, uma das maiores dores de cabeça é gerenciar os conflitos de IDs gerados através de sequences. Além disso, em muitos casos o problema surge bem antes da necessidade de se migrar bancos de dados. Onde existe o conceito de sincronização de dados o uso de UUIDs faz muito mais sentido do que usar sequences. Sequences são muitas vezes impeditivos na verdade. Darei um exemplo.

No meu projeto do software para advogados, eu quero permitir que cada advogado use a aplicação em suas máquinas individuais. Suponha que o advogado Fulano cadastrou alguns processos, clientes, reuniões, etc em sua máquina. Suponha também que o sócio dele, o advogado Sicrano também fez alguns cadastros de processos, clientes, etc em sua máquina. Suponha agora que os 2 gostariam de compartilhar seus dados. Se as chaves primárias fossem sequences, isso significaria gravar na máquina do Sicrano os processos com IDs 1, 2, 3, 4… que foram cadastrados na máquina do Fulano e gravar na máquina do Fulano os processos com IDs 1, 2, 3, 4… cadastrados na máquina do Sicrano. Opa, não demorou muito pra ter conflito não é?? Agora, se os IDs fossem algo como 9c7b8ee2-6f22-4dad-bdec-1266bb533ac6, a sincronização seria moleza não é mesmo?

Esta questão da sincronização de dados é necessária para muitas aplicações. O Siebel (CRM comprado pela Oracle) possuía o conceito de usuários remotos e usuários normais. Os usuários normais faria tudo diretamente no servidor de produção. Os usuários remotos fariam o seu trabalho em um laptop se deslocando diariamente em seu trabalho e então sincronizariam suas atividades 1, 2 vezes por dia tipicamente. Impossível fazer isso com sequences. O Siebel usava chaves alfanuméricas geradas com um algoritmo próprio que eu não conheço, mas funcionava também. O UUID resolve facilmente este problema, e está disponível para qualquer um utilizar em boa parte das linguagens de programação.

Assim, o que quero concluir é: chaves primárias são identificadores únicos e pronto!! Porque as chaves primárias têm que ser números inteiros, seqüênciais e sem saltos entre eles?? A resposta é: elas não precisam!! Para ter meta-informações sobre os registros, defina as meta-informações que você quer e aborde isto explicitamente.

Bom, mais uma vez, não espero convencer ninguém, só dei a minha humilde opinião.😉

6 respostas para A fascinação por sequences de BD x UUIDs

  1. Fabiano Izabel disse:

    Brunão, sou fã de UUIDs e os implemento em 100% dos softwares que desenvolvo em regime freelancer, no lugar das chaves primarias. Sua abordagem é bastante interessante, principalmente se levarmos em consideração que alguns DBAs dinossauros (isto é quase um pleonasmo. hahaha), por cultura, tem a velha mania de economizar bits no armazenamento de dados, em função dos poucos recursos disponíveis quando os SGBDs começaram a todo vapor (quem usou um PC-AT DX2 486 sabe BEM o valor de 100MB de HD :)). Além disso, o UUID pode ser gerado em qualquer ponto da aplicação, inclusive pode ser armazenado em uma variável no momento anterior à persistência dos dados e ser utilizado como chave de tabelas relacionadas, evitando POGs do tipo “Ih, persisti sem guardar o valor do sequence … vou dar um select MAX() para buscar … “. hehehe

    Grande abraço!

  2. Silvano disse:

    Aproveito para lembrar que o próprio oracle é capaz de gerar os GUID automaticamente, através da função SYS_GUID (http://download-west.oracle.com/docs/cd/B10501_01/server.920/a96540/functions125a.htm#SQLRF06120).

    Existe também uma convenção quanto a geração: http://www.opengroup.org/onlinepubs/9629399/apdxa.htm

  3. blpsilva disse:

    Opa Silvano, legal saber da função do Oracle. Eu tô ligado que os servidores de bancos de dados são capazes de gerar os UUIDs, mas nunca usei esta funcionalidade deles. Bom saber desta função especificamente.

    Na minha aplicação de Advogados, o método que gera UUIDs fica numa classe utilitária e é assim:

    public static UUID generateUUID() {
    return UUID.randomUUID();
    }

  4. Shelly disse:

    Divide the dough ball and together with your hands, pat it firmly all around the tart molds.
    When the glue has set, cut every cork from the bunch, and trim away any excess paper.

  5. Regina disse:

    I do not even know how I ended up here, but I thought this post was
    great. I do not know who you are but definitely you are going to a famous blogger if you are not already😉 Cheers!

  6. wonderful submit, very informative. I wonder why the opposite
    specialists of this sector do not notice this.
    You should continue your writing. I am sure, you’ve a huge readers’ base already!

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: