Estou criando um site onde as pessoas podem avaliar/avaliar bebidas alcoólicas ("Destilados"). Dado que algumas bebidas destiladas podem variar muito de garrafa para garrafa, gostaria que os usuários tivessem a opção de revisar a bebida em si ou optar por revisar uma garrafa específica dessa bebida.
Considere as tabelas (SQL Server) abaixo:
Spirits
+--------+------------------+
| Column | Type |
+--------+------------------+
| Id | uniqueidentifier |
| Name | nvarchar(255) |
+--------+------------------+
Bottles
+----------+------------------+
| Column | Type |
+----------+------------------+
| Id | uniqueidentifier |
| SpiritId | uniqueidentifier |
+----------+------------------+
Ratings
+----------+------------------------+
| Column | Type |
+----------+------------------------+
| Id | uniqueidentifier |
| SpiritId | uniqueidentifier |
| BottleId | uniqueidentifier, null |
| Score | int |
+----------+------------------------+
Estou me aproximando da Ratings
mesa corretamente? Em caso afirmativo, como faço para garantir que BottleId
é filho de SpiritId
?
Ou devo require SpiritId
or BottleId
, mas não ambos (e existe uma maneira de impor esse requisito no banco de dados?)
Tenho certeza de que uma pergunta como essa foi feita, mas estou tendo problemas suficientes para formulá-la sozinho, portanto, minhas tentativas de pesquisa não produziram nada de útil. Obrigado.
Uma maneira de fazer isso é com uma chave alternativa composta (restrição exclusiva) na
Bottles
tabelaSpiritId
eBottleId
nas colunas. ARatings
tabela pode então ter uma chave estrangeira referenciando ambas as colunas daBottles
tabela para garantir que a bebida e a garrafa correspondam. Observe que uma chave estrangeira pode fazer referência a colunas de uma restrição exclusiva ou de um índice exclusivo, não apenas à chave primária.As linhas com
NULL
valores de chave estrangeira não são verificadas quanto à integridade referencial, portanto, uma classificação comNULL
BottleId será permitida desde que o SpiritId seja válido, imposto apenas pela restrição de chave estrangeiraSpiritId
.Exemplo de DDL e dados:
Não vejo nada de muito errado com o seu design.
Você já está aplicando isso em sua
Bottles
tabela, fazendo referência aSpirit
por meio do campo de chave estrangeira não anulávelSpiritId
. Você vai querer ter certeza de criar um objeto de chave estrangeira para impor esse relacionamento, na prática.Uma maneira alternativa de estruturá-lo também é uma tabela separada para
SpiritRatings
vsBottleRatings
. Você não precisa fazer isso, pois seu design atual parece bom para mim à primeira vista, mas você pode achar esse design alternativo mais benéfico no futuro, caso adicione colunas às classificações que se aplicam apenas a um, mas não ao outro.