Tenho um cenário em que preciso projetar uma estrutura de banco de dados SQL no MariaDB, mas não sou arquiteto de banco de dados e quero fazer certo na primeira tentativa.
Então, eu tenho uma tabela de produtos que, para fins de legibilidade, tem 2 campos, id e name. Não tenho ideia de como fazer esse gráfico, então usarei json para defini-lo:
productColumns = {
id: "INTEGER",
name: "STRING",
}
Então eu tenho a tabela de variantes:
variantsColumns = {
id: "INTEGER",
name: "STRING",
product_id: "INTEGER",
}
Agora o objetivo. Preciso adicionar Bundles e Carts . Bundles precisam conter vários produtos com uma variante especificada. Carts precisam conter vários produtos com uma variante especificada e também bundles. Agora preciso da capacidade de também adicionar descontos a carrinhos e bundles como um todo, mas também adicionar descontos a produtos específicos do carrinho ou do bundle.
O que eu pensei:
bundlesColumns: {
id: "INTEGER",
name: "STRING",
discount_type: "PERCENTAGE|ABSOLUTE"
discount: "INTEGER"
}
bundleItems: {
id: "INTEGER",
bundle_id: "INTEGER",
discount_type: "PERCENTAGE|ABSOLUTE",
discount: "INTEGER",
product_id: "INTEGER",
variant_id: "INTEGER",
quantity: "INTEGER",
}
carts: {
id: "INTEGER",
discount_type: "PERCENTAGE|ABSOLUTE"
discount: "INTEGER"
}
cartItems: {
id: "INTEGER",
cart_id: "INTEGER",
discount_type: "PERCENTAGE|ABSOLUTE",
discount: "INTEGER",
product_id: "INTEGER",
variant_id: "INTEGER",
bundle_id: "INTEGER",
quantity: "INTEGER"
}
Eu já projetei alguns bancos de dados antes, mas algo sobre essa estrutura parece estranho, parece que vai ser uma dor de cabeça para desenvolvimento futuro e queria saber sua opinião sobre isso. Existe uma maneira melhor de fazer isso?
Você pode criar as seguintes tabelas e índices
Seu problema (o "pressentimento" que você tem) está relacionado a este design desnormalizado:
Isso permite
cartItems
que sejam dois tipos de coisas completamente diferentes: um pacote e um único produto. Este é um exemplo de uma Associação Polimórfica. Seu design existente só pode ser retificado pelo uso de umaCHECK
restriçãoIsso pode tornar esta tabela um tanto difícil de usar, pois a junção a ela pode se tornar condicional.
Projetos alternativos incluem:
Faça
product_id
evariant_id
obrigatório (não anulável) e tenha os três pares(product_id, variant_id, bundle_id)
com chave estrangeira parabundleItems
.Nessa nota,
bundleItems
é uma tabela de junção e, portanto, não deve ter umaid
coluna separada. Em vez disso, sua chave primária deve ser uma chave composta feita dessas mesmas três colunas.Este design também tem a desvantagem de não ser possível impor a adição de todo o pacote, apenas parte dele.
Observe a falta de uma
id
coluna, pois as colunas compostas denotam a chave primária.Esse design é o mais normalizado, mas pode ser um pouco difícil de consultar, pois você precisa consultar as duas tabelas separadamente e unir os resultados.
Isso pode ser bastante pesado em termos de armazenamento se houver apenas alguns itens que realmente precisam ser agrupados, mas é o mais fácil de consultar.