[mysql] 여러 테이블에 MySQL 삽입? (데이터베이스 정규화?)

insert동일한 쿼리에서 여러 테이블의 정보를 검색하는 방법을 시도했지만 불가능하다는 것을 알았습니다. 그래서 나는 insert단순히 여러 쿼리를 사용하여 그것을 원합니다 .

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로부터 users“수동”으로 userid에 대한 profile테이블을?



답변

아니요, 하나의 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 명령에 넣을 수 없습니까?

자세히 설명하겠습니다. 여기에는 3 가지 방법이 있습니다.

  1. 위 코드에서 볼 수 있습니다. 이것은 MySQL에서 모든 작업을 수행하며
    LAST_INSERT_ID()in 두 번째 명령문은 자동으로 첫 번째 명령문에 삽입 된 자동 증분 열의 값이됩니다.

    불행히도, 두 번째 명령문 자체가 자동 증가 열이있는 테이블에 행을 삽입 LAST_INSERT_ID()하면 테이블 1이 아니라 테이블 2의 행으로 업데이트됩니다. 이후에 테이블 1의 행이 계속 필요하면이를 저장해야합니다. 변수에서. 이것은 우리를 길 2와 3으로 인도합니다.

  2. LAST_INSERT_ID()MySQL 변수에 재고를 보관합니다 :

    INSERT ...
    SELECT LAST_INSERT_ID() INTO @mysql_variable_here;
    INSERT INTO table2 (@mysql_variable_here, ...);
    INSERT INTO table3 (@mysql_variable_here, ...);
  3. 재고 것 LAST_INSERT_ID()PHP는 변수 (또는 당신의 선택의 데이터베이스에 연결할 수있는 모든 언어)에서 :

    • INSERT ...
    • 언어를 사용하여 LAST_INSERT_ID()MySQL에서 리터럴 문을 실행하거나 예를 들어 PHP를 사용하여을 mysql_insert_id()검색하십시오.
    • INSERT [use your php variable here]

경고

이 문제를 해결하는 방법에 관계없이 쿼리간에 실행이 중단 될 경우 어떻게해야하는지 결정해야 합니다 (예 : 데이터베이스 서버 충돌). “일부는 끝났고 그렇지 않은 사람”과 함께 살 수 있다면 계속 읽으십시오.

그러나 “모든 쿼리가 완료되거나 완료되지 않습니다. 일부 테이블에는 행을 원하지 않지만 다른 테이블에는 일치하는 행을 원하지 않으면 항상 데이터베이스 테이블이 일관성을 유지하기를 원할 경우”모든 명령문을 트랜잭션에 래핑해야합니다. 내가 사용하는 이유 BEGINCOMMIT여기.

더 많은 정보가 필요한 경우 다시 의견 🙂


답변

저장 프로 시저를 사용하는 경우 매우 간단합니다.

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;


답변

이러한 레코드를 여러 개 만들려면 어떻게해야합니까 (하나가 아닌 10 명의 사용자를 등록하기 위해)? 다음과 같은 해결책을 찾았습니다 (단지 5 개의 쿼리).

1 단계 : 새 데이터를 저장할 임시 테이블을 만듭니다.

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’)

단계 II : ‘user’테이블로 데이터를 보냅니다.

INSERT IGNORE INTO users (username, password)
SELECT username, password FROM tmp;

여기서 일부 사용자가 이미 내부에있는 것을 허용하는 경우 “IGNORE”를 사용할 수 있습니다. 선택적으로이 단계 전에 단계 III과 유사한 UPDATE를 사용하여 이미 내부에있는 사용자를 찾아서 tmp 테이블에 표시 할 수 있습니다. 여기서는 사용자 이름이 PRIMARYusers 테이블에서 선언 된 것으로 가정 합니다.

3 단계 : 업데이트를 적용하여 모든 사용자 ID를 사용자에서 tmp 테이블로 읽습니다. 이것은 필수 단계입니다.

UPDATE tmp JOIN users ON tmp.username=users.username SET tmp.id=users.id

IV 단계 : 사용자의 읽기 ID를 사용하여 다른 테이블 작성

INSERT INTO profiles (userid, bio, homepage)
SELECT id, bio, homepage FROM tmp


답변

이 시도

$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


답변

이것이 내가 유니 프로젝트를 위해했던 방식이며, 잘 작동하며 안전하지 않을 것입니다.

$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);
}

}


답변

당신의 말에 대한 언급

안녕하세요, 같은 쿼리에서 여러 테이블에 정보를 삽입하는 방법을 검색했습니다.

같은 그릇에 음료수와 혼합 된 모든 점심 요리를 먹습니까?
나는 생각한다.

여기도 마찬가지입니다.
우리가 별도로하는 일이 있습니다.
2 개의 삽입 쿼리는 2 개의 삽입 쿼리입니다. 괜찮아 아무 문제가 없습니다. 한 번에 으 깨지 않아도됩니다.
선택과 동일합니다. 쿼리는 합리적이어야하며 제대로 작동해야합니다. 그게 유일한 이유입니다. 쿼리 수가 없습니다.

거래에 관해서는-당신은 그들을 사용할 수 있지만, 평균 웹 사이트에 그렇게 큰 것은 아닙니다. 일년에 한 번 (있는 경우) 한 명의 사용자 등록이 중단 된 경우 문제를 해결할 수 있습니다.
트랜잭션 지원 드라이버없이 mysql을 실행하는 수십만 개의 사이트가 있습니다. 이 사이트들을 파괴하는 끔찍한 재난에 대해 들어 보셨습니까? 나도

그리고 mysql_insert_id ()는 트랜잭션과 관련이 없습니다. 당신은 거래에 모든 권리를 포함시킬 수 있습니다. 그것은 단지 다른 문제입니다. 누군가이 질문을 아무 데나 제기하지 않았습니다.