Seria uma má prática ter vários FKs anuláveis ​​em uma tabela no SQL Server

13

Na minha estrutura de banco de dados no SQL Server, tenho 3 tipos de produtos que requerem informações diferentes sobre o pedido. Então, eu criei uma Customersmesa e três tabelas diferentes ordens: OrdersForProductAs, OrdersForProductBs, OrdersForProductCs. Todas as tabelas de pedidos têm um para muitos relacionamentos na Customerstabela.

Também tenho outra tabela que Paymentscontém e mantém os detalhes do pagamento. Mas tenho dúvidas aqui sobre como estruturá-lo.

Como tenho vários tipos de produtos e um cliente pode ter pedidos de vários produtos ao mesmo tempo, preciso relacionar essas três tabelas de pedidos à Paymentstabela.

A outra questão é que um cliente pode ter um pedido para apenas um tipo de produto. Portanto, as colunas FK na Paymentstabela precisam ser nullable.

Minha pergunta é se essas nullablecolunas FK seriam uma dor de cabeça para mim a longo prazo ou não? De um modo geral, seria uma má prática ter colunas FK anuláveis ​​em uma tabela?

tugberk
fonte
2
Certifique-se de incluir uma restrição de verificação para que pelo menos um desses FKs não seja nulo.
Damien_The_Unbeliever
3
Uma chave estrangeira anulável é demais.
Nvogel

Respostas:

13

Gostaria de perguntar por que você tem OrdersForProductXtabelas.
É possível que o problema do FK que você perguntou possa ser planejado ...

Se essas tabelas tiverem a mesma estrutura, você simplesmente precisará de uma ProductTypecoluna em alguma OrderProducttabela. Em seguida, Paymentbasta vincular a isso com um FK

Se a tabela tiver estruturas diferentes, presumo que elas tenham alguns atributos em comum. Portanto, você pode ter uma OrderProducttabela comum e, em seguida, tabela filha específica por tipo de produto (veja abaixo). Novamente, Paymentbasta vincular à tabela comum com um FK

Este é o "padrão de superchave / subtipo"

  • UQ1 é a "super chave" usada uma chave estrangeira nas tabelas de subtipos
  • Cada tabela de subtipo possui um PK e um FK compostos em (OrderID, ProductType)
  • Cada tabela de subtipo possui uma restrição CHECK para restringir os tipos nessa tabela

OrderProduct

  • Código do pedido, PK, UQ1
  • Tipo de produto, UQ1
  • CommonThing1
  • ...

OrderProductA

  • Código do pedido, PK, FK
  • Tipo de produto, PK, FK, CHECK Tipo de produto = A
  • ProductAThing1
  • ...

OrderProductB

  • Código do pedido, PK, FK
  • Tipo de produto, PK, FK, CHECK Tipo de produto = B
  • ProductBThing1
  • ...
gbn
fonte
4
@ Tugberk: Observe que você não terá NULLcolunas FK com essa abordagem.
ypercubeᵀᴹ
"Se essas tabelas tiverem a mesma estrutura" Elas não terão a mesma estrutura.
tugberk
5

Evite "chaves estrangeiras" anuláveis. Eles têm várias desvantagens.

A restrição em uma linha de referência nem sempre é imposta quando a chave estrangeira contém um nulo. No entanto, esse comportamento padrão não é consistente entre diferentes DBMSs. Alguns DBMSs suportam opções de configuração para alterar o comportamento de chaves estrangeiras anuláveis ​​e outras não. Os desenvolvedores e usuários de SQL podem, portanto, não ter certeza sobre o que uma restrição de chave estrangeira anulável realmente significa da perspectiva da integridade dos dados. Portar o banco de dados entre produtos DBMS ou mesmo entre servidores diferentes usando o mesmo produto pode gerar resultados inconsistentes.

As ferramentas de design de banco de dados, as ferramentas de integração e outros softwares nem sempre os suportam corretamente e os resultados que eles produzem podem estar errados.

Chaves estrangeiras são freqüentemente usadas em junções e outras lógicas de consulta, compondo os problemas para usuários que pensam que a restrição está em vigor quando não existe ou que não conhecem a lógica que está sendo aplicada pelo seu DBMS específico.

Alguns recursos de otimização de consulta que permitem reescritas e outras otimizações podem não estar disponíveis quando uma chave estrangeira é anulável.

Em termos lógicos, uma restrição de "chave estrangeira" anulável não faz muito sentido lógico. De acordo com o padrão SQL, essa restrição não pode ser violada, mesmo que a tabela que está sendo referenciada esteja vazia. Isso contradiz uma das justificativas alegadas mais comuns para o uso de um nulo - que representa o caso "desconhecido". Se não houver valores válidos para X, qualquer X "desconhecido" certamente não poderá ser um valor válido - e, no entanto, o SQL permitirá.

Chaves estrangeiras anuláveis ​​são completamente desnecessárias. Você sempre pode decompor a chave estrangeira em uma nova tabela ou usar um padrão de supertipo / subtipo para que nulos não sejam necessários. Por uma questão de simplicidade e precisão, é melhor deixar nulos do que colocá-los.

nvogel
fonte
2

Nunca ouvi dizer que era uma prática ruim usar colunas FK anuláveis. Eles são o ajuste ideal para uma coluna que faz referência a outra tabela, mas pode não ser preenchida (ou seja, são dados opcionais).

(Por que você acha que seria um problema?)

StilesCrisis
fonte
Obrigado! Bem, não tenho muita certeza disso, mas tive um projeto como esse alguns anos atrás e lembro que estava com dores de cabeça em alguma coisa . Portanto, não estou claro como você vê: s é por isso que fiz a pergunta.