MySQL - 如何使用外键向多个表中插入数据

13

我是MySQL的新手,请多关照 :)

我想从PHP表单中插入数据到三个不同的表中,这些表都有外键。我该如何编写一个插入命令来同时更新这三个表呢?因为如果我尝试手动更新表,则由于缺少引用而出现错误。 我需要处理“NULL”条目并逐个更新每个表吗?还是可以用一个单一的命令解决这个问题?就像MySQLi_Multi_Query这样的命令?

非常感谢!


请您能否发布模式的相关部分? - Christian Mann
4个回答

32
你可以用三种方法完成:
第一种方法,建议使用“SELECT IN THE INSERT VALUE”方式:
   INSERT INTO user (name)
     VALUES ('John Smith');
INSERT INTO user_details (id, weight, height)
     VALUES ((SELECT id FROM user WHERE name='John Smith'), 83, 185);
第二点。在INSERT VALUE中使用LAST_INSERT_ID:
INSERT INTO a (id)
     VALUES ('anything');
INSERT INTO user_details (id, weight, height)
     VALUES (LAST_INSERT_ID(),83, 185);

第三步. 使用PHP脚本

<?php
// Connecting to database
$link = mysql_connect($wgScriptsDBServerIP, $wgScriptsDBServerUsername, $wgScriptsDBServerPassword, true);
if(!$link || !@mysql_SELECT_db($wgScriptsDBName, $link)) {
echo("Cant connect to server");
    exit;
}

// Values to insert
$name = 'John Smith';
$weight = 83;
$height = 185;

// insertion to user table
$sql = "INSERT INTO user (name) VALUES ('$name')";
$result = mysql_query( $sql,$conn );
// retrieve last id
$user_id = mysql_insert_id( $conn );
mysql_free_result( $result );

// insertion to user_details table
$sql = "INSERT INTO user_details (id, weight, height) VALUES ($user_id, $weight, $height)";
$result = mysql_query( $sql,$conn );
mysql_free_result( $result );
?>

5
小心第一个也是推荐的建议。那假设只有一个“John Smith”。如果名称不是唯一的列,那就会有麻烦。使用LAST_INSERT_ID()是正确的方法。 - kontiki
这些多表插入是原子性的吗?即,要么更新2个表,要么为零(如果存在任何中间错误)?还是必须使用“开始事务”来确保原子性? - colm.anseo

10

您很可能需要按照它们的依赖关系插入内容。因此,如果您有三个表(A、B和C),我们假设C依赖于B,B依赖于A。我们还假设每个表分别具有主键AID、BID和CID。

  1. 您将向A中插入行并获取AID。
  2. 然后,您将使用步骤1中获取的AID向B中插入行。
  3. 然后,您将使用步骤2(及可能是步骤1)中获取的BID(和可能的AID)向C中插入行。

在您的方式中,我们必须逐个执行SQL,这可能会导致性能问题。是否有一种解决方案可以在一个SQL中插入所有相关行?现在,我在考虑,如果我可以获得一个AID列表而不插入行,会怎样? - oppo
你可以研究一下MySQL的批量插入(我只在MSSQL中有经验)。然后,你可以将所有三个批量插入封装到一个事务中(这样如果一个失败了,所有的都会回滚)。 - Corith Malin

4
您的方法1语法存在错误。
INSERT INTO user_details (id, weight, height)
     VALUES (SELECT(id FROM user WHERE name='John Smith'), 83, 185);

应该是

INSERT INTO user_details (id, weight, height)
     VALUES ((SELECT id FROM user WHERE name='John Smith'), 83, 185);

1

1) foreign_key 的意义在于将一个字段中的值与其他地方的预先存在的值关联起来。因此,您应该按逻辑顺序进行插入。

2) 如果您想避免逻辑限制,您应该

SET foreign_key_checks = 0  // disable key checks in server
INSERT ... // any order
INSERT ...
...
SET foreign_key_checks = 1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接