O endereço de email é um candidato ruim para o primário quando comparado aos números com incremento automático?
Nosso aplicativo da web precisa que o endereço de email seja exclusivo no sistema. Então, pensei em usar o endereço de email como chave primária. No entanto, meu colega sugere que a comparação de strings será mais lenta que a comparação de números inteiros.
É um motivo válido para não usar o email como chave primária?
Nós estamos usando PostgreSQL
.
sql
database
database-design
postgresql
Robert
fonte
fonte
Respostas:
A comparação de strings é mais lenta que a comparação int. No entanto, isso não importa se você simplesmente recupera um usuário do banco de dados usando o endereço de email. É importante se você tiver consultas complexas com várias junções.
Se você armazenar informações sobre usuários em várias tabelas, as chaves estrangeiras da tabela de usuários serão o endereço de email. Isso significa que você armazena o endereço de email várias vezes.
fonte
Também apontarei que o e-mail é uma péssima escolha para criar um campo único, existem pessoas e até pequenas empresas que compartilham um endereço de e-mail. E, como números de telefone, os e-mails podem ser reutilizados. [email protected] pode facilmente pertencer a John Smith um ano e Julia Smith dois anos depois.
Outro problema com os e-mails é que eles mudam com frequência. Se você estiver ingressando em outras tabelas com essa chave, precisará atualizar também as outras tabelas, o que pode ser bastante prejudicial ao desempenho quando uma empresa cliente inteira altera seus e-mails (o que eu já vi acontecer).
fonte
a chave primária deve ser única e constante
os endereços de email mudam como as estações do ano. Útil como chave secundária para pesquisa, mas é uma má escolha para a chave primária.
fonte
Desvantagens de usar um endereço de email como chave primária:
Mais devagar ao fazer junções.
Qualquer outro registro com uma chave estrangeira publicada agora tem um valor maior, ocupando mais espaço em disco. (Dado o custo do espaço em disco hoje, esse provavelmente é um problema trivial, exceto na medida em que o registro agora leva mais tempo para ser lido. Consulte o item 1.)
Um endereço de email pode mudar, o que força todos os registros que usam isso como uma chave estrangeira a serem atualizados. Como o endereço de email não muda com tanta frequência, o problema de desempenho é provavelmente menor. O maior problema é que você precisa garantir isso. Se você precisar escrever o código, isso é mais trabalhoso e apresenta a possibilidade de erros. Se o seu mecanismo de banco de dados suportar "em cascata de atualização", é um problema menor.
Vantagens de usar o endereço de email como chave primária:
Você pode eliminar completamente algumas junções. Se tudo o que você precisa no "registro mestre" for o endereço de email, com uma chave inteira abstrata, será necessário fazer uma junção para recuperá-lo. Se a chave é o endereço de email, você já o possui e a associação é desnecessária. Se isso ajuda você depende de quantas vezes essa situação surge.
Quando você está fazendo consultas ad hoc, é fácil para um ser humano ver qual registro mestre está sendo referenciado. Isso pode ser uma grande ajuda ao tentar rastrear problemas de dados.
Você quase certamente precisará de um índice no endereço de e-mail, tornando-a a chave primária para eliminar um índice, melhorando assim o desempenho das inserções, pois agora elas têm apenas um índice para atualizar em vez de dois.
Na minha humilde opinião, não é um slam-dunk de qualquer maneira. Costumo preferir usar chaves naturais quando uma prática está disponível, porque elas são mais fáceis de trabalhar, e as desvantagens tendem a não ser muito importantes na maioria dos casos.
fonte
Isso é muito ruim. Suponha que algum provedor de e-mail saia do negócio. Os usuários desejarão alterar seus emails. Se você usou o email como chave primária, todas as chaves estrangeiras dos usuários duplicarão esse email, dificultando a alteração ...
... e nem comecei a falar sobre considerações de desempenho.
fonte
Não sei se isso pode ser um problema na sua configuração, mas, dependendo do seu RDBMS, os valores de uma coluna podem fazer distinção entre maiúsculas e minúsculas . Os documentos do PostgreSQL dizem: "Se você declarar uma coluna como UNIQUE ou PRIMARY KEY, o índice gerado implicitamente faz distinção entre maiúsculas e minúsculas". Em outras palavras, se você aceitar a entrada do usuário para uma pesquisa em uma tabela com email como chave primária e o usuário fornecer "[email protected]", você não encontrará "[email protected]".
fonte
Parece que ninguém mencionou um possível problema: os endereços de email podem ser considerados privados. Se o endereço de e-mail for a chave principal, o URL de uma página de perfil provavelmente será semelhante a
..../Users/[email protected]
. E se você não quiser expor o endereço de email do usuário? Você precisaria encontrar outra maneira de identificar o usuário, possivelmente por um valor inteiro único para criar URLs..../Users/1
. Você acabaria com um valor inteiro único, afinal.fonte
No nível lógico , o email é a chave natural. No nível físico , desde que você esteja usando um banco de dados relacional, a chave natural não se encaixa bem na chave primária. O motivo é principalmente os problemas de desempenho mencionados por outros.
Por esse motivo, o design pode ser adaptado. A chave natural se torna a chave alternativa (UNIQUE, NOT NULL) e você usa uma chave substituta / artificial / técnica como chave primária, o que pode ser um incremento automático no seu caso.
systempuntoout perguntou,
É para isso que serve a cascata .
Outro motivo para usar uma chave substituta numérica como chave primária está relacionado a como a indexação funciona em sua plataforma. No InnoDB do MySQL, por exemplo, todos os índices em uma tabela têm a chave primária pendente, então você deseja que o PK seja o menor possível (por questões de velocidade e tamanho). Também relacionado a isso, o InnoDB é mais rápido quando a chave primária é armazenada em sequência, e uma string não ajudaria lá.
Outra coisa a ser levada em consideração ao usar uma string como chave alternativa é que o uso de um hash da string que você deseja pode ser mais rápido, ignorando coisas como letras maiúsculas e minúsculas. (Na verdade, cheguei aqui enquanto procurava uma referência para confirmar o que acabei de dizer; ainda estou procurando ...)
fonte
Sim, é uma chave primária ruim porque seus usuários desejam atualizar seus endereços de email.
fonte
Sim, é melhor se você usar um número inteiro. você também pode definir sua coluna de email como restrição exclusiva.
como isso:
fonte
Outro motivo pelo qual a chave primária inteira é melhor é quando você se refere ao endereço de email na tabela diferente. Se o endereço em si for uma chave primária, em outra tabela você deverá usá-lo como chave. Então você armazena endereços de e-mail várias vezes.
fonte
Eu não estou muito familiarizado com o postgres. Chaves primárias é um grande tópico. Eu já vi algumas excelentes perguntas e respostas neste site (stackoverflow.com).
Eu acho que você pode ter um melhor desempenho por ter uma chave primária numérica e usar um ÍNDICE UNIQUE na coluna de email. Os emails tendem a variar em tamanho e podem não ser adequados para o índice de chave primária.
algumas leituras aqui e aqui.
fonte
Pessoalmente, não uso nenhuma informação para chave primária ao projetar o banco de dados, porque é muito provável que eu precise alterar essas informações posteriormente. A única razão pela qual eu forneço a chave primária é que é conveniente fazer a maioria das operações SQL do lado do cliente, e minha opção por isso sempre foi o tipo inteiro de incremento automático.
fonte
Seu colega está certo: use um número inteiro com aumento automático para sua chave primária.
Você pode implementar a exclusividade de email no nível do aplicativo ou marcar sua coluna de endereço de email como exclusiva e adicionar um índice nessa coluna.
Adicionar o campo como exclusivo custará uma comparação de cadeias apenas ao inserir nessa tabela, e não ao executar junções e verificações de restrição de chave estrangeira.
Obviamente, você deve observar que adicionar restrições ao seu aplicativo no nível do banco de dados pode tornar seu aplicativo inflexível. Sempre dê a devida consideração antes de tornar qualquer campo "exclusivo" ou "não nulo" apenas porque seu aplicativo precisa que ele seja exclusivo ou não esteja vazio.
fonte
Use um GUID como chave primária ... para que você possa gerá-lo a partir do seu programa quando fizer um INSERT e não precisará obter uma resposta do servidor para descobrir qual é a chave primária. Também será exclusivo entre tabelas e bancos de dados e você não precisa se preocupar com o que acontece se você truncar a tabela algum dia e o incremento automático for redefinido para 1.
fonte
Sei que é um pouco tardio, mas gostaria de acrescentar que as pessoas abandonam as contas de email e os provedores de serviços recuperam o endereço, permitindo que outra pessoa o utilize.
Como o @HLGEM apontou, "[email protected] pode facilmente pertencer a John Smith um ano e Julia Smith dois anos depois". nesse caso, caso John Smith deseje seu serviço, você deve recusar-se a usar o endereço de e-mail dele ou excluir todos os seus registros pertencentes a Julia Smith.
Se você precisar excluir registros e eles estiverem relacionados ao histórico financeiro da empresa, dependendo da legislação local, você poderá se encontrar em água quente.
Portanto, eu nunca usaria dados como endereços de e-mail, chapas de matrícula etc. como chaves primárias, porque não importa o quão exclusivos eles pareçam estar fora de seu controle e pode oferecer alguns desafios interessantes com os quais você pode não ter tempo para lidar.
fonte
Pode ser necessário considerar qualquer legislação de regulamentação de dados aplicável. O email é uma informação pessoal e, se seus usuários são cidadãos da UE, por exemplo, no GDPR, eles podem instruí-lo a excluir suas informações dos seus registros (lembre-se de que isso se aplica independentemente do país em que você se baseia).
Se você precisar manter o próprio registro no banco de dados por integridade referencial ou por razões históricas, como auditoria, o uso de uma chave substituta permitiria anular apenas todos os campos de dados pessoais. Obviamente, isso não é tão fácil se seus dados pessoais forem a chave primária
fonte
você pode melhorar o desempenho usando a chave primária inteira.
fonte
você deve usar uma chave primária inteira. se você precisa que a coluna de email seja exclusiva, por que simplesmente não define um índice exclusivo nessa coluna?
fonte
Se você tiver um valor não int como chave primária, as inserções e recuperações serão muito lentas em dados grandes.
fonte
chave primária deve ser escolhido um atributo estático. Como os endereços de email não são estáticos e podem ser compartilhados por vários candidatos, não é uma boa ideia usá-los como chave primária. Além disso, os endereços de e-mail são cadeias geralmente com um determinado comprimento que pode ser maior que o ID único que gostaríamos de usar [len (endereço_de_ email)> len (nome_id)], por isso exigiria mais espaço e, pior ainda, eles serão armazenados várias vezes como chave estrangeira . E, consequentemente, levará a degradar o desempenho.
fonte
Depende da mesa. Se as linhas na sua tabela representam endereços de email, o email é o melhor ID. Caso contrário, o email não é um bom ID.
fonte
Se for apenas uma questão de exigir que o email seja exclusivo, basta criar um índice exclusivo com essa coluna.
fonte
O email é um bom candidato a índice exclusivo, mas não para a chave primária; se for uma chave primária, você não poderá alterar o endereço de email do contato, por exemplo. Acho que suas consultas de junção também serão mais lentas.
fonte
não use o endereço de email como chave primária, mantenha o email como único, mas não o use como chave primária, use o ID do usuário ou nome de usuário como chave primária
fonte