Como engenheiros de back-end, muitas vezes temos a tarefa de construir sistemas que possam escalar e lidar com vários recursos, usuários e entidades, cada um precisando de identificação exclusiva. Em muitos casos, o uso de IDs sequenciais (por exemplo, 1, 2, 3) parece uma solução simples, mas isso pode rapidamente se tornar problemático à medida que seu aplicativo cresce e é dimensionado em sistemas distribuídos. É aqui que entram os UUIDs (Identificadores Universalmente Únicos).
Nesta postagem do blog, exploraremos:
Um UUID (Identificador Universalmente Único) é um número de 128 bits usado para identificar informações exclusivamente em sistemas de computador. Ele foi projetado para ser globalmente único, o que significa que UUIDs gerados independentemente em diferentes sistemas não entrarão em conflito.
Um UUID se parece com isto:
66e69275-c6bc-800c-90a6-2f41cb991502
É composto por 32 dígitos hexadecimais, exibidos em cinco grupos separados por hífens, no formato 8-4-4-4-12.
Chaves de banco de dados em sistemas distribuídos: Em sistemas onde diferentes bancos de dados ou microsserviços precisam gerar IDs exclusivos sem se comunicarem entre si, os UUIDs garantem exclusividade. Por exemplo, em uma plataforma de comércio eletrônico distribuída, cada serviço pode gerar independentemente IDs de pedidos ou transações, e os UUIDs evitarão qualquer colisão.
IDs de sessão: UUIDs são comumente usados para identificar sessões de usuários em aplicativos da web. Eles são particularmente úteis quando você precisa manter informações da sessão sem vazar dados confidenciais ou previsíveis.
Identificadores de arquivo ou recurso: Quando você precisa rastrear arquivos, documentos ou qualquer recurso em várias plataformas ou bancos de dados, um UUID pode ser atribuído a cada recurso para facilitar a pesquisa sem o risco de duplicatas.
APIs e referências externas: expor IDs sequenciais ou facilmente adivinháveis (por exemplo, usuário/1, usuário/2) em uma API pode levar a vulnerabilidades de privacidade. Ao usar UUIDs (por exemplo, user/66e69275-c6bc-800c-90a6-2f41cb991502), você reduz a probabilidade de os usuários adivinharem e acessarem recursos que não pertencem a eles.
A biblioteca uuid do Python simplifica a geração e o gerenciamento de UUIDs. Veja como:
import uuid # Generate a UUID generated_uuid = uuid.uuid4() print(f"Generated UUID: {generated_uuid}")
A função uuid4() gera um UUID aleatório baseado em números aleatórios ou pseudo-aleatórios, que é a variante mais comum usada no desenvolvimento web.
Ao usar bancos de dados como PostgreSQL, é comum usar UUIDs como chaves primárias. Veja como você pode configurá-lo em Python com SQLAlchemy:
from sqlalchemy import Column, String from sqlalchemy.dialects.postgresql import UUID import uuid from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class User(Base): __tablename__ = 'users' id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, unique=True, nullable=False) username = Column(String, nullable=False) # This will generate a UUID primary key for each new user.
Neste exemplo, definimos o campo id como um UUID, garantindo que cada usuário terá um identificador exclusivo que não entrará em conflito com outros registros, mesmo em bancos de dados distribuídos.
Ignorar UUIDs em favor de IDs sequenciais ou de incremento automático pode representar vários riscos:
Vulnerabilidades de segurança: IDs sequenciais são previsíveis, tornando mais fácil para os invasores enumerarem registros e descobrirem dados confidenciais. Por exemplo, se os IDs de usuário forem sequenciais, um invasor poderá tentar adivinhar outros IDs de usuário e acessar contas não autorizadas.
Colisões de dados: em um sistema distribuído, depender de números inteiros com incremento automático pode levar a colisões de ID, especialmente quando vários serviços ou bancos de dados estão gerando IDs sem coordenação central.
Problemas de migração e mesclagem de dados: ao combinar bancos de dados ou migrar dados entre sistemas, ter IDs sequenciais não exclusivos pode causar conflitos. Os UUIDs evitam esses problemas garantindo exclusividade.
Armazenando UUIDs como Strings: Um erro comum é armazenar UUIDs como strings, o que desperdiça espaço e pode tornar as consultas mais lentas, especialmente em grandes bancos de dados. A maioria dos bancos de dados modernos, como PostgreSQL, possui tipos UUID nativos que armazenam UUIDs de forma eficiente.
Errado:
CREATE TABLE users ( id VARCHAR(36) PRIMARY KEY );
Certo:
CREATE TABLE users ( id UUID PRIMARY KEY );
Não usando a versão correta do UUID: Existem várias versões de UUIDs (por exemplo, uuid1(), uuid3(), uuid4(), uuid5()), cada uma adequada para uso específico casos. uuid4(), baseado em números aleatórios, é o mais comumente usado para gerar IDs exclusivos em aplicações web. Esteja atento à versão que você está usando e se ela atende às suas necessidades.
Ignorando possibilidades de colisão: Embora os UUIDs sejam projetados para serem únicos, há uma chance muito pequena de colisão. Para a maioria das aplicações, o risco é insignificante, mas se você estiver gerando bilhões de UUIDs ou operando em ambientes altamente sensíveis, deverá implementar a detecção de colisão.
Use UUIDs para referências externas: Ao expor IDs em URLs ou APIs, prefira UUIDs a IDs sequenciais. Isso aumenta a segurança e torna mais difícil para os usuários prever IDs de recursos.
Armazenar UUIDs em formatos nativos: Use o tipo UUID nativo do banco de dados para armazenar UUIDs em vez de strings. Isso reduz o espaço de armazenamento e melhora o desempenho da consulta.
Escolha a versão correta do UUID: Na maioria dos casos, uuid4() (UUID baseado em aleatório) é a melhor escolha para gerar identificadores exclusivos em aplicativos da web. No entanto, se você precisar de UUIDs gerados deterministicamente, você pode considerar uuid3() ou uuid5() (UUIDs baseados em namespace).
Validar UUIDs: ao aceitar UUIDs da entrada do usuário, sempre valide-os para garantir que estejam formatados corretamente antes do processamento. Em Python, você pode usar objetos UUID para verificar a validade de uma string.
def is_valid_uuid(uuid_to_test, version=4): try: uuid_obj = uuid.UUID(uuid_to_test, version=version) return str(uuid_obj) == uuid_to_test except ValueError: return False # Example usage print(is_valid_uuid("66e69275-c6bc-800c-90a6-2f41cb991502")) # True print(is_valid_uuid("invalid-uuid-string")) # False
UUIDs são ferramentas poderosas para gerar identificadores exclusivos em sistemas distribuídos e garantir segurança em aplicações web. Eles ajudam a evitar problemas como colisões de dados, ataques de ID previsíveis e conflitos de ID durante migrações de banco de dados. Ao compreender e seguir as práticas recomendadas para UUIDs, você pode construir sistemas de back-end mais robustos, escaláveis e seguros.
Lembre-se de usar a versão UUID apropriada, armazená-los corretamente em seus bancos de dados e estar atento aos riscos potenciais. Com essas dicas, você estará bem equipado para lidar com UUIDs de maneira eficaz em seus projetos!
Sinta-se à vontade para comentar abaixo se tiver alguma dúvida ou dicas adicionais sobre UUIDs! Boa codificação!
Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.
Copyright© 2022 湘ICP备2022001581号-3