Por default, o Django cria chaves primarias do tipo inteiro (32 bits) quando usado com o banco PostgreSQL. Estes campos sao incrementados automaticamente e funcionam perfeitamente bem em ambiente local. Um problema que aparece quando voce cria uma API e o fato de seus ids sequenciais e numericos exporem detalhes de sua base de dados.Imagine que seu cliente tem o id 1, ele pode imaginar (e com razao) que e seu primeiro cliente. O mesmo pode ser utilizado por concorrentes para saber quantos novos clientes voce obteve em determinado periodo, bastando para isso criar uma nova conta. Isto pode gerar uma vontade incontrolavel em algumas pessoas de explorar os valores de suas chaves. Com chaves inteiras, esta tarefa e facil, basta incrementar o valor da chave de 1 e tentar novamente.Uma alternativa as chaves inteiras e a utilizacao de UUID, geradas aleatoriamente, porem maiores (128 bits). Por serem 4 vezes maiores, ja podemos imaginar que o espaco em disco ocupado pelas chaves e indices vai tambem aumentar. Mas e quanto as operacoes de insercao, busca e atualizacao de tabelas? Quanto custa substituir as chaves inteiras por UUIDs.Exemplo de UUID:cab5ade3-2dc3-4344-b5a6-80df59f91458Eu resolvi fazer um teste, comparando chaves inteiras, uuids e uma solucao mista, onde a uuid e utilizada fora da aplicacao, mas mantendo uma chave primaria inteira.Os modelos sao bem simples (chaves inteiras, modelo de referencia):class A(models.Model): bigtext = models.TextField() name = models.CharField(max_length=100) counter = models.IntegerField(default=0)class B(models.Model): parent = models.ForeignKey(A, related_name="bs") bigtext = models.TextField() counter = models.IntegerField(default=0)class C(models.Model): parent = models.ForeignKey(B, related_name="cs") grandparent = models.ForeignKey(A, related_name="cs") bigtext = models.TextField() counter = models.IntegerField(default=0)A, B, C e foram configuradas de forma a estabeler um relacionamento entre elas.Vamos modificar os modelos para utilizarmos UUIDs:class A(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) bigtext = models.TextField() name = models.CharField(max_length=100) counter = models.IntegerField(default=0)class B(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) parent = models.ForeignKey(A, related_name="bs") bigtext = models.TextField() counter = models.IntegerField(default=0)class C(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) parent = models.ForeignKey(B, related_name="cs") grandparent = models.ForeignKey(A, related_name="cs") bigtext = models.TextField() counter = models.IntegerField(default=0)E uma solucao hibrida alternativa, com duas chaves, uma uuid e outra inteira:class A(models.Model): surrogate_id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True) bigtext = models.TextField() name = models.CharField(max_length=100) counter = models.IntegerField(default=0)class B(models.Model): surrogate_id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True) parent = models.ForeignKey(A, related_name="bs") bigtext = models.TextField() counter = models.IntegerField(default=0)class C(models.Model): surrogate_id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True) parent = models.ForeignKey(B, related_name="cs") grandparent = models.ForeignKey(A, related_name="cs") bigtext = models.TextField() counter = models.IntegerField(default=0)O programa completo pode ser baixado aqui: https://github.com/lskbr/keyperftestAmbiente de testes:Processador: Intel Core i7 4790K 4 GHzDisco: Samsung SSD 850 EVOUbuntu 16.04 rodando em VM VirtualBox (4 GB, 4 CPUs)PostgreSQL 9.5.2 rodando via dockerDjango 1.9.6Python 3.5.1Testes realizados em: 28/05/2016Rodando o programa com 1000 registros, obtemos os seguintes resultados (todos os tempos em segundos):Neste primeiro resultado, percebemos o tempo de insercao com chave inteira e uuid nao e muito diferente. A solucao mista (chave inteira + uuid) leva mais tempo.Para simular o tempo de acesso aleatorio a tabelas com chave inteira ou uuid, vemos que como esperado, as chaves inteiras possuem a melhor performance. A solucao hibrida se apresenta como uma alternativa interessante, uma vez que o relacionamento entre as tabelas continua