Capítulo 07: Relacionamentos N para M (Muitos para Muitos) e Tabelas Associativas

🎯 Objetivo da Aula

Nesta aula avançada de modelagem relacional, você aprenderá a resolver o cenário mais comum e desafiador da logística corporativa: o relacionamento Muitos para Muitos (N:M). No laboratório de informática, você compreenderá por que nenhum SGBD relacional permite ligar diretamente duas tabelas com cardinalidade N:M e aprenderá a técnica canônica de decomposição em dois relacionamentos 1:N utilizando uma Tabela Associativa (Junction / Bridge Table). Você aprenderá também a criar uma Chave Primária Composta (Composite Primary Key) no Access.

Ao final desta aula, seu banco de dados será capaz de detalhar os manifestos de carga da FastLog S.A., permitindo que uma única viagem transporte dezenas de mercadorias diferentes com controle rigoroso de pesos e valores declarados.


🏢 Cenário Prático (FastLog S.A.)

Empresa: FastLog Transportes & Logística Integrada S.A.
Problema: No Centro de Distribuição Fracionado, uma carreta nunca viaja com um único item. A ordem de frete OF-1050 transportava 40 caixas de smartphones, 12 pallets de autopeças e 80 fardos de tecidos. Na tentativa de registrar isso em uma planilha, o operador criou as colunas Produto_1, Qtd_1, Valor_1, Produto_2, Qtd_2, Valor_2... até Produto_10. Quando um cliente industrial contratou o transporte de 14 tipos de mercadorias no mesmo caminhão, a planilha simplesmente não tinha colunas suficientes! O operador começou a digitar múltiplos itens na mesma célula separados por vírgula, inviabilizando totalmente a soma do seguro de carga e o cálculo de cubagem.
Sua Missão: Como modelador sênior de dados, você criará a tabela mestre de produtos (tbl_Produtos) e a tabela associativa de itens de carga (tbl_ItensFrete). Você decomporá a relação N:M em duas relações 1:N perfeitas, permitindo que uma ordem de frete transporte de 1 até 1.000 mercadorias distintas com cálculo automático de peso e seguro.


🧠 Fundamentos: A Teoria Traduzida

1. A Natureza do Problema Muitos para Muitos (N:M)

No transporte e na administração:

  • Uma Ordem de Frete contém Muitas Mercadorias.
  • Uma Mercadoria (ex: “Sacas de Café”, “Pneus Aro 17”) está presente em Muitas Ordens de Frete ao longo do mês.
  • O Dilema: Onde colocar a Chave Estrangeira? Se colocarmos ID_Produto na tabela de frete, o frete só poderá ter um produto. Se colocarmos ID_OrdemFrete na tabela de produtos, o produto só poderá ser transportado em uma única viagem em toda a história da empresa!
erDiagram
    tbl_OrdensFrete ||--o{ tbl_ItensFrete : "1 : N (contém)"
    tbl_Produtos ||--o{ tbl_ItensFrete : "1 : N (composto por)"

    tbl_OrdensFrete {
        Autonumber ID_OrdemFrete PK
        Date Data_Despacho
        Currency Valor_Frete
    }

    tbl_ItensFrete {
        Long ID_OrdemFrete PK_FK
        Long ID_Produto PK_FK
        Integer Qtd_Volumes
        Long Peso_Aferido_Kg
        Currency Valor_Declarado_Item
    }

    tbl_Produtos {
        Autonumber ID_Produto PK
        ShortText Descricao_Mercadoria
        ShortText Categoria
        Currency Valor_Seguro_Sugerido
    }

2. A Solução: A Tabela Associativa (Junction Table)

Para resolver o impasse de forma matematicamente perfeita, os bancos de dados utilizam uma terceira tabela intermediária, chamada Tabela Associativa:

  • Ela fica posicionada no centro, recebendo duas pontas de cardinalidade Vários ($\infty$).
  • O relacionamento original $N:M$ transforma-se em: $$\text{tbl_OrdensFrete (1)} \longleftrightarrow (\infty)\ \text{tbl_ItensFrete}\ (\infty) \longleftrightarrow \text{(1) tbl_Produtos}$$

3. A Chave Primária Composta (Composite Primary Key)

Na tabela associativa tbl_ItensFrete, nenhuma das duas chaves estrangeiras pode ser chave primária isolada, pois elas se repetem. No entanto, a combinação das duas chaves (ID_OrdemFrete + ID_Produto) é absolutamente única!

  • Como fazer no Access: No Modo Design, seguramos a tecla Ctrl, clicamos sobre os seletores de linha dos dois campos simultaneamente e clicamos no botão Chave Primária 🔑. O Access colocará uma chave dourada nos dois campos ao mesmo tempo!

📖 Exemplo Guiado: Passo a Passo no Laboratório

Abra o arquivo FastLog_Database.accdb. Vamos construir o catálogo de mercadorias e a tabela associativa de manifesto.

Passo 1: Criando a Tabela de Produtos (tbl_Produtos)

  1. Acesse Criar ➔ Design da Tabela.
  2. Adicione os seguintes campos:
    • ID_Produto: Autonumeração, Chave Primária 🔑.
    • Descricao_Produto: Texto Curto, Tamanho: 70, Requerido: Sim.
    • Categoria_Carga: Texto Curto, Tamanho: 30 (Ex: Eletrônicos, Alimentos, Químicos, Têxtil).
    • Tipo_Embalagem: Texto Curto, Tamanho: 20 (Ex: Palete, Caixa, Tambor, Fardo).
    • Peso_Medio_Unitario_Kg: Número, Tamanho: Inteiro.
  3. Salve a tabela com o nome: tbl_Produtos.
  1. Abra tbl_Produtos no Modo Folha de Dados e cadastre:
    • Linha 1: ID 1 | Smartphones 5G Modelo Pro | Eletrônicos | Caixa Lacrada | 15
    • Linha 2: ID 2 | Sacas de Café Arábica Especial | Alimentos | Saca 60kg | 60
    • Linha 3: ID 3 | Bobinas de Aço Laminado | Metalurgia | Bobina Cinta | 2500

🛠️ Prática Obrigatória 1: Criando a Tabela Associativa com Chave Composta

Agora você construirá a tabela central do manifesto de carga: tbl_ItensFrete.

Passo a Passo no Computador:

  1. Acesse Criar ➔ Design da Tabela.
  2. Adicione a estrutura da tabela associativa:
Nome do CampoTipo de DadosPropriedades Técnicas
ID_OrdemFreteNúmeroTamanho: Inteiro Longo, Requerido: Sim
ID_ProdutoNúmeroTamanho: Inteiro Longo, Requerido: Sim
Qtd_VolumesNúmeroTamanho: Inteiro, Regra de Validação: >0, Requerido: Sim
Peso_Aferido_KgNúmeroTamanho: Inteiro Longo, Regra: >0, Requerido: Sim
Valor_Declarado_ItemMoedaFormato: Moeda, Regra: >0, Requerido: Sim
  1. Criando a Chave Primária Composta:
    • Clique no seletor de linha cinza à esquerda de ID_OrdemFrete.
    • Mantenha a tecla Ctrl pressionada no teclado.
    • Clique no seletor de linha cinza de ID_Produto.
    • Com os dois campos selecionados (destacados em azul), clique no botão Chave Primária (ícone da chave dourada 🔑 na faixa de opções).
    • Observe: Ambos os campos passam a exibir a chave dourada 🔑!
  2. Salve a tabela com o nome oficial: tbl_ItensFrete e feche-a.

✅ Resultado Esperado (Prática 1):

A tabela tbl_ItensFrete é criada com chave primária composta de dois campos, impedindo que o mesmo produto seja inserido duas vezes na mesma viagem com linhas repetidas.


🛠️ Prática Obrigatória 2: Vinculando a Tabela Associativa na Janela de Relações

Agora você conectará o coração relacional da transportadora.

Passo a Passo no Computador:

  1. Abra a Janela de Relações (Ferramentas de Banco de Dados ➔ Relações).
  2. Clique no botão Adicionar Tabelas e adicione:
    • tbl_Produtos
    • tbl_ItensFrete
  3. Posicione tbl_ItensFrete visualmente entre tbl_OrdensFrete e tbl_Produtos.
  4. Criando a Conexão 1 (Frete ➔ Itens):
    • Arraste ID_OrdemFrete de tbl_OrdensFrete para ID_OrdemFrete de tbl_ItensFrete.
    • Marque: ☑ Exigir Integridade Referencial.
    • Marque: ☑ Propagar Exclusão dos Registros Relacionados (Aqui a exclusão em cascata É PERMITIDA, pois se um frete for cancelado antes de faturar, seus itens de manifesto devem ser apagados juntos!).
    • Clique em Criar.
  5. Criando a Conexão 2 (Produtos ➔ Itens):
    • Arraste ID_Produto de tbl_Produtos para ID_Produto de tbl_ItensFrete.
    • Marque: ☑ Exigir Integridade Referencial.
    • Deixe Propagar Exclusão DESMARCADA (para nunca apagar o cadastro de mercadorias!).
    • Clique em Criar.
  6. Salve o diagrama e feche a janela.
  7. Povoando um Frete Multi-Itens:
    • Abra tbl_ItensFrete e adicione para a ordem 1:
      • ID_OrdemFrete: 1 | ID_Produto: 1 | Qtd: 200 | Peso: 3000 | Valor: R$ 600.000,00
      • ID_OrdemFrete: 1 | ID_Produto: 2 | Qtd: 150 | Peso: 9000 | Valor: R$ 180.000,00

✅ Resultado Esperado (Prática 2):

A Janela de Relações exibe a arquitetura clássica em “Y” com a tabela associativa recebendo duas pontas do símbolo $\infty$, permitindo múltiplos itens por viagem.


📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o banco de dados e feche o Access.
  2. Nomeie o arquivo: FastLog_BD_Cap07_SeuNome_SeuSobrenome.accdb.
  3. Acesse o Microsoft Teams na equipe da disciplina.
  4. Abra a tarefa: “Banco de Dados - Cap 07: Relações N:M e Tabelas Associativas”.
  5. Anexe o seu arquivo .accdb e clique em Entregar (Turn In).

💡 Checkpoint de Gestão & TI

Por que entender a Tabela Associativa diferencia um técnico amador de um verdadeiro especialista em logística? Porque no mundo real, tudo é N:M: pedidos e produtos, rotas e pedágios, caminhões e motoristas, notas fiscais e conhecimentos de transporte. Quem domina tabelas associativas e chaves compostas é capaz de modelar qualquer sistema de ERP do mercado global, do SAP ao Totvs Protheus.


🔥 Desafio de Fixação: Prevenção de Duplicidade pela Chave Composta

Teste a robustez da Chave Primária Composta que você acabou de criar:

  1. Abra a tabela tbl_ItensFrete no Modo Folha de Dados.
  2. Tente inserir uma terceira linha com exatamente os mesmos códigos da primeira:
    • ID_OrdemFrete: 1
    • ID_Produto: 1
    • Qtd_Volumes: 50
    • Peso_Aferido_Kg: 750
    • Valor_Declarado_Item: 150000
  3. Tente salvar a linha ou mudar de registro.
  4. Documente no seu caderno a mensagem de erro emitida pelo motor do Access e explique por que esse comportamento protege a integridade do manifesto de carga.

🔑 Revelar Gabarito Oficial e Material de Apoio da Aula (Clique para expandir)
💡 Incentivo Pedagógico: Tente resolver as práticas e o desafio de fixação por conta própria antes de abrir o gabarito. Seus erros e tentativas durante o laboratório são a chave para a consolidação real do aprendizado!

Resposta Técnica do Desafio de Fixação:

1
2
3
4
5
Mensagem emitida pelo Microsoft Access:
"As alterações solicitadas para a tabela não foram bem-sucedidas porque criariam valores duplicados no índice, chave primária ou relação."

Explicação Técnica:
A chave primária composta é formada pela junção (ID_OrdemFrete + ID_Produto). O par (1, 1) já havia sido gravado na primeira linha da tabela. Ao tentar gravar novamente o par (1, 1), o motor relacional impede a duplicação, forçando o operador a somar a quantidade na linha já existente (ex: alterar de 200 para 250 volumes). Isso impede duplicidades contábeis e cobrança de seguro em duplicidade para a mesma mercadoria no mesmo frete.

📥 Download dos Scripts desta Aula:
Baixe o arquivo de script Capitulo_07.sql ou o pacote compactado (.zip) com os comandos SQL e esquemas da aula.


📝 Atividade Extra: Questionário de Fixação (Caderno)

Instruções: Responda no caderno, de próprio punho, as 10 perguntas reflexivas abaixo com base no conteúdo deste capítulo. Ao concluir, apresente o caderno ao professor para conferência e visto.

  1. Explique por que a relação entre Ordens de Frete e Produtos Transportados é de cardinalidade Muitos para Muitos (N:M).
  2. Por que sistemas de banco de dados relacionais não permitem conectar diretamente duas tabelas em cardinalidade N:M?
  3. O que é uma Tabela Associativa (Junction / Bridge Table) e como ela resolve o problema da relação N:M?
  4. No Cenário Prático da FastLog, qual foi o erro de modelagem cometido na planilha do Excel que gerou a limitação de produtos por viagem?
  5. O que é uma Chave Primária Composta (Composite Primary Key) e como ela se diferencia de uma chave primária simples?
  6. Qual é o atalho de teclado utilizado no Modo Design do Access para selecionar múltiplos campos simultaneamente e definir a chave composta?
  7. Cite dois exemplos de atributos próprios do fato do relacionamento que pertencem exclusivamente à tabela tbl_ItensFrete e não à tabela de produtos.
  8. Na Prática Obrigatória 2, por que foi aceitável ativar a “Exclusão em Cascata” na relação entre tbl_OrdensFrete e tbl_ItensFrete?
  9. Na mesma prática, por que a “Exclusão em Cascata” DEVE permanecer desmarcada na relação entre tbl_Produtos e tbl_ItensFrete?
  10. No Desafio de Fixação, qual foi a reação do Access quando você tentou cadastrar o produto ID 1 duas vezes na mesma ordem de frete ID 1?