Skip to content

Instantly share code, notes, and snippets.

@avandrevitor
Forked from rponte/using-uuid-as-pk.md
Created February 25, 2021 20:04
Show Gist options
  • Select an option

  • Save avandrevitor/fd1b7dadd40f64debfba078a85d1bbd6 to your computer and use it in GitHub Desktop.

Select an option

Save avandrevitor/fd1b7dadd40f64debfba078a85d1bbd6 to your computer and use it in GitHub Desktop.

Revisions

  1. @rponte rponte revised this gist Dec 31, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion using-uuid-as-pk.md
    Original file line number Diff line number Diff line change
    @@ -65,7 +65,7 @@ Favoreça um modelo hibrido

    Nem oito nem oitenta, já dizia minha mãe.

    Na minha opinião, se possível, **favoreça o uso de `Int/BigInt` para IDs internos do banco de dados (PKs e FKs), e use uma coluna do tipo `UUID` como ID externo (por exemplo `external_id`)**. Essa forma hibrida possibilita seu que sistema continue tirando o melhor proveito do seu RDBMS ao mesmo tempo que possibilita ter um ID opaco (segurança).
    Na minha opinião, se possível, **favoreça o uso de `Int/BigInt` para IDs internos do banco de dados (PKs e FKs), e use uma coluna do tipo `UUID` como ID externo (por exemplo `external_id`)**. Essa forma hibrida possibilita que seu sistema continue tirando o melhor proveito do seu RDBMS ao mesmo tempo que possibilita ter um ID opaco (segurança).

    Essa abordagem não só minimiza o impacto no uso de `UUID` como também oferece vantagens interessantes:

  2. @rponte rponte revised this gist Dec 31, 2020. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions using-uuid-as-pk.md
    Original file line number Diff line number Diff line change
    @@ -9,17 +9,17 @@ TL;TD
    Um pouco mais de detalhes
    -------------------------

    Usar `UUID` como tipo numa PK (Primary Key) em vez de `Int/BigInt` **em bancos de dados relacionais (RDBMS)** parece ter se tornado comum em aplicações nesse mundo de APIs REST, microsserviços e sistemas distribuídos, afinal temos algumas boas vantagens nessa abordagem:
    Usar `UUID` como tipo numa PK (Primary Key) em vez de `Int/BigInt` **em bancos de dados relacionais (RDBMS)** parece ter se tornado comum em aplicações nesse mundo de APIs REST, [microsserviços e sistemas distribuídos](https://youtu.be/uoLTYZL6qWo?list=PLHMMERsvy9EyWQPru4SrJAYHEGKfkjRgP&t=658), afinal temos algumas boas vantagens nessa abordagem:

    - segurança: IDs opacos para expor em APIs REST;
    - geração de IDs descentralizados: assim browsers, clients e serviços, apps, outros bancos podem gerar IDs únicos;
    - geração de IDs descentralizados: assim browsers, clients e serviços, apps mobile e outros bancos podem gerar IDs únicos;
    - ideal em DBs distribuídos ou com múltiplos nodes de escrita;
    - são ótimos para tabelas temporárias ou ao fazer merge entre bancos;
    - super útil em migração entre DBs (evita colisão);
    - seu uso em batch processing pode melhorar substancialmente o throughput;
    - comuns em cenários de replicação de dados;

    Vantagens existem e são várias, mas há um custo: **impacto direto na escrita e na leitura**.
    Vantagens existem e são várias, especialmente em cenários distribuídos, mas há um custo: **impacto direto na escrita e na leitura** do seu banco de dados.

    Apesar desse custo depender de N fatores como banco de dados e versão utilizada, setup e tuning, workload, hardware etc, não dá para ignorar que ao usar `UUID` como PK nós estamos tentando resolver um problema de 4 bytes (32 bits) com 16 bytes (128 bits)! É 4x mais problema para inserir, ler e armazenar!

  3. @rponte rponte revised this gist Dec 31, 2020. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion using-uuid-as-pk.md
    Original file line number Diff line number Diff line change
    @@ -73,7 +73,8 @@ Essa abordagem não só minimiza o impacto no uso de `UUID` como também oferece
    - não precisamos necessariamente de um index na coluna;
    - podemos usar um index do tipo [HASH em vez de BTREE (funciona melhor para queries de comparação por igualdade)](http://www.savepoint.blog.br/2018/02/17/chaves-artificiais-no-postgresql-desempenho/);
    - não “espalhamos” o `UUID` pelas FKs de outras tabelas;
    - ocupamos menos espaço em disco, afinal temos menos FKs com `UUID`s;
    - ocupamos menos espaço em disco e memoria, afinal os indices param de referenciar `UUIDs`;
    - com menos dados conseguimos **operar nosso workload em memoria** (e isso por si só já é uma melhoria brutal);
    - podemos fazer tuning apropriado na coluna de acordo com nosso workload;
    - permitimos que o banco trabalhe melhor via PK/FK sequencial em JOINs, agregações e ordenações;
    - excelente para schemas existentes ou legados;
  4. @rponte rponte revised this gist Dec 30, 2020. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions using-uuid-as-pk.md
    Original file line number Diff line number Diff line change
    @@ -23,7 +23,7 @@ Vantagens existem e são várias, mas há um custo: **impacto direto na escrita

    Apesar desse custo depender de N fatores como banco de dados e versão utilizada, setup e tuning, workload, hardware etc, não dá para ignorar que ao usar `UUID` como PK nós estamos tentando resolver um problema de 4 bytes (32 bits) com 16 bytes (128 bits)! É 4x mais problema para inserir, ler e armazenar!

    Conhecer e entender as principais devantagens (trade-offs) é importante antes de bater o martelo. A verdade, é que praticamente todos os RDBMS modernos apresentam algum tipo de problema ou limitação no uso de `UUID` como PK, apesar da maioria destes problemas poderem ser contornados ou minimizados através de setup ou tuning apropriado, e é justamente nesse momento que o papel de um DBA no time brilha.
    Conhecer e entender as principais devantagens (trade-offs) é importante antes de bater o martelo. A verdade, é que praticamente todos os RDBMS modernos apresentam algum tipo de problema ou limitação no uso de `UUID` como PK, apesar da maioria destes problemas poderem ser contornados ou minimizados através de analise, setup ou tuning apropriado. E é justamente nesse momento de fazer essa analise e tuning que o papel de um DBA no time brilha.

    Para não me alongar mais, segue alguns desses trade-offs:

    @@ -56,7 +56,7 @@ Em 2012 o Instagram precisou distriuir seu banco de dados (fazer sharding) para

    Um pouco antes, em 2010, o Twitter também precisou gerar IDs únicos entre suas instâncias de MySQL e o banco de dados Cassandra, e para isso optou por um [serviço distribuído de geração de IDs](https://blog.twitter.com/engineering/en_us/a/2010/announcing-snowflake.html), que por sinal foi criado por eles e recebeu o nome de **Snowflake**. Assim como o Instagram, a equipe do Twitter seguiu por esse caminho pois era importante que os IDs gerados fossem ordenáveis e tivessem o tamanho de 64 bits.

    Nesse mundo de microsserviços e sistemas distribuídos, geralmente cada serviço possui um banco isolado e independente que possui um schema pequeno, enxuto e com baixa volumetria de dados, então, na minha percepção, as chances de problemas são bem menores no uso de `UUID` como PK! **Afinal, o estilo arquitetural escolhido já distribui por natureza a massa de dados entre as dezenas ou milhares de serviços**. Mas não se engane, se há chances do volume de dados crescer em um intervalo curto de tempo então talvez seja melhor refletir e discutir com seu DBA sobre sua adoção.
    Nesse mundo de microsserviços e sistemas distribuídos, geralmente cada serviço possui um banco isolado e independente que possui um schema pequeno, enxuto e com baixa volumetria de dados, o que acaba por minimizar as chances de problemas ao adotar `UUID` como PK! Afinal, o estilo arquitetural escolhido já **distribui por natureza a massa de dados** entre as dezenas ou milhares de serviços. Mas não se engane, se há chances do volume de dados crescer em um intervalo curto de tempo então talvez seja melhor refletir e discutir com seu DBA sobre sua adoção.

    Em muitos cenários, nem todas as tabelas precisam ser expostas para sistemas externos, portanto ao adotar `UUID` como PK atente-se a dar preferência somente às tabelas que precisam mostrar a cara pro mundo a fora, dessa forma minimiza-se o impacto no restante do sistema.

  5. @rponte rponte revised this gist Dec 30, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion using-uuid-as-pk.md
    Original file line number Diff line number Diff line change
    @@ -56,7 +56,7 @@ Em 2012 o Instagram precisou distriuir seu banco de dados (fazer sharding) para

    Um pouco antes, em 2010, o Twitter também precisou gerar IDs únicos entre suas instâncias de MySQL e o banco de dados Cassandra, e para isso optou por um [serviço distribuído de geração de IDs](https://blog.twitter.com/engineering/en_us/a/2010/announcing-snowflake.html), que por sinal foi criado por eles e recebeu o nome de **Snowflake**. Assim como o Instagram, a equipe do Twitter seguiu por esse caminho pois era importante que os IDs gerados fossem ordenáveis e tivessem o tamanho de 64 bits.

    Nesse mundo de microsserviços e sistemas distribuídos, geralmente cada serviço possui um banco isolado e independente que possui um schema pequeno, enxuto e com baixa volumetria de dados, então, na minha percepção, as chances de problemas são bem menores no uso de `UUID` como PK! Afinal, o estilo arquitetural escolhido já distribui por natureza a massa de dados entre as dezenas ou milhares de serviços. Mas não se engane, se há chances do volume de dados crescer em um intervalo curto de tempo então talvez seja melhor refletir e discutir com seu DBA sobre sua adoção.
    Nesse mundo de microsserviços e sistemas distribuídos, geralmente cada serviço possui um banco isolado e independente que possui um schema pequeno, enxuto e com baixa volumetria de dados, então, na minha percepção, as chances de problemas são bem menores no uso de `UUID` como PK! **Afinal, o estilo arquitetural escolhido já distribui por natureza a massa de dados entre as dezenas ou milhares de serviços**. Mas não se engane, se há chances do volume de dados crescer em um intervalo curto de tempo então talvez seja melhor refletir e discutir com seu DBA sobre sua adoção.

    Em muitos cenários, nem todas as tabelas precisam ser expostas para sistemas externos, portanto ao adotar `UUID` como PK atente-se a dar preferência somente às tabelas que precisam mostrar a cara pro mundo a fora, dessa forma minimiza-se o impacto no restante do sistema.

  6. @rponte rponte revised this gist Dec 30, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion using-uuid-as-pk.md
    Original file line number Diff line number Diff line change
    @@ -40,7 +40,7 @@ Para não me alongar mais, segue alguns desses trade-offs:

    O problema não é o uso do tipo `UUID` em si, mas sim utilizá-lo como chave primária em tabelas do banco de dados. O que estou querendo dizer, é que, desenhar uma feature seguindo deliberadamente essa abordagem costuma ser responsável e fazer muito sentido, mas adotá-la cegamente para [**TODAS** as tabelas do seu schema é muito perigoso](https://tomharrisonjr.com/uuid-or-guid-as-primary-keys-be-careful-7b2aa3dcb439)!

    Muitas vezes, esse tipo de design é utilizado como um "shortcut" (atalho) para facilitar a vida dos devs na hora de expor suas entidades em APIs REST, mas que joga todo o onus da manutenção para o time de infra, DBAs e muitas vezes para própria empresa, como comprar mais disco ou substituir hardware. Além disso, um ID opaco só resolve [parte do problema de segurança](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/05-Authorization_Testing/04-Testing_for_Insecure_Direct_Object_References), pois ainda se faz necessário [validações de acesso e propriedade dos dados](https://cheatsheetseries.owasp.org/cheatsheets/Insecure_Direct_Object_Reference_Prevention_Cheat_Sheet.html#additional-remarks), que geralmente é a parte mais chata de se implementar.
    Muitas vezes, esse tipo de design é utilizado como um "shortcut" (atalho) para facilitar a vida dos devs na hora de expor suas entidades em APIs REST, mas que joga todo o onus da manutenção para o time de infra, DBAs e muitas vezes para própria empresa, como comprar mais disco ou substituir hardware. Além disso, **um ID opaco só resolve [parte do problema de segurança](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/05-Authorization_Testing/04-Testing_for_Insecure_Direct_Object_References)**, pois ainda se faz necessário [validações de acesso e propriedade dos dados](https://cheatsheetseries.owasp.org/cheatsheets/Insecure_Direct_Object_Reference_Prevention_Cheat_Sheet.html#additional-remarks), que geralmente é a parte mais chata de se implementar.

    Não me entenda errado, não é que esse tipo de solução não funcione, ela vai funcionar, mas como meu amigo [Raul Oliveira](https://twitter.com/rauldoliveira) me disse uma vez:
    > Eh como fazer caminhada plantando bananeira. Da pra fazer, vai concluir, gastar mais energia. Mas eh uma boa ideia?
  7. @rponte rponte revised this gist Dec 30, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion using-uuid-as-pk.md
    Original file line number Diff line number Diff line change
    @@ -35,7 +35,7 @@ Para não me alongar mais, segue alguns desses trade-offs:
    - [PostgreSQL e impacto na escrita e leitura](http://www.savepoint.blog.br/2018/02/17/chaves-artificiais-no-postgresql-desempenho/);
    - [PostgreSQL e Write Amplification](https://github.com/uuidjs/uuid/issues/303#issuecomment-575992079);
    - [MySQL e clustered indexes](https://www.percona.com/blog/2019/11/22/uuids-are-popular-but-bad-for-performance-lets-discuss/);
    - [MS SQL Server e clustered indexes](https://www.mssqltips.com/sqlservertip/1600/auto-generated-sql-server-keys-with-the-uniqueidentifier-or-identity/)
    - [MS SQL Server e clustered indexes (sofre do mesmo mal do MySQL)](https://www.mssqltips.com/sqlservertip/1600/auto-generated-sql-server-keys-with-the-uniqueidentifier-or-identity/);
    - [Oracle e impacto de performance](https://franckpachot.medium.com/uuid-aka-guid-vs-oracle-sequence-number-ab11aa7dbfe7);

    O problema não é o uso do tipo `UUID` em si, mas sim utilizá-lo como chave primária em tabelas do banco de dados. O que estou querendo dizer, é que, desenhar uma feature seguindo deliberadamente essa abordagem costuma ser responsável e fazer muito sentido, mas adotá-la cegamente para [**TODAS** as tabelas do seu schema é muito perigoso](https://tomharrisonjr.com/uuid-or-guid-as-primary-keys-be-careful-7b2aa3dcb439)!
  8. @rponte rponte revised this gist Dec 30, 2020. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion using-uuid-as-pk.md
    Original file line number Diff line number Diff line change
    @@ -34,7 +34,8 @@ Para não me alongar mais, segue alguns desses trade-offs:
    - pode piorar? claro, basta armazenar seu o `UUID` como texto no banco;
    - [PostgreSQL e impacto na escrita e leitura](http://www.savepoint.blog.br/2018/02/17/chaves-artificiais-no-postgresql-desempenho/);
    - [PostgreSQL e Write Amplification](https://github.com/uuidjs/uuid/issues/303#issuecomment-575992079);
    - [MySQL e clustered indexes (MSSQL Server também sofre desse mal)](https://www.percona.com/blog/2019/11/22/uuids-are-popular-but-bad-for-performance-lets-discuss/);
    - [MySQL e clustered indexes](https://www.percona.com/blog/2019/11/22/uuids-are-popular-but-bad-for-performance-lets-discuss/);
    - [MS SQL Server e clustered indexes](https://www.mssqltips.com/sqlservertip/1600/auto-generated-sql-server-keys-with-the-uniqueidentifier-or-identity/)
    - [Oracle e impacto de performance](https://franckpachot.medium.com/uuid-aka-guid-vs-oracle-sequence-number-ab11aa7dbfe7);

    O problema não é o uso do tipo `UUID` em si, mas sim utilizá-lo como chave primária em tabelas do banco de dados. O que estou querendo dizer, é que, desenhar uma feature seguindo deliberadamente essa abordagem costuma ser responsável e fazer muito sentido, mas adotá-la cegamente para [**TODAS** as tabelas do seu schema é muito perigoso](https://tomharrisonjr.com/uuid-or-guid-as-primary-keys-be-careful-7b2aa3dcb439)!
  9. @rponte rponte revised this gist Dec 29, 2020. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions using-uuid-as-pk.md
    Original file line number Diff line number Diff line change
    @@ -55,9 +55,9 @@ Em 2012 o Instagram precisou distriuir seu banco de dados (fazer sharding) para

    Um pouco antes, em 2010, o Twitter também precisou gerar IDs únicos entre suas instâncias de MySQL e o banco de dados Cassandra, e para isso optou por um [serviço distribuído de geração de IDs](https://blog.twitter.com/engineering/en_us/a/2010/announcing-snowflake.html), que por sinal foi criado por eles e recebeu o nome de **Snowflake**. Assim como o Instagram, a equipe do Twitter seguiu por esse caminho pois era importante que os IDs gerados fossem ordenáveis e tivessem o tamanho de 64 bits.

    Nesse mundo de microsserviços, geralmente cada serviço possui um banco isolado e independente que possui um schema pequeno, enxuto e com baixa volumetria de dados, então, na minha percepção, as chances de problemas são bem menores no uso de `UUID` como PK! Mas não se engane, se há chances do volume de dados crescer em um intervalo curto de tempo então talvez seja melhor refletir e discutir com seu DBA sobre sua adoção.
    Nesse mundo de microsserviços e sistemas distribuídos, geralmente cada serviço possui um banco isolado e independente que possui um schema pequeno, enxuto e com baixa volumetria de dados, então, na minha percepção, as chances de problemas são bem menores no uso de `UUID` como PK! Afinal, o estilo arquitetural escolhido já distribui por natureza a massa de dados entre as dezenas ou milhares de serviços. Mas não se engane, se há chances do volume de dados crescer em um intervalo curto de tempo então talvez seja melhor refletir e discutir com seu DBA sobre sua adoção.

    Outro detalhe importante, nem todas as tabelas precisam ser expostas para sistemas externos, portanto ao adotar `UUID` como PK atente-se a dar preferência somente para tabelas que precisam ser vistas por sistemas terceiros, dessa forma minimiza-se o impacto no restante do sistema.
    Em muitos cenários, nem todas as tabelas precisam ser expostas para sistemas externos, portanto ao adotar `UUID` como PK atente-se a dar preferência somente às tabelas que precisam mostrar a cara pro mundo a fora, dessa forma minimiza-se o impacto no restante do sistema.

    Favoreça um modelo hibrido
    -------------------------
  10. @rponte rponte revised this gist Dec 29, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion using-uuid-as-pk.md
    Original file line number Diff line number Diff line change
    @@ -84,7 +84,7 @@ Concluindo

    Provavelmente eu falei alguma groselha, então não se acanhe em me corrigir ou dar um toque!

    Embora eu tenha sugerido o modelo hibrido, você não precisa adotá-lo ou mesmo considerar que usar `UUID` como PK seja errado, **pois não é**! Se está funcionando para você então está tudo bem, continue utilizando, afinal no **seu contexto** fez (e ainda faz) sentido seguir essa abordagem. O importante aqui é que você não ignore os trade-offs, pois em algum momento eles podem voltar para assombrar você e sua equipe!
    Embora eu tenha sugerido o modelo hibrido, você não precisa adotá-lo ou mesmo considerar que usar `UUID` como PK seja errado, **pois não é**! Se está funcionando para você então está tudo bem, continue utilizando, afinal no **seu contexto** fez (e ainda faz) sentido seguir essa abordagem. O importante aqui é que os trade-offs estejam claros em cima da mesa, caso contrário em algum momento eles podem voltar para assombrar você e sua equipe!

    Acredito que existem outras vantagens e desvantagens na adoção de `UUID` como chave primária, afinal [esse tipo de problema não é de hoje](https://blog.codinghorror.com/primary-keys-ids-versus-guids/), então, caso você lembre de mais algum pró ou mesmo contra, ou um outro contexto interessante não deixe de comentar e compartilhar sua experiência. Com certeza eu posso aprender muito mais e melhor com a sua experiência e de outros.

  11. @rponte rponte revised this gist Dec 29, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion using-uuid-as-pk.md
    Original file line number Diff line number Diff line change
    @@ -84,7 +84,7 @@ Concluindo

    Provavelmente eu falei alguma groselha, então não se acanhe em me corrigir ou dar um toque!

    Embora eu tenha sugerido o modelo hibrido, você não precisa adotá-lo ou mesmo considerar que usar `UUID` como PK seja errado, não é! Se está funcionando para você então está tudo bem, continue utilizando, afinal no **seu contexto** fez (e ainda faz) sentido seguir essa abordagem. O importante aqui é que você não ignore os trade-offs, pois em algum momento eles podem voltar para assombrar você e sua equipe!
    Embora eu tenha sugerido o modelo hibrido, você não precisa adotá-lo ou mesmo considerar que usar `UUID` como PK seja errado, **pois não é**! Se está funcionando para você então está tudo bem, continue utilizando, afinal no **seu contexto** fez (e ainda faz) sentido seguir essa abordagem. O importante aqui é que você não ignore os trade-offs, pois em algum momento eles podem voltar para assombrar você e sua equipe!

    Acredito que existem outras vantagens e desvantagens na adoção de `UUID` como chave primária, afinal [esse tipo de problema não é de hoje](https://blog.codinghorror.com/primary-keys-ids-versus-guids/), então, caso você lembre de mais algum pró ou mesmo contra, ou um outro contexto interessante não deixe de comentar e compartilhar sua experiência. Com certeza eu posso aprender muito mais e melhor com a sua experiência e de outros.

  12. @rponte rponte revised this gist Dec 29, 2020. 1 changed file with 4 additions and 2 deletions.
    6 changes: 4 additions & 2 deletions using-uuid-as-pk.md
    Original file line number Diff line number Diff line change
    @@ -84,6 +84,8 @@ Concluindo

    Provavelmente eu falei alguma groselha, então não se acanhe em me corrigir ou dar um toque!

    Certamente existem outras vantagens e desvantagens na adoção de `UUID` como chave primária, afinal [esse tipo de problema não é de hoje](https://blog.codinghorror.com/primary-keys-ids-versus-guids/), então, caso lembre de mais algum pró ou mesmo contra, ou um contexto interessante não deixe de comentar. Com certeza posso aprender muito mais e melhor com a sua experiência e de outros.
    Embora eu tenha sugerido o modelo hibrido, você não precisa adotá-lo ou mesmo considerar que usar `UUID` como PK seja errado, não é! Se está funcionando para você então está tudo bem, continue utilizando, afinal no **seu contexto** fez (e ainda faz) sentido seguir essa abordagem. O importante aqui é que você não ignore os trade-offs, pois em algum momento eles podem voltar para assombrar você e sua equipe!

    Enfim, resolvi escrever esse gist por causa dessa [thread no twitter](https://twitter.com/edgarberlinck/status/1342831389255868416?s=20) e para não esquecer detalhes desse tópico!
    Acredito que existem outras vantagens e desvantagens na adoção de `UUID` como chave primária, afinal [esse tipo de problema não é de hoje](https://blog.codinghorror.com/primary-keys-ids-versus-guids/), então, caso você lembre de mais algum pró ou mesmo contra, ou um outro contexto interessante não deixe de comentar e compartilhar sua experiência. Com certeza eu posso aprender muito mais e melhor com a sua experiência e de outros.

    Enfim, resolvi escrever esse gist por causa dessa [thread no twitter](https://twitter.com/edgarberlinck/status/1342831389255868416?s=20) e para ajudar o "Rafael do futuro"a não esquecer detalhes sobre este tópico!
  13. @rponte rponte revised this gist Dec 29, 2020. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions using-uuid-as-pk.md
    Original file line number Diff line number Diff line change
    @@ -75,6 +75,7 @@ Essa abordagem não só minimiza o impacto no uso de `UUID` como também oferece
    - ocupamos menos espaço em disco, afinal temos menos FKs com `UUID`s;
    - podemos fazer tuning apropriado na coluna de acordo com nosso workload;
    - permitimos que o banco trabalhe melhor via PK/FK sequencial em JOINs, agregações e ordenações;
    - excelente para schemas existentes ou legados;

    Provavelmente existem outras vantagens nessa abordagem, mas meu pouco conhecimento sobre RDBMS não me permite pensar mais longe nesse momento. De qualquer forma, não esqueça de consultar seu DBA, fazer alguns testes de carga e entender os limites da sua aplicação!

  14. @rponte rponte revised this gist Dec 29, 2020. 1 changed file with 14 additions and 11 deletions.
    25 changes: 14 additions & 11 deletions using-uuid-as-pk.md
    Original file line number Diff line number Diff line change
    @@ -11,19 +11,19 @@ Um pouco mais de detalhes

    Usar `UUID` como tipo numa PK (Primary Key) em vez de `Int/BigInt` **em bancos de dados relacionais (RDBMS)** parece ter se tornado comum em aplicações nesse mundo de APIs REST, microsserviços e sistemas distribuídos, afinal temos algumas boas vantagens nessa abordagem:

    - segurança: IDs opacos pra expor em APIs REST;
    - geração de IDs descentralizados (browsers, clients, serviços, apps, bancos etc);
    - segurança: IDs opacos para expor em APIs REST;
    - geração de IDs descentralizados: assim browsers, clients e serviços, apps, outros bancos podem gerar IDs únicos;
    - ideal em DBs distribuídos ou com múltiplos nodes de escrita;
    - ótimos para tabelas temporárias ou merge entre bancos;
    - super útil em migração entre DBs;
    - uso em batch processing (melhor throughput);
    - são ótimos para tabelas temporárias ou ao fazer merge entre bancos;
    - super útil em migração entre DBs (evita colisão);
    - seu uso em batch processing pode melhorar substancialmente o throughput;
    - comuns em cenários de replicação de dados;

    Vantagens existem e são várias, mas há um custo: **impacto na escrita e na leitura**.
    Vantagens existem e são várias, mas há um custo: **impacto direto na escrita e na leitura**.

    Apesar desse custo depender de N fatores como banco de dados e versão utilizada, setup e tuning, workload, hardware etc, não dá para ignorar que ao usar `UUID` como PK nós estamos tentando resolver um problema de 4 bytes (32 bits) com 16 bytes (128 bits)! É 4x mais problema para inserir, ler e armazenar!

    Conhecer e entender as principais devantagens (trade-offs) é importantes antes de uma tomada de decisão. Praticamente todos os RDBMS modernos apresentam algum tipo de problema ou limitação no uso de `UUID` como PK, apesar da maioria destes problemas poderem ser contornados ou minimizados através de setup ou tuning apropriado (papel de um DBA aqui é importante).
    Conhecer e entender as principais devantagens (trade-offs) é importante antes de bater o martelo. A verdade, é que praticamente todos os RDBMS modernos apresentam algum tipo de problema ou limitação no uso de `UUID` como PK, apesar da maioria destes problemas poderem ser contornados ou minimizados através de setup ou tuning apropriado, e é justamente nesse momento que o papel de um DBA no time brilha.

    Para não me alongar mais, segue alguns desses trade-offs:

    @@ -37,14 +37,14 @@ Para não me alongar mais, segue alguns desses trade-offs:
    - [MySQL e clustered indexes (MSSQL Server também sofre desse mal)](https://www.percona.com/blog/2019/11/22/uuids-are-popular-but-bad-for-performance-lets-discuss/);
    - [Oracle e impacto de performance](https://franckpachot.medium.com/uuid-aka-guid-vs-oracle-sequence-number-ab11aa7dbfe7);

    O problema não é o uso do tipo `UUID` em si, mas sim utilizá-lo como chave primária (PK) em tabelas do banco de dados. O que estou querendo dizer, é que, desenhar uma feature seguindo deliberadamente essa abordagem costuma ser responsável e fazer sentido, mas adotá-la cegamente para [**TODAS** as tabelas do seu schema é muito perigoso](https://tomharrisonjr.com/uuid-or-guid-as-primary-keys-be-careful-7b2aa3dcb439)!
    O problema não é o uso do tipo `UUID` em si, mas sim utilizá-lo como chave primária em tabelas do banco de dados. O que estou querendo dizer, é que, desenhar uma feature seguindo deliberadamente essa abordagem costuma ser responsável e fazer muito sentido, mas adotá-la cegamente para [**TODAS** as tabelas do seu schema é muito perigoso](https://tomharrisonjr.com/uuid-or-guid-as-primary-keys-be-careful-7b2aa3dcb439)!

    Muitas vezes, esse tipo de design é utilizado como um "shortcut" (atalho) para facilitar a vida dos devs na hora de expor suas entidades em APIs REST, mas que joga todo o onus da manutenção para o time de infra, DBAs e muitas vezes para própria empresa, como comprar mais disco ou substituir hardware. Além disso, um ID opaco só resolve [parte do problema de segurança](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/05-Authorization_Testing/04-Testing_for_Insecure_Direct_Object_References), pois ainda se faz necessário [validações de acesso e propriedade dos dados](https://cheatsheetseries.owasp.org/cheatsheets/Insecure_Direct_Object_Reference_Prevention_Cheat_Sheet.html#additional-remarks), que geralmente é a parte mais chata de se implementar.

    Não me entenda errado, não é que esse tipo de solução não funcione, ela vai funcionar, mas como meu amigo [Raul Oliveira](https://twitter.com/rauldoliveira) me disse uma vez:
    > Eh como fazer caminhada plantando bananeira. Da pra fazer, vai concluir, gastar mais energia. Mas eh uma boa ideia?
    Perceba que é muito fácil enumerar as vantagens das tecnologias (e técnicas), pois elas estão escancaradas em todos os lugares. Mas na minha opinião, um bom arquiteto(a) ou dev(a) senior não escolhe tecnologias por suas vantagens, mas sim por suas desvantagens. Ele precisa saber o que está perdendo ao tomar uma decisão!
    Perceba que é muito fácil enumerar as vantagens das tecnologias e no uso de técnicas, pois elas estão escancaradas em todos os lugares. Mas na minha opinião, um bom arquiteto(a) ou dev(a) senior não escolhe tecnologias apenas por suas vantagens, mas principalmente por suas desvantagens. Ele(a) precisa saber o que está perdendo ao tomar uma decisão!

    Contudo, é dificil entender e pesar o custo e impacto das desvantagens sem um contexto, por isso...

    @@ -64,10 +64,11 @@ Favoreça um modelo hibrido

    Nem oito nem oitenta, já dizia minha mãe.

    Na minha opinião, se possível, **favoreça o uso de `Int/BigInt` para IDs internos do banco de dados (PKs e FKs), e use uma coluna do tipo `UUID` como ID externo (por exemplo `external_id`)**. Essa forma hibrida possibilita seu sistema continue tirando o melhor proveito do seu RDBMS ao mesmo tempo que possibilita ter um ID opaco (segurança).
    Na minha opinião, se possível, **favoreça o uso de `Int/BigInt` para IDs internos do banco de dados (PKs e FKs), e use uma coluna do tipo `UUID` como ID externo (por exemplo `external_id`)**. Essa forma hibrida possibilita seu que sistema continue tirando o melhor proveito do seu RDBMS ao mesmo tempo que possibilita ter um ID opaco (segurança).

    No caso de deixar o banco de dados trabalhar, essa abordagem abre espaço para:
    Essa abordagem não só minimiza o impacto no uso de `UUID` como também oferece vantagens interessantes:

    - permite ter um ID opaco para expor em APIs REST;
    - não precisamos necessariamente de um index na coluna;
    - podemos usar um index do tipo [HASH em vez de BTREE (funciona melhor para queries de comparação por igualdade)](http://www.savepoint.blog.br/2018/02/17/chaves-artificiais-no-postgresql-desempenho/);
    - não “espalhamos” o `UUID` pelas FKs de outras tabelas;
    @@ -80,6 +81,8 @@ Provavelmente existem outras vantagens nessa abordagem, mas meu pouco conhecimen
    Concluindo
    ----------

    Provavelmente eu falei alguma groselha, então não se acanhe em me corrigir ou dar um toque!

    Certamente existem outras vantagens e desvantagens na adoção de `UUID` como chave primária, afinal [esse tipo de problema não é de hoje](https://blog.codinghorror.com/primary-keys-ids-versus-guids/), então, caso lembre de mais algum pró ou mesmo contra, ou um contexto interessante não deixe de comentar. Com certeza posso aprender muito mais e melhor com a sua experiência e de outros.

    Enfim, resolvi escrever esse gist por causa dessa [thread no twitter](https://twitter.com/edgarberlinck/status/1342831389255868416?s=20) e para não esquecer detalhes desse tópico!
  15. @rponte rponte revised this gist Dec 29, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion using-uuid-as-pk.md
    Original file line number Diff line number Diff line change
    @@ -4,7 +4,7 @@ Pretende usar `UUID` como PK em vez de `Int/BigInt` no seu banco de dados? Pense
    TL;TD
    -----

    **Não use `UUID` como PK** nas suas tabelas do banco de dados.
    **Não use `UUID` como PK** nas tabelas do seu banco de dados.

    Um pouco mais de detalhes
    -------------------------
  16. @rponte rponte revised this gist Dec 29, 2020. No changes.
  17. @rponte rponte revised this gist Dec 29, 2020. No changes.
  18. @rponte rponte revised this gist Dec 29, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion using-uuid-as-pk.md
    Original file line number Diff line number Diff line change
    @@ -69,7 +69,7 @@ Na minha opinião, se possível, **favoreça o uso de `Int/BigInt` para IDs inte
    No caso de deixar o banco de dados trabalhar, essa abordagem abre espaço para:

    - não precisamos necessariamente de um index na coluna;
    - podemos usar um index do tipo [HASH em vez de BTREE (funciona melhor para queries de comparação de igualdade](http://www.savepoint.blog.br/2018/02/17/chaves-artificiais-no-postgresql-desempenho/);
    - podemos usar um index do tipo [HASH em vez de BTREE (funciona melhor para queries de comparação por igualdade)](http://www.savepoint.blog.br/2018/02/17/chaves-artificiais-no-postgresql-desempenho/);
    - não “espalhamos” o `UUID` pelas FKs de outras tabelas;
    - ocupamos menos espaço em disco, afinal temos menos FKs com `UUID`s;
    - podemos fazer tuning apropriado na coluna de acordo com nosso workload;
  19. @rponte rponte revised this gist Dec 29, 2020. 1 changed file with 16 additions and 4 deletions.
    20 changes: 16 additions & 4 deletions using-uuid-as-pk.md
    Original file line number Diff line number Diff line change
    @@ -32,9 +32,10 @@ Para não me alongar mais, segue alguns desses trade-offs:
    - `UUID` não são ordenáveis (embora existam specs e implementações para tal, como a [ULID](https://medium.com/@victoryosayi/ulid-universally-unique-lexicographically-sortable-identifier-d75c253bc6a8));
    - maioria dos servidores são 64 bits: `UUID` são chaves de 128 bits, logo precisam de no minimo 2 ciclos de CPU para serem processadas;
    - pode piorar? claro, basta armazenar seu o `UUID` como texto no banco;
    - [PostgreSQL e impacto na escrita e leitura](http://www.savepoint.blog.br/2018/02/17/chaves-artificiais-no-postgresql-desempenho/);
    - [PostgreSQL e Write Amplification](https://github.com/uuidjs/uuid/issues/303#issuecomment-575992079);
    - [MySQL e clustered indexes (MSSQL Server também sofre desse mal)](https://www.percona.com/blog/2019/11/22/uuids-are-popular-but-bad-for-performance-lets-discuss/);
    - [Oracle e performance](https://franckpachot.medium.com/uuid-aka-guid-vs-oracle-sequence-number-ab11aa7dbfe7);
    - [Oracle e impacto de performance](https://franckpachot.medium.com/uuid-aka-guid-vs-oracle-sequence-number-ab11aa7dbfe7);

    O problema não é o uso do tipo `UUID` em si, mas sim utilizá-lo como chave primária (PK) em tabelas do banco de dados. O que estou querendo dizer, é que, desenhar uma feature seguindo deliberadamente essa abordagem costuma ser responsável e fazer sentido, mas adotá-la cegamente para [**TODAS** as tabelas do seu schema é muito perigoso](https://tomharrisonjr.com/uuid-or-guid-as-primary-keys-be-careful-7b2aa3dcb439)!

    @@ -43,7 +44,7 @@ Muitas vezes, esse tipo de design é utilizado como um "shortcut" (atalho) para
    Não me entenda errado, não é que esse tipo de solução não funcione, ela vai funcionar, mas como meu amigo [Raul Oliveira](https://twitter.com/rauldoliveira) me disse uma vez:
    > Eh como fazer caminhada plantando bananeira. Da pra fazer, vai concluir, gastar mais energia. Mas eh uma boa ideia?
    Perceba que é muito fácil enumerar as vantagens das tecnologias (e técnicas), pois elas estão escancaradas em todos os lugares. Mas na minha opinião, um bom arquiteto(a) ou dev(a) senior não escolhe tecnologias por suas vantagens, mas sim por suas desvantagens.
    Perceba que é muito fácil enumerar as vantagens das tecnologias (e técnicas), pois elas estão escancaradas em todos os lugares. Mas na minha opinião, um bom arquiteto(a) ou dev(a) senior não escolhe tecnologias por suas vantagens, mas sim por suas desvantagens. Ele precisa saber o que está perdendo ao tomar uma decisão!

    Contudo, é dificil entender e pesar o custo e impacto das desvantagens sem um contexto, por isso...

    @@ -63,11 +64,22 @@ Favoreça um modelo hibrido

    Nem oito nem oitenta, já dizia minha mãe.

    Na minha opinião, se possível, **favoreça o uso de `Int/BigInt` para IDs internos do banco de dados (PKs e FKs), e use uma coluna do tipo `UUID` como ID externo (por exemplo `external_id`)**. Essa forma hibrida possibilita seu sistema continue tirando o melhor proveito do seu RDBMS ao mesmo tempo que possibilita ter um ID opaco (segurança). Mas não esqueça de conversar com seu DBA, fazer alguns testes de carga e entender os limites da sua aplicação!
    Na minha opinião, se possível, **favoreça o uso de `Int/BigInt` para IDs internos do banco de dados (PKs e FKs), e use uma coluna do tipo `UUID` como ID externo (por exemplo `external_id`)**. Essa forma hibrida possibilita seu sistema continue tirando o melhor proveito do seu RDBMS ao mesmo tempo que possibilita ter um ID opaco (segurança).

    No caso de deixar o banco de dados trabalhar, essa abordagem abre espaço para:

    - não precisamos necessariamente de um index na coluna;
    - podemos usar um index do tipo [HASH em vez de BTREE (funciona melhor para queries de comparação de igualdade](http://www.savepoint.blog.br/2018/02/17/chaves-artificiais-no-postgresql-desempenho/);
    - não “espalhamos” o `UUID` pelas FKs de outras tabelas;
    - ocupamos menos espaço em disco, afinal temos menos FKs com `UUID`s;
    - podemos fazer tuning apropriado na coluna de acordo com nosso workload;
    - permitimos que o banco trabalhe melhor via PK/FK sequencial em JOINs, agregações e ordenações;

    Provavelmente existem outras vantagens nessa abordagem, mas meu pouco conhecimento sobre RDBMS não me permite pensar mais longe nesse momento. De qualquer forma, não esqueça de consultar seu DBA, fazer alguns testes de carga e entender os limites da sua aplicação!

    Concluindo
    ----------

    Certamente existem outras vantagens e desvantagens na adoção de `UUID` como chave primária, afinal [esse tipo de problema não é de hoje](https://blog.codinghorror.com/primary-keys-ids-versus-guids/), então, caso conheça mais algum pró e contra, ou um contexto interessante não deixe de comentar. Com certeza posso aprender muito mais e melhor com a sua experiência e de outros.
    Certamente existem outras vantagens e desvantagens na adoção de `UUID` como chave primária, afinal [esse tipo de problema não é de hoje](https://blog.codinghorror.com/primary-keys-ids-versus-guids/), então, caso lembre de mais algum pró ou mesmo contra, ou um contexto interessante não deixe de comentar. Com certeza posso aprender muito mais e melhor com a sua experiência e de outros.

    Enfim, resolvi escrever esse gist por causa dessa [thread no twitter](https://twitter.com/edgarberlinck/status/1342831389255868416?s=20) e para não esquecer detalhes desse tópico!
  20. @rponte rponte revised this gist Dec 29, 2020. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions using-uuid-as-pk.md
    Original file line number Diff line number Diff line change
    @@ -52,6 +52,8 @@ Contextos importam

    Em 2012 o Instagram precisou distriuir seu banco de dados (fazer sharding) para melhorar performance e throughput do site, e, em vez de adotar `UUID` eles resolveram [criar um próprio ID de 64bits](https://instagram-engineering.com/sharding-ids-at-instagram-1cf5a71e5a5c). Eles não fizeram isso à toa, eles estavam cientes do custo imposto pelo uso de `UUID` na epoca e dentro do contexto deles.

    Um pouco antes, em 2010, o Twitter também precisou gerar IDs únicos entre suas instâncias de MySQL e o banco de dados Cassandra, e para isso optou por um [serviço distribuído de geração de IDs](https://blog.twitter.com/engineering/en_us/a/2010/announcing-snowflake.html), que por sinal foi criado por eles e recebeu o nome de **Snowflake**. Assim como o Instagram, a equipe do Twitter seguiu por esse caminho pois era importante que os IDs gerados fossem ordenáveis e tivessem o tamanho de 64 bits.

    Nesse mundo de microsserviços, geralmente cada serviço possui um banco isolado e independente que possui um schema pequeno, enxuto e com baixa volumetria de dados, então, na minha percepção, as chances de problemas são bem menores no uso de `UUID` como PK! Mas não se engane, se há chances do volume de dados crescer em um intervalo curto de tempo então talvez seja melhor refletir e discutir com seu DBA sobre sua adoção.

    Outro detalhe importante, nem todas as tabelas precisam ser expostas para sistemas externos, portanto ao adotar `UUID` como PK atente-se a dar preferência somente para tabelas que precisam ser vistas por sistemas terceiros, dessa forma minimiza-se o impacto no restante do sistema.
  21. @rponte rponte revised this gist Dec 28, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion using-uuid-as-pk.md
    Original file line number Diff line number Diff line change
    @@ -36,7 +36,7 @@ Para não me alongar mais, segue alguns desses trade-offs:
    - [MySQL e clustered indexes (MSSQL Server também sofre desse mal)](https://www.percona.com/blog/2019/11/22/uuids-are-popular-but-bad-for-performance-lets-discuss/);
    - [Oracle e performance](https://franckpachot.medium.com/uuid-aka-guid-vs-oracle-sequence-number-ab11aa7dbfe7);

    O problema não é o uso do tipo `UUID` em si, mas sim utilizá-lo como chave primária (PK) em tabelas do banco de dados. O que estou querendo dizer, é que, desenhar uma feature com essa abordagem deliberadamente costuma ser responsável e fazer sentido, mas adotar cegamente para [**TODAS** as tabelas do seu schema é muito perigoso](https://tomharrisonjr.com/uuid-or-guid-as-primary-keys-be-careful-7b2aa3dcb439)!
    O problema não é o uso do tipo `UUID` em si, mas sim utilizá-lo como chave primária (PK) em tabelas do banco de dados. O que estou querendo dizer, é que, desenhar uma feature seguindo deliberadamente essa abordagem costuma ser responsável e fazer sentido, mas adotá-la cegamente para [**TODAS** as tabelas do seu schema é muito perigoso](https://tomharrisonjr.com/uuid-or-guid-as-primary-keys-be-careful-7b2aa3dcb439)!

    Muitas vezes, esse tipo de design é utilizado como um "shortcut" (atalho) para facilitar a vida dos devs na hora de expor suas entidades em APIs REST, mas que joga todo o onus da manutenção para o time de infra, DBAs e muitas vezes para própria empresa, como comprar mais disco ou substituir hardware. Além disso, um ID opaco só resolve [parte do problema de segurança](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/05-Authorization_Testing/04-Testing_for_Insecure_Direct_Object_References), pois ainda se faz necessário [validações de acesso e propriedade dos dados](https://cheatsheetseries.owasp.org/cheatsheets/Insecure_Direct_Object_Reference_Prevention_Cheat_Sheet.html#additional-remarks), que geralmente é a parte mais chata de se implementar.

  22. @rponte rponte revised this gist Dec 28, 2020. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions using-uuid-as-pk.md
    Original file line number Diff line number Diff line change
    @@ -54,14 +54,14 @@ Em 2012 o Instagram precisou distriuir seu banco de dados (fazer sharding) para

    Nesse mundo de microsserviços, geralmente cada serviço possui um banco isolado e independente que possui um schema pequeno, enxuto e com baixa volumetria de dados, então, na minha percepção, as chances de problemas são bem menores no uso de `UUID` como PK! Mas não se engane, se há chances do volume de dados crescer em um intervalo curto de tempo então talvez seja melhor refletir e discutir com seu DBA sobre sua adoção.

    Outro detalhe importante, nem todas as tabelas precisam ser expostas para sistemas externos, portanto ao adotar `UUID` como PK atente-se a dar preferência somente para tabelas que precisam ser expostas, dessa forma minimiza-se o impacto no restante do sistema.
    Outro detalhe importante, nem todas as tabelas precisam ser expostas para sistemas externos, portanto ao adotar `UUID` como PK atente-se a dar preferência somente para tabelas que precisam ser vistas por sistemas terceiros, dessa forma minimiza-se o impacto no restante do sistema.

    Favoreça um modelo hibrido
    -------------------------

    Nem oito nem oitenta, já dizia minha mãe.

    No fim, se possível, **favoreça o uso de `Int/BigInt` para IDs internos do banco de dados (PKs e FKs), e use uma coluna do tipo `UUID` como ID externo (por exemplo `external_id`)**. Essa forma hibrida possibilita seu sistema tirar o melhor proveito do seu RDBMS ao mesmo tempo que possibilita ter um ID opaco (segurança). Mas não esqueça de conversar com seu DBA, fazer alguns testes de carga e entender os limites da sua aplicação!
    Na minha opinião, se possível, **favoreça o uso de `Int/BigInt` para IDs internos do banco de dados (PKs e FKs), e use uma coluna do tipo `UUID` como ID externo (por exemplo `external_id`)**. Essa forma hibrida possibilita seu sistema continue tirando o melhor proveito do seu RDBMS ao mesmo tempo que possibilita ter um ID opaco (segurança). Mas não esqueça de conversar com seu DBA, fazer alguns testes de carga e entender os limites da sua aplicação!

    Concluindo
    ----------
  23. @rponte rponte revised this gist Dec 28, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion using-uuid-as-pk.md
    Original file line number Diff line number Diff line change
    @@ -38,7 +38,7 @@ Para não me alongar mais, segue alguns desses trade-offs:

    O problema não é o uso do tipo `UUID` em si, mas sim utilizá-lo como chave primária (PK) em tabelas do banco de dados. O que estou querendo dizer, é que, desenhar uma feature com essa abordagem deliberadamente costuma ser responsável e fazer sentido, mas adotar cegamente para [**TODAS** as tabelas do seu schema é muito perigoso](https://tomharrisonjr.com/uuid-or-guid-as-primary-keys-be-careful-7b2aa3dcb439)!

    Muitas vezes, esse tipo de design é utilizado como um "shortcut" (atalho) para facilitar a vida dos devs na hora de expor suas entidades em APIs REST, mas que joga todo o onus da manutenção para o time de infra, DBAs e muitas vezes para própria empresa, como comprar mais disco ou substituir hardware. Além disso, um ID opaco só resolve [parte do problema de segurança](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/05-Authorization_Testing/04-Testing_for_Insecure_Direct_Object_References#:~:text=Insecure%20Direct%20Object%20References%20(IDOR,example%20database%20records%20or%20files.), pois ainda se faz necessário [validações de acesso e propriedade dos dados](https://cheatsheetseries.owasp.org/cheatsheets/Insecure_Direct_Object_Reference_Prevention_Cheat_Sheet.html#additional-remarks), que geralmente é a parte mais chata de se implementar.
    Muitas vezes, esse tipo de design é utilizado como um "shortcut" (atalho) para facilitar a vida dos devs na hora de expor suas entidades em APIs REST, mas que joga todo o onus da manutenção para o time de infra, DBAs e muitas vezes para própria empresa, como comprar mais disco ou substituir hardware. Além disso, um ID opaco só resolve [parte do problema de segurança](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/05-Authorization_Testing/04-Testing_for_Insecure_Direct_Object_References), pois ainda se faz necessário [validações de acesso e propriedade dos dados](https://cheatsheetseries.owasp.org/cheatsheets/Insecure_Direct_Object_Reference_Prevention_Cheat_Sheet.html#additional-remarks), que geralmente é a parte mais chata de se implementar.

    Não me entenda errado, não é que esse tipo de solução não funcione, ela vai funcionar, mas como meu amigo [Raul Oliveira](https://twitter.com/rauldoliveira) me disse uma vez:
    > Eh como fazer caminhada plantando bananeira. Da pra fazer, vai concluir, gastar mais energia. Mas eh uma boa ideia?
  24. @rponte rponte revised this gist Dec 28, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion using-uuid-as-pk.md
    Original file line number Diff line number Diff line change
    @@ -38,7 +38,7 @@ Para não me alongar mais, segue alguns desses trade-offs:

    O problema não é o uso do tipo `UUID` em si, mas sim utilizá-lo como chave primária (PK) em tabelas do banco de dados. O que estou querendo dizer, é que, desenhar uma feature com essa abordagem deliberadamente costuma ser responsável e fazer sentido, mas adotar cegamente para [**TODAS** as tabelas do seu schema é muito perigoso](https://tomharrisonjr.com/uuid-or-guid-as-primary-keys-be-careful-7b2aa3dcb439)!

    Muitas vezes, esse tipo de design é utilizado como um "shortcut" (atalho) para facilitar a vida dos devs na hora de expor suas entidades em APIs REST, mas que joga todo o onus da manutenção para o time de infra, DBAs e muitas vezes para própria empresa, como comprar mais disco ou substituir hardware. Além disso, um ID opaco só resolve parte do problema de segurança, pois ainda se faz necessário validações de acesso e propriedade dos dados, que geralmente é a parte mais chata de se implementar.
    Muitas vezes, esse tipo de design é utilizado como um "shortcut" (atalho) para facilitar a vida dos devs na hora de expor suas entidades em APIs REST, mas que joga todo o onus da manutenção para o time de infra, DBAs e muitas vezes para própria empresa, como comprar mais disco ou substituir hardware. Além disso, um ID opaco só resolve [parte do problema de segurança](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/05-Authorization_Testing/04-Testing_for_Insecure_Direct_Object_References#:~:text=Insecure%20Direct%20Object%20References%20(IDOR,example%20database%20records%20or%20files.), pois ainda se faz necessário [validações de acesso e propriedade dos dados](https://cheatsheetseries.owasp.org/cheatsheets/Insecure_Direct_Object_Reference_Prevention_Cheat_Sheet.html#additional-remarks), que geralmente é a parte mais chata de se implementar.

    Não me entenda errado, não é que esse tipo de solução não funcione, ela vai funcionar, mas como meu amigo [Raul Oliveira](https://twitter.com/rauldoliveira) me disse uma vez:
    > Eh como fazer caminhada plantando bananeira. Da pra fazer, vai concluir, gastar mais energia. Mas eh uma boa ideia?
  25. @rponte rponte revised this gist Dec 28, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion using-uuid-as-pk.md
    Original file line number Diff line number Diff line change
    @@ -38,7 +38,7 @@ Para não me alongar mais, segue alguns desses trade-offs:

    O problema não é o uso do tipo `UUID` em si, mas sim utilizá-lo como chave primária (PK) em tabelas do banco de dados. O que estou querendo dizer, é que, desenhar uma feature com essa abordagem deliberadamente costuma ser responsável e fazer sentido, mas adotar cegamente para [**TODAS** as tabelas do seu schema é muito perigoso](https://tomharrisonjr.com/uuid-or-guid-as-primary-keys-be-careful-7b2aa3dcb439)!

    Muitas vezes, esse tipo de design é utilizado como um "shortcut" (atalho) para facilitar a vida dos devs na hora de expor suas entidades em APIs REST, mas que joga todo o onus da manutenção para o time de infra, DBAs e muitas vezes para própria empresa, como comprar mais disco ou substituir hardware.
    Muitas vezes, esse tipo de design é utilizado como um "shortcut" (atalho) para facilitar a vida dos devs na hora de expor suas entidades em APIs REST, mas que joga todo o onus da manutenção para o time de infra, DBAs e muitas vezes para própria empresa, como comprar mais disco ou substituir hardware. Além disso, um ID opaco só resolve parte do problema de segurança, pois ainda se faz necessário validações de acesso e propriedade dos dados, que geralmente é a parte mais chata de se implementar.

    Não me entenda errado, não é que esse tipo de solução não funcione, ela vai funcionar, mas como meu amigo [Raul Oliveira](https://twitter.com/rauldoliveira) me disse uma vez:
    > Eh como fazer caminhada plantando bananeira. Da pra fazer, vai concluir, gastar mais energia. Mas eh uma boa ideia?
  26. @rponte rponte revised this gist Dec 28, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion using-uuid-as-pk.md
    Original file line number Diff line number Diff line change
    @@ -9,7 +9,7 @@ TL;TD
    Um pouco mais de detalhes
    -------------------------

    Usar `UUID` como tipo numa PK (Primary Key) em vez de `Int/BigInt` **em banco de dados relacionais (RDBMS)** parece ter se tornado comum em aplicações nesse mundo de APIs REST, microsserviços e sistemas distribuídos, afinal temos algumas boas vantagens:
    Usar `UUID` como tipo numa PK (Primary Key) em vez de `Int/BigInt` **em bancos de dados relacionais (RDBMS)** parece ter se tornado comum em aplicações nesse mundo de APIs REST, microsserviços e sistemas distribuídos, afinal temos algumas boas vantagens nessa abordagem:

    - segurança: IDs opacos pra expor em APIs REST;
    - geração de IDs descentralizados (browsers, clients, serviços, apps, bancos etc);
  27. @rponte rponte revised this gist Dec 28, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion using-uuid-as-pk.md
    Original file line number Diff line number Diff line change
    @@ -61,7 +61,7 @@ Favoreça um modelo hibrido

    Nem oito nem oitenta, já dizia minha mãe.

    No fim, se possível, **favoreça o uso de `Int/BigInt` para IDs internos do banco de dados (PKs e FKs), e use uma coluna do tipo `UUID` (por exemplo `external_id`) como ID externo**. Essa forma hibrida possibilita seu sistema tirar o melhor proveito do seu RDBMS ao mesmo tempo que possibilita ter um ID opaco (segurança). Mas não esqueça de conversar com seu DBA, fazer alguns testes de carga e entender os limites da sua aplicação!
    No fim, se possível, **favoreça o uso de `Int/BigInt` para IDs internos do banco de dados (PKs e FKs), e use uma coluna do tipo `UUID` como ID externo (por exemplo `external_id`)**. Essa forma hibrida possibilita seu sistema tirar o melhor proveito do seu RDBMS ao mesmo tempo que possibilita ter um ID opaco (segurança). Mas não esqueça de conversar com seu DBA, fazer alguns testes de carga e entender os limites da sua aplicação!

    Concluindo
    ----------
  28. @rponte rponte revised this gist Dec 28, 2020. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions using-uuid-as-pk.md
    Original file line number Diff line number Diff line change
    @@ -45,11 +45,11 @@ Não me entenda errado, não é que esse tipo de solução não funcione, ela va
    Perceba que é muito fácil enumerar as vantagens das tecnologias (e técnicas), pois elas estão escancaradas em todos os lugares. Mas na minha opinião, um bom arquiteto(a) ou dev(a) senior não escolhe tecnologias por suas vantagens, mas sim por suas desvantagens.

    Contudo, é dificil entender e pesar o custo e impacto das desvantagens sem um contexto, por isso...

    Contextos importam
    ------------------

    É dificil entender e pesar o custo e impacto das desvantagens sem um contexto, por isso vamos falar um pouco sobre isso...

    Em 2012 o Instagram precisou distriuir seu banco de dados (fazer sharding) para melhorar performance e throughput do site, e, em vez de adotar `UUID` eles resolveram [criar um próprio ID de 64bits](https://instagram-engineering.com/sharding-ids-at-instagram-1cf5a71e5a5c). Eles não fizeram isso à toa, eles estavam cientes do custo imposto pelo uso de `UUID` na epoca e dentro do contexto deles.

    Nesse mundo de microsserviços, geralmente cada serviço possui um banco isolado e independente que possui um schema pequeno, enxuto e com baixa volumetria de dados, então, na minha percepção, as chances de problemas são bem menores no uso de `UUID` como PK! Mas não se engane, se há chances do volume de dados crescer em um intervalo curto de tempo então talvez seja melhor refletir e discutir com seu DBA sobre sua adoção.
  29. @rponte rponte revised this gist Dec 28, 2020. 1 changed file with 4 additions and 2 deletions.
    6 changes: 4 additions & 2 deletions using-uuid-as-pk.md
    Original file line number Diff line number Diff line change
    @@ -48,6 +48,8 @@ Perceba que é muito fácil enumerar as vantagens das tecnologias (e técnicas),
    Contextos importam
    ------------------

    É dificil entender e pesar o custo e impacto das desvantagens sem um contexto, por isso vamos falar um pouco sobre isso...

    Em 2012 o Instagram precisou distriuir seu banco de dados (fazer sharding) para melhorar performance e throughput do site, e, em vez de adotar `UUID` eles resolveram [criar um próprio ID de 64bits](https://instagram-engineering.com/sharding-ids-at-instagram-1cf5a71e5a5c). Eles não fizeram isso à toa, eles estavam cientes do custo imposto pelo uso de `UUID` na epoca e dentro do contexto deles.

    Nesse mundo de microsserviços, geralmente cada serviço possui um banco isolado e independente que possui um schema pequeno, enxuto e com baixa volumetria de dados, então, na minha percepção, as chances de problemas são bem menores no uso de `UUID` como PK! Mas não se engane, se há chances do volume de dados crescer em um intervalo curto de tempo então talvez seja melhor refletir e discutir com seu DBA sobre sua adoção.
    @@ -64,6 +66,6 @@ No fim, se possível, **favoreça o uso de `Int/BigInt` para IDs internos do ban
    Concluindo
    ----------

    Certamente existem outras vantagens e desvantagens na adoção de `UUID` como chave primária, afinal [esse tipo de problema não é de hoje](https://blog.codinghorror.com/primary-keys-ids-versus-guids/), então, caso conheça mais alguma ou um contexto interessante não deixe de comentar. Com certeza posso aprender mais e melhor com a experiência de outros.
    Certamente existem outras vantagens e desvantagens na adoção de `UUID` como chave primária, afinal [esse tipo de problema não é de hoje](https://blog.codinghorror.com/primary-keys-ids-versus-guids/), então, caso conheça mais algum pró e contra, ou um contexto interessante não deixe de comentar. Com certeza posso aprender muito mais e melhor com a sua experiência e de outros.

    Enfim, resolvi escrever esse gist por causa dessa [thread no twitter](https://twitter.com/edgarberlinck/status/1342831389255868416?s=20) :-)
    Enfim, resolvi escrever esse gist por causa dessa [thread no twitter](https://twitter.com/edgarberlinck/status/1342831389255868416?s=20) e para não esquecer detalhes desse tópico!
  30. @rponte rponte revised this gist Dec 28, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion using-uuid-as-pk.md
    Original file line number Diff line number Diff line change
    @@ -27,7 +27,7 @@ Conhecer e entender as principais devantagens (trade-offs) é importantes antes

    Para não me alongar mais, segue alguns desses trade-offs:

    - espaço em disco;
    - requer maior espaço em disco;
    - compromete o buffer de memoria para tabela de indexes;
    - `UUID` não são ordenáveis (embora existam specs e implementações para tal, como a [ULID](https://medium.com/@victoryosayi/ulid-universally-unique-lexicographically-sortable-identifier-d75c253bc6a8));
    - maioria dos servidores são 64 bits: `UUID` são chaves de 128 bits, logo precisam de no minimo 2 ciclos de CPU para serem processadas;