Chave exclusiva ou primária do endereço de e-mail?

11

Eu sou um novato em bancos de dados. Eu li e descobri que provavelmente não é uma boa idéia usar o endereço de email como chave primária, porque as comparações de string são mais lentas, o que afeta o desempenho em junções complexas e, se um email mudar, eu teria que alterar todas as chaves estrangeiras, o que exige muito de esforço.

Mas se minha tabela de usuários exigir que todos os usuários tenham um endereço de email e cada um desses endereços seja único, será suficiente adicionar um índice exclusivo na coluna de email? Como os campos exclusivos do afaik permitem valores nulos, enquanto eu exijo que todo usuário tenha um endereço de email, não permitindo valores nulos. Há algo que estou perdendo aqui? Ou eu suponho que a coluna de email seja única e verifique durante a validação de dados no servidor que o usuário insira um endereço de email para que todo usuário tenha um?

aandis
fonte
3
O que acontece quando um usuário altera seu endereço de e-mail - como, por exemplo, mudar de emprego
user151019
1
As comparações de strings não são apenas mais lentas, as strings também tendem a ser maiores do que digamos, um número inteiro e, portanto, você pode caber menos em uma página na memória, aumentando suas leituras lógicas para consultas.
Nameless One

Respostas:

7

Vamos primeiro distinguir entre chaves e índices, a chave faz parte do modelo lógico e é frequentemente implementada com um índice exclusivo. No entanto, você pode criar um índice exclusivo sem criar uma chave, mas isso não pode ser referenciado por uma chave estrangeira.

Uma chave candidata é algo que identifica exclusivamente uma linha em uma tabela. No SQL, uma das chaves candidatas é normalmente usada como chave primária (nunca entendi realmente por que uma das ck é considerada "melhor" que as outras, mas essa é outra). história), e o ck restante se torna restrições únicas.

Uma restrição exclusiva pode ser usada da mesma maneira que uma chave primária. Considerar:

create table A ( x ... not null
               , y ... not null
               , z ... not null
               ,     unique (x)
               ,     primary key (y,z) );

create table B ( x ...
               ,   ...
               ,     foreign key (x) references A (x) );

create table C ( y ...
               , z ...
               ,   ...
               ,     foreign key (y, z) references A (y, z) );  

B faz referência à restrição exclusiva e C faz referência à restrição de chave primária.

NOT NULL é outro tipo de restrição. No seu caso, você pode aplicar isso a emails sem declará-los únicos.

O próximo aspecto da sua postagem diz respeito à estabilidade de uma chave, uma chave deve ser estável (mas isso não significa que ela nunca pode mudar, não precisa ser imutável). Alguns DBMS implementam o ON UPDATE CASCADE que podem ser úteis para essa operação, ainda que a chave seja distribuída em torno do seu modelo, será difícil atualizá-lo.

No seu caso, eu provavelmente escolheria outra chave candidata como chave primária e declararia o email como NOT NULL e UNIQUE.

Lennart
fonte
1
No SQL Server, você pode fazer referência a um índice exclusivo como um FK.
Martin Smith
1
Como não tenho acesso ao sql, não posso verificar por mim mesmo; isso cria implicitamente uma restrição exclusiva quando você cria um índice exclusivo?
Lennart
1
Não. Uma restrição exclusiva é tratada de maneira um pouco diferente e possui alguns metadados adicionais e restrições adicionais em comparação com um índice exclusivo, mas o SQL Server permite que seja usado em um FK.
Martin Smith
1
Isso é um pouco estranho, então, os índices nem sequer são mencionados no padrão sql, enquanto as chaves são uma parte central dele. De qualquer forma, obrigado pela informação.
Lennart
É importante notar que, se houver muitos registros com chave estrangeira no seu e-mail, poderá levar um bom tempo para atualizar todos esses registros quando a atualização ocorrer em cascata.
Cimmanon
6

Sim, ter um índice exclusivo na coluna EmailAddress deve estar ok. O único problema seria se alguém desistisse do endereço de email depois de se inscrever no serviço, mas não lhe dissesse, quem quer que o proprietário do endereço de email tente se inscrever. Mas esse é um caso bastante raro.

Se um índice exclusivo permite valores nulos que dependem da sua plataforma de banco de dados. Oracle faz, o SQL Server permite um único valor NULL. Você pode resolver isso fazendo a coluna não permitir valores NULL e construindo o índice exclusivo nela.

mrdenny
fonte
1
Isso não é verdade sobre o servidor SQL. Você pode criar índices com wherecláusulas que, por exemplo, permitem excluir NULLvalores do índice.
Kirk Woll
1
A afirmação SQL Server allows a single NULL valueainda é verdadeira. Não diz que não há como obter vários NULLvalores. Acho que o respondente estava tentando manter a resposta simples e não explicar detalhes extras (como o filtro indexado).
Brandon
1
Sim, eu poderia ter mergulhado no coelho inteiro de índices filtrados, mas uma pergunta simples geralmente precisa de uma resposta simples. Sem plataforma e versão de banco de dados, mantenho minhas respostas genéricas.
Mrdenny
2

Ter o índice exclusivo no EmailAddress é bom.

Como você já declarou que existe uma validação em seu aplicativo por ter o Endereço de email como campo obrigatório, eu diria que a outra validação seria do banco de dados não aceita um usuário sem um endereço de email e evita a entrada duplicada também e essa validação será imposto com este índice exclusivo.

Conforme declarado em outra resposta do SQL Server, você precisa criar uma coluna para não permitir valor nulo antes de criar índices exclusivos.

vijayp
fonte