MySQL插入到多个表中? (数据库正常化?)
我试图寻找一种方法在同一个查询中的多个表中插入信息,但发现这是不可能的? 所以我想通过使用多重查询即插入它;
INSERT INTO users (username, password) VALUES('test', 'test') INSERT INTO profiles (userid, bio, homepage) VALUES('[id of the user here?]','Hello world!', 'http://www.stackoverflow.com')
但是,我怎样才能从用户的自动递增ID到configuration文件表的“手动”用户ID?
不,你不能在一个MySQL命令中插入多个表。 您可以使用交易。
BEGIN; INSERT INTO users (username, password) VALUES('test', 'test'); INSERT INTO profiles (userid, bio, homepage) VALUES(LAST_INSERT_ID(),'Hello world!', 'http://www.stackoverflow.com'); COMMIT;
看看LAST_INSERT_ID()
来重用自动增量值。
编辑:你说:“ 毕竟这个试图弄清楚,它仍然不起作用。我不能简单地把刚生成的ID放在一个$ var中,并把$ var放在所有的MySQL命令中?
让我详细说明一下:这里有三种可能的方法:
-
在上面看到的代码中。 这一切都在MySQL中完成,而第二个语句中的
LAST_INSERT_ID()
将自动成为插入到第一个语句中的autoincrement列的值。不幸的是,当第二个语句本身在一个带有自动增量列的表中插入行时,
LAST_INSERT_ID()
将被更新为表2的表,而不是表1.如果你之后仍然需要表1的话,将其存储在一个variables中。 这导致我们的方式2和3: -
将
LAST_INSERT_ID()
在一个MySQLvariables中:INSERT ... SELECT LAST_INSERT_ID() INTO @mysql_variable_here; INSERT INTO table2 (@mysql_variable_here, ...); INSERT INTO table3 (@mysql_variable_here, ...);
-
将
LAST_INSERT_ID()
在一个phpvariables(或任何可以连接到您select的数据库的语言)中:-
INSERT ...
- 使用你的语言来检索
LAST_INSERT_ID()
,或者通过在MySQL中执行该文字语句,或者使用例如php的mysql_insert_id()
来为你做这个 -
INSERT [use your php variable here]
-
警告
无论select什么方式来解决这个问题,你都必须决定在查询之间执行被中断 (例如,你的数据库服务器崩溃)应该发生什么。 如果你能忍受“一些已经完成,另一些没有”,不要继续阅读。
但是,如果您决定“要么所有查询都完成了,要么没有完成 – 我不希望某些表中的行存在,但是其他表中没有匹配的行,我总是希望我的数据库表保持一致”,则需要将所有语句包装在一个事务中。 这就是我在这里使用BEGIN
和COMMIT
的原因。
再次评论,如果你需要更多的信息:)
如果你使用存储过程相当简单:
call insert_user_and_profile('f00','http://www.f00.com');
完整的脚本:
drop table if exists users; create table users ( user_id int unsigned not null auto_increment primary key, username varchar(32) unique not null ) engine=innodb; drop table if exists user_profile; create table user_profile ( profile_id int unsigned not null auto_increment primary key, user_id int unsigned not null, homepage varchar(255) not null, key (user_id) ) engine=innodb; drop procedure if exists insert_user_and_profile; delimiter # create procedure insert_user_and_profile ( in p_username varchar(32), in p_homepage varchar(255) ) begin declare v_user_id int unsigned default 0; insert into users (username) values (p_username); set v_user_id = last_insert_id(); -- save the newly created user_id insert into user_profile (user_id, homepage) values (v_user_id, p_homepage); end# delimiter ; call insert_user_and_profile('f00','http://www.f00.com'); select * from users; select * from user_profile;
尝试这个
$sql= " INSERT INTO users (username, password) VALUES('test', 'test') "; mysql_query($sql); $user_id= mysql_insert_id(); if(!empty($user_id) { $sql=INSERT INTO profiles (userid, bio, homepage) VALUES($user_id,'Hello world!', 'http://www.stackoverflow.com'); /* or $sql=INSERT INTO profiles (userid, bio, homepage) VALUES(LAST_INSERT_ID(),'Hello world!', 'http://www.stackoverflow.com'); */ mysql_query($sql); };
参考
PHP
MYSQL
看看mysql_insert_id()
这里的文档: http : //in.php.net/manual/en/function.mysql-insert-id.php
如果你想创build许多这样的logging(如果要注册10个用户,而不是一个),会发生什么? 我find以下解决scheme(只有5个查询):
第一步:创build临时表来存储新的数据。
CREATE TEMPORARY TABLE tmp (id bigint(20) NOT NULL, ...)...;
接下来,填充这个值。
INSERT INTO tmp (username, password, bio, homepage) VALUES $ALL_VAL
在这里,不是$ALL_VAL
,而是放置值列表:('test1','test1','bio1','home1'),…,('testn','testn','bion','homen' )
第二步:将数据发送到“用户”表。
INSERT IGNORE INTO users (username, password) SELECT username, password FROM tmp;
在这里,“IGNORE”可以使用,如果你允许一些用户已经在里面。 可选的,你可以使用类似于第三步的UPDATE,在这一步之前,找出哪些用户已经在里面(并且把它们标记在tmp表中)。 在这里,我们认为,用户名在用户表中声明为PRIMARY
。
第三步:应用更新从用户读取所有用户id到tmp表。 这是必不可less的步骤。
UPDATE tmp JOIN users ON tmp.username=users.username SET tmp.id=users.id
第四步:创build另一个表,为用户使用读取ID
INSERT INTO profiles (userid, bio, homepage) SELECT id, bio, homepage FROM tmp
只是说一下你的话
嗨,我试图寻找一种方法来在同一个查询中的多个表中插入信息
你在同一个碗里把你所有的混合饮料的午餐都吃了吗?
我想 – 不。
同样在这里。
有些事情我们分开做。
2个插入查询是2个插入查询。 没关系。 没有错。 没有必要在一个捣烂它。
相同的select。 查询必须明智,并做好工作。 这是唯一的原因。 查询数量不是。
至于交易 – 你可以使用它们,但对于一般的网站来说并不是什么大事。 如果每年发生一次(如果曾经发生)一个用户注册被破坏,那么您将无疑可以修复。
有数十万个运行mysql的站点没有事务支持驱动程序。 你听说过把这些网站分开的可怕的灾难吗? 我也不。
和mysql_insert_id()有关的交易。 你可以包括在交易中。 这只是不同的事情。 有人提出这个问题的地方。
这是我为一个uni项目做的,工作正常,可能不安全
$dbhost = 'localhost'; $dbuser = 'root'; $dbpass = ''; $conn = mysql_connect($dbhost, $dbuser, $dbpass); $title = $_POST['title']; $name = $_POST['name']; $surname = $_POST['surname']; $email = $_POST['email']; $pass = $_POST['password']; $cpass = $_POST['cpassword']; $check = 1; if (){ } else{ $check = 1; } if ($check == 1){ require_once('website_data_collecting/db.php'); $sel_user = "SELECT * FROM users WHERE user_email='$email'"; $run_user = mysqli_query($con, $sel_user); $check_user = mysqli_num_rows($run_user); if ($check_user > 0){ echo '<div style="margin: 0 0 10px 20px;">Email already exists!</br> <a href="recover.php">Recover Password</a></div>'; } else{ $users_tb = "INSERT INTO users ". "(user_name, user_email, user_password) ". "VALUES('$name','$email','$pass')"; $users_info_tb = "INSERT INTO users_info". "(user_title, user_surname)". "VALUES('$title', '$surname')"; mysql_select_db('dropbox'); $run_users_tb = mysql_query( $users_tb, $conn ); $run_users_info_tb = mysql_query( $users_info_tb, $conn ); if(!$run_users_tb || !$run_users_info_tb){ die('Could not enter data: ' . mysql_error()); } else{ echo "Entered data successfully\n"; } mysql_close($conn); }
}
这是一种可以同时插入多个表的方法
<?php require 'Connection.php'; $sql = "insert into `disease`(`diseasename`,`statusofgiving`) values('pentamina','no');"; $sql2 = "insert into `location`(`state`,`city`) values('pentamina','no');"; $res = mysqli_query($con,$sql); $res = mysqli_query($con,$sql2); ?>
对于PDO你可以这样做
$stmt1 = "INSERT INTO users (username, password) VALUES('test', 'test')"; $stmt2 = "INSERT INTO profiles (userid, bio, homepage) VALUES('LAST_INSERT_ID(),'Hello world!', 'http://www.stackoverflow.com')"; $sth1 = $dbh->prepare($stmt1); $sth2 = $dbh->prepare($stmt2); BEGIN; $sth1->execute (array ('test','test')); $sth2->execute (array ('Hello world!','http://www.stackoverflow.com')); COMMIT;