phpMyAdmin
 sql >> Base de Dados >  >> Database Tools >> phpMyAdmin

Como configurar o relacionamento entre tabelas no phpMyAdmin


A restrição de chave estrangeira table2 significa que qualquer valor customerId table2 deve aparecer como customerId em table1. Você está recebendo o erro porque está inserindo um customerID na tabela2 que não aparece na tabela1.

Como o SGBD está gerando customerIDs table1 por incremento automático, se você inserir uma linha, terá que obter esse valor para inserir uma linha usando esse customerID na tabela2.

Eu acho que você diz "Eu já estabeleci um relacionamento entre tabela1 e tabela2" para significar "Eu declarei uma restrição de chave estrangeira". E acho que você acha que isso significa "depois de inserir na tabela1, o DBMS usará o valor da chave gerada automaticamente como o valor da chave estrangeira quando eu inserir na tabela2". Mas isso não significa isso. Você tem que fazer isso sozinho. A restrição de chave estrangeira significa apenas que o DBMS verifica se cada valor table2 customerId aparece como um valor table1 customerId.

Você pode e deve usar qualquer valor de chave inserido anteriormente como o valor correspondente ao inserir em uma tabela com uma chave estrangeira para essa chave.

Para recuperar o valor da chave incrementado automaticamente gerado pelo DBMS, use LAST_INSERT_ID() :
INSERT INTO table1 (CustomerName,Address,State)
VALUES('value1','value2','value3');
INSERT INTO table2 (customerId,product,cost)
VALUES(LAST_INSERT_ID(),'valueA','valueB');

É para isso que serve. Mas aqui estão os problemas se você não usá-lo.

Primeiro, se você não estiver em uma transação serializada, deverá usar LAST_INSERT_ID(). Porque após a inserção da tabela1, mas antes da inserção da tabela2, outras pessoas podem ter adicionado linhas e/ou linhas excluídas, incluindo sua nova linha e/ou alteradas, incluindo sua nova linha. Portanto, você não pode confiar em consultar table1 após sua inserção obter algum valor customerId que você sabe que adicionou.

Segundo, suponha que você esteja em uma transação serializada e não use LAST_INSERT_ID().

Se (CustomerName,Address,State) também for uma superchave da tabela1, ou seja, seus valores são únicos, ou seja, SQL UNIQUE/KEY/PK é declarado em todas ou algumas de suas colunas, então você pode usá-lo para consultar o novo customerId associado:
set @customerId = (
    SELECT customerId
    FROM table1
    WHERE CustomerName = 'value1'
    AND Address = 'value2'
    AND State = 'value3');
INSERT INTO table2 (customerId,product,cost)
VALUES(@customerId,'valueA','valueB');

Mas se (CustomerName,Address,State) não for uma superchave da tabela1, você não pode fazer isso. Porque outras linhas duplicadas para essa sublinha podem estar em table1. Assim, você pode obter várias linhas de volta. Então você não saberia qual é o mais novo. Em vez disso, você precisa consultar table1 antes da inserção, inserir e encontrar a diferença entre os conjuntos antigo e novo de customerIds:
CREATE TEMPORARY TABLE table1old (
    customerId (int) PRIMARY KEY
    );
INSERT INTO table1old
SELECT customerId FROM table1;

INSERT INTO table1 (CustomerName,Address,State)
VALUES('value1','value2','value3');

set @customerId = (
    SELECT customerId
    FROM table1
    WHERE CustomerName NOT IN table1old);
INSERT INTO table2 (customerId,product,cost)
VALUES(@customerId,'valueA','valueB');

Basta usar LAST_INSERT_ID().

PS:Curiosamente, dadas as definições da tabela, o ideal seria escrever:
INSERT INTO (
    SELECT CustomerName,Address,State,A,B
    FROM table1 JOIN table2
    USING (CustomerId))
VALUES('value1','value2','value3','valueA','valueB')

uma vez que há apenas um par de novos valores table1 &table2 que podem resultar. Existem algumas atualizações legais por meio de visualizações no SQL, embora nenhuma envolvendo várias tabelas no MySQL atualmente