Dúvida com Modelagem de Banco de Dados

Problema

Tenho algumas tabelas em um projeto de banco de dados, são elas:

  • tb_produto(id_produto, nome, descricao, id_categoria)
  • tb_categoria(id_categoria, nome)
  • tb_caracteristica(id_caracteristica, nome, id_produto)
  • tb_valor(id_valor, nome, preco, quantidade, id_caracteristica)
  • tb_imagem_valor(id_imagem, caminho, id_valor)
  • tb_venda(id_venda, descricao, id_vendedor, id_tipo_pagamento, data)
  • tb_item_venda(id_produto, id_venda, quantidade) Relacionamentos:
  • Um produto pode pertencer a uma categoria, e uma categoria pode ter vários produtos;
  • 1 produto pode ter várias características como voutagem, cor, e uma caracteristica pode ter vários valores; cor=amarelo, azul voutagem = 220V, 127V
  • Um valor de característica pode ter várias imagens
  • Uma venda pode ter vários itens de venda
  • Os ids da tabela de item_venda formam uma chave composta
  • Todos os relacionamentos são 1 pra n ou n pra 1

Dúvida

Como que eu posso modelar esse banco para inserir estes produtos com categoria a que pertence, caracteristicas, valores e imagens em um estoque, e como que eu faria pra salvar nas vendas qual caracteristica e valor foram escolhidos na hora da compra, pois desse geito que está, ao tentar buscar por um produto ele vai trazer todas as características e valores, mas em cada venda eu só queria o que foce escolhido Exemplo: Da forma que está: { "itens": [ { "nome": "Liquidificador", "categoria": "Eletrodomésticos", "caracteristicas": [ { "nome": "Cor", "valores": [ { "nome": "Amarelo" }, { "nome": "Branco" } ] } ] } } Fiz o json na mão, desculpa se ficou errado RS Então, caso eu compre um liquidificador amarelo, queria que na minha venda só salvace a referência desse produto/caracteristica/valor. Uma forma que pensei foi fazer isso, será que está certo? tb_item_venda(id_item, quantidade, id_produto, id_venda, id_caracteristica, id_valor) Já que a caracteristica teria o produto a qual pertence e o valor teria a referência da caracteristica. No caso, não usaria mais a chave composta Grato a quem puder ajudar!

Opa cara, tudo bem?

O que se pode fazer, e na vida real se faz assim mesmo, é criar uma cópia do produto como item do pedido de venda.

Como assim?

Imagine que você fez a compra de um produto. Depois da sua compra, o produto foi deletado do banco de dados. O que vai acontecer com o seu pedido? O item vai sumir? Isso não pode acontecer. O mesmo pode acontecer com as características.

Então, no momento da compra, você deve criar uma cópia dos dados do produto pertinentes ao pedido. Para as características, uma opção é salvar o nome e o valor, ao invés do Id.

Então como ficaria a tabela item_venda:

  • tb_item_venda(id_produto, nome, preco_compra_unidade, preco_compra_total, id_venda, quantidade, caracteristica_nome, caracteristica_valor, url_imagem)

Dica: acredito que o relacionamento correto para caracaterísticas e produtos seja de m para n. O preço e a imagem poderiam ficar na tabela do relacionamento

  • tb_produto_caracteristica_valor(id_produto, id_caracteristica, id_valor, preco, imagem_url)

Outra dica que digo de coração: te aconselho a estudar português e a ler mais. Leia de tudo, especialmente literatura clássica e ficção, algo que goste. Vai te ajudar bastante a melhorar a sua comunicação e seu aprendizado, além de outras soft skills.

Abraço, espero ter te ajudado. Continue estudando!

Opa, joaons! Sobre as chaves estrangeiras, na tabela item_venda, fiquei preocupado em guardar somente o nome e valor da característica, pois não pretendo excluir o produto do banco, só marcar como inativo mesmo. Pois fica mais fácil para gerar relatórios depois. Sobre o relacionamento produto e característica, faz sentido o relacionamento n pra n mesmo Muito obrigado pela ajuda e dicas!

Oi MatheusLima,  o que o joanse está correto. Em muitas aplicações os valores são copiados quando uma venda é feita para garantir a consistência de dados no momento da venda. Portanto, guardar apenas chaves estrangeiras (foreign keys) de outras tabelas não é o suficiente porque se os dados do produto mudarem acabam interferindo com os dados da venda.

Contudo, existem outras aplicações onde produtos com atributos diferentes acabam se tornando produtos distintos chamados variantes. Por exemplo, um camiseta da cor azul e tamanho médio é considerado um produto e a mesma camiseta da cor vermelha e de tamanho também médio é outro produto distinto; ambos têm a mesma identificação de variante portanto a aplicação sabe que são variações do mesmo produto. Combinado a isso, os produtos são imutáveis, para  atualizar um produto teríamos que na verdade fazer uma cópia do existente com a modificação desejada e nunca apagar o original (apenas marcar como apagado mais ainda existente no banco de dados). Em aplicações que usam estes dois conceitos (variantes + imutabilidade) teria sim como guardar apenas as identificações de produto e o preço atual quando a venda é feita. Porém, acho que a sua aplicação não tem estes conceitos.

Recomendo dar uma olhada como alguns bancos de dados de ecommerce funcionam porque é um assunto muito interessante. Ou pesquise sobre SKU e variantes de produtos.

abrs

Sim, pretendo não excluir um produto depois de cadastrado, pretendo marcar como inativo caso queira excluir