Executando verificação de segurança...
6

Quando utilizar UUID e quando utilizar auto-increment?

Salve galerinha!

Hoje venho com uma singela dúvida, que sinceramente nunca parei muito pra pesquisar, mas quais as diferenças em aplicar o uso entre UUID e auto-increment?

Sei dos cases de segurança que o UUID traz, mas vocês podem me dizer em quais casos um auto-increment se sobressai? Ou deixando de lado qual é melhor ou pior, quando usar um ou outro?

Tamo junto meu povo!

Carregando publicação patrocinada...
5

Imagino que está falando de usar como chave primária em banco de dados.

Use o incremento até que prove que UUID é melhor. Mas precisa ser prova mesmo.

Segurança? Não, ele não dá. As pessoas têm essa ideia que ele dá porque a pessoa não pode adivinhar o próximo. Se a sua segurança é baseada nisso, comece a rezar. E se conseguir deixar seguro com UUID, então consegue também com sequencial.

O maior motivo para usar UUID é a distribuição, ou seja, você precisa criar o id fora do servidor que vai centralizar os dados ou os dados podem nunca ser centralizados, mas podem interagir sob o mesmo ambiente geral.

Ainda é possível ter algo distribuído e usar algo incrementado, mas nem sempre é a solução ideal, pode ter ineficiências e não atender todos os requisitos. Mas pode ser uma solução melhor, porque UUID também tem suas desvantagens.

Usar o que tem pronto, feito de forma correta (boa parte dos sistemas que tentam inventar algo diferente funciona 99%), eficiente e fácil, é sempre mais interessante, inclusive porque o sequencial facilita você, humano, chegar na informação e no grosso do tempo que precisa disso é melhor assim.

Sempre opte pelo simples e depois vá para o complexo se for provado que é melhor. Para isso você precisa ter todas as informações necessárias acerca do problema e enxergar a computação como um todo.

Alguns casos começa se fazer necessário usar UUID porque a tecnologia adotada exige. Isso em geral é um caso em que a tecnologia é ruim e não deveria ser adotada. Desde "sempre" se sabe que primeiro você traça os objetivos e requisitos, para depois adotar a tecnologia certa, mas está cada vez mais raro fazerem isso, e a pessoa adapta o problema para encaixar com a tecnologia que adotou.

Tem caso que é meio que um tanto faz. Se for algo mais bobo o UUID não causará grandes problemas, mas é uma solução pior. Sem ter grandes problemas a pessoa fica satisfeita, com o pior. Projetos pequenos aceitam erros mais facilmente.

Eu já respondi isso antes:

Faz sentido para você?

Espero ter ajudado.


Farei algo que muitos pedem para aprender a programar corretamente, gratuitamente. Para saber quando, me segue nas suas plataformas preferidas. Quase não as uso, não terá infindas notificações (links aqui).

1

Praticamente uma aula, muito obrigado pela resposta! Vou dar uma olhada em todos os links que disponibilizou e levar adiante quando possível em discussões iguais a essa.

2

Sempre que eu vejo uma discussão a respeito de UUID como chave de uma tabela, eu me lembro de uma apresentação excelente do rponte que começou no Gist, virou esse blog post e finalmente a apresentação que mencionei.

Eu particularmente só vejo vantagem no UUID quando a geração desses IDs são descentralizados e unificados em algum determinado momento.

Em bases de dados relacionais

Para quem faz uso apenas de ORMs e não estão acostumados a escrever consultas performáticas diretamente no SQL, não vai ver sentido em dizer que UUID são piores que identificadores numéricos.


Sei dos cases de segurança que o UUID traz...

Que "segurança" você se refere aqui?

1

Atualmente sempre considero o uso de um UUID como chave primária, primeiramente pela facilidade, ou seja, fica a cargo da aplicação a geração da chave primária e não de responsabilidade do banco fazer esse incrementação.
Porém o uso de UUID se você for conversar com um DBA ele irá mencionar que ele é péssimo na indexação como chave primária, tendo em vista isso, quando eu estou trabalhando e a chave primária é UUID e tem uma alta carga de dados que precisam ser indexados cronologicamente as inserções na base de dados eu considero essa implementação como fonte de geração de UUID, o exemplo é em C# mas pode ser aplicado em qualquer outra linguagem..
Resumidamente ele cria um UUID gerado pela data/hora do sistema, então conforme for inserindo vai sendo indexado cronologicamente de forma correta.

Acho que especialmente quando você expoe uma API para a internet, ou seja, que pessoas podem acessar sua api creio que devemos levar em consideração em não usar uma chave primária como inteiro pelo seguinte cenário..
Vamos supor que você expoe uma api que lista dados dos funcionário (vamos pensar que a PK é int e deve estar autenticado) e por alguma falha de segurança algum hacker conseguiu entrar dentro da rede de sua empresa e consegue realizar as requisições dentro da rede interna, ele tendo acesso a essa API e vendo que o final é um número incremental ele conseguiria extrair toda a base de dados por "força bruta", quando usado um UUID isso não seria possível...

Resumidamente, sempre estou tendo a preferência por UUIDs como PK, se for de extrema necessária a performance eu opto pela implementação de UUIDs sequenciais.

1

Ao longo da carreira ouvi muito dizer exatamente essa aplicação do UUID, pensando em algo que fique exposto, uma API pública ou uma página web que utiliza o identificador na url, expondo públicamente. Na minha concepção ambos os casos seriam problemáticos.

Obrigado por compartilhar o exemplo, pretendo replicar e salvar num gist pra sempre poder usar haha!

1

Quando vou começar um projeto, eu pego papelzinhos e escrevo neles:

  • GUID
  • incremental
  • prefixado
  • random
  • baseado na fé

Jogo eles pra cima e pego um. O que eu pegar, é o modelo de chave primária que vou usar.

1

O UUID é vantajoso em algumas situações, por exemplo

Gerar IDs sem preocupação com colisão

É muito baixa a possibilidade gerar dois UUIDs iguais quando se usa uma fonte randomica segura.

Dito isso, abre a possibilidade por exemplo de o teu frontend gerar IDs mesmo antes de salvar no banco de dados.

Isso permite por exemplo você gerar referências futuras a IDs que ainda nem foram criados, por exemplo:

Imagine um sistema de gerar roteiros turísticos, em que você exemplo em relações entre modelos, mas que você não quer salvar por partes.

Ou você quer um sistema complexo que consegue trabalhar offline e depois só sincronizar as alterações no banco.

Outro caso é criar segurança por obscuridade. Você pode não querer dar visibilidade ao usuário sobre a quantidade de pedidos que tem no seu sistema. Então ao invés de usar um id de pedido sequencial, você randomiza usando um UUID.

Torna impossível o cara tentar procurar um id "maximo" em um endpoint tipo pedidos/{id}.

Se você não conseguir enxergar uma vantagem no seu caso de uso, então não complique, rs.

1

Andei fazendo um estudo há um tempo atrás e cheguei a seguinte conclusão:

  • Não é bom utilizar UUID como chave primaria pois é mais lento para gerar os indices no banco de dados.
  • UUID é bom, pois dificulta de alguém mal intencionado descobrir o proximo item da sua base ou algo do tipo.
  • Pensando na utilização de um banco de dados relacional, podemos fazer o seguinte:
    1. Utilizar um id auto incremente nas tabelas.
    2. Utilizar em todas as tabelas um campo external_id, no qual é armazenado valores uuid e deve ser utilizado para expor nas APIs.
      Quando precisarmos buscar uma informação filtramos a partir deste external_id e com o registro em mãos utilizamos o id (que é um integer auto increment) para fazer as operações e relacionamentos necesários em nossos controllers e services.

Acho uma solução válida, caso alguém tenha uma objeção, esclareça os pontos por favor.

1

O id como primary key, é por padrão indexado para agilizar as buscas. Criar mais um campo external_id que também precisa ser indexado, pois será usado como parâmetro de busca, como api/usuario/{external_id}, não seria estranho, já que a primary key já poderia ser o external_id?

0

Uso UUID em chaves primárias e considero uma boa prática.
Participei de algumas discussões sobre o assunto e o que mais se falava lá pelo ano de 2008 era a questão de velocidade em indexação, pelo tamanho da chave .
Eu, particularmente, não consigo ver muita diferença a ponto de ser relevante . Mas, minhas bases de dados são relativamente pequenas, uns 30 GB no máximo, com uns 50 ou 60 milhões de registros. Tudo funciona a contento.
Para mim, não vejo necessidade em usar autoincrenento. Nos casos em que preciso controlar números sequenciais, prefiro usar uma tabela com id e sequência e controlo programáticamente. Isso é útil, principalmente para números que não podem pular sequência, como notas fiscais, número de pedidos, número do item na nota, etc.

1

Exatamente, nos projetos em que trabalhei, e trabalho, sempre usamos UUID, por isso me veio a dúvida do nada, mas realmente muito se fala, ou se falava, sobre a velocidade e também a escalabilidade caso a base fique muito grande, porém nunca vi na prátia algo tão gigante ao ponto que o UUID fosse um empecilho

1

Sei que o SQL Server trata internamento os UUID como inteiros, então essa questão de indexação lenta pelo tamanho da chave é contornada lá. Não pesquisei sobre outros bancos.