Implementando um relacionamento um para zero ou um no SQL

10

Digamos que estou projetando um banco de dados para um cenário em que exista um relacionamento de um para zero ou um (1-0..1). Por exemplo:

  • Há um conjunto de usuários e alguns usuários também podem ser clientes .

Assim, criei as duas tabelas correspondentes userse customers, mas ...

… Qual é a melhor maneira de representar e implementar essa situação em uma determinada plataforma SQL? Eu considerei duas soluções possíveis:

  1. Na userstabela, adicione a customercoluna que pode ser uma referência para FOREIGN KEY customersou uma NULLmarca.

  2. Na customerstabela, inclua uma usercoluna (definida com uma UNIQUErestrição) que aponta para a userstabela.

Eu já fiz uma pergunta semelhante em alguns fóruns, mas a resposta foi basicamente "o que você precisar", "o que achar conveniente". Eu não gosto desse tipo de resposta. Em vez disso, quero uma séria teoria da DB, uma resposta bem fundamentada. Onde posso ler sobre relacionamentos 1-0..1?

Porton
fonte

Respostas:

10

Eu quero um pedaço sério da teoria do DB

A teoria relacional moderna rejeita nulos , o que parece invalidar imediatamente sua opção 1. No entanto, esse palpite pode ser eliminado substituindo o nulo padrão por um valor padrão, por exemplo, um cliente 'fictício' criado apenas para modelar explicitamente o "não é um cliente" correspondência.

Eu acho que sua opção 2 é a mais sólida teoricamente porque, diferentemente da opção 1 modificada, as relações podem estar na sexta forma normal (6NF), sendo uma forma normal de junção de projeção e a forma normal mais alta possível.

Também ouvi falar de uma regra prática de design que afirma que uma relação deve modelar UMA entidade OU o relacionamento entre entidades, mas nunca as duas, o que me parece sensato. Novamente, isso favoreceria a opção 2. No entanto, ouvi falar dessa regra há muitos anos, não lembro onde e não posso oferecer uma base teórica séria (além da 6NF, como mencionado acima).

um dia quando
fonte
2

Você recebeu a resposta correta em parte. A resposta real vem do seu modelo de dados e de como ele foi normalizado. Uma chave é como você chega ao relacionamento:

  • A customerstabela consiste em vários campos considerados para a userstabela que pertencem ao conceito de cliente e são nulos, a menos que o usuário também seja um cliente (subtipo de usuário). Nesse caso, a customerstabela herda a chave primária da userstabela. (É possível vários subtipos que podem ou não se sobrepor.)

  • A customerstabela consiste em vários campos relacionados ao conceito de cliente, mas não necessariamente ao conceito de usuário. O cliente é uma mesa forte e não depende do conceito do usuário. (A remoção da userstabela não afetaria significativamente o design da tabela de clientes.) Nesse caso, a tabela de clientes obtém sua própria chave primária.

O que você tem é um caso especial de um relacionamento opcional para muitos, onde o limite superior é 1. Considere-o de ambos os lados: seria possível que um usuário tivesse vários clientes ou um cliente tivesse vários usuários? Nesse caso, você precisará remodelar seus dados.

Adicionar a user-idchave estrangeira à customerstabela pode ser considerado uma opção melhor, pois mapeia corretamente o relacionamento de um para muitos (limite superior 1) e evita um campo nulo. Para impor o limite superior, o índice de chave estrangeira precisa ser exclusivo. Isso ocorrerá automaticamente se a chave primária for user-id.

Adicionar a customer-idchave estrangeira opcional à userstabela impõe o limite superior de 1 no relacionamento, mas reverte a dependência.

BillThor
fonte
1

Você já considerou uma abordagem um pouco mais complexa, mas flexível. A tabela pai é "pessoa" (ou "entidade", dependendo de quão complexo você deseja ser). Em seguida, a tabela do cliente e a tabela do usuário têm um FK para a tabela da pessoa. A tabela de pessoa contém detalhes pessoais, enquanto as tabelas de cliente e usuário contêm apenas atributos associados a um usuário ou cliente. Muitas vezes, endereços (email e correio tradicional), números de telefone etc. também são representados em tabelas separadas com tabelas de mapeamento para permitir situações de muitos para muitos. Este é um modelo relativamente comum que você pode encontrar em vários sites de referência.

Raio
fonte