출처 : http://dongz.tistory.com/entry/MYSQL-%EC%9E%90%EB%8F%99%EC%A6%9D%EA%B0%80%EA%B0%92-%EA%B0%80%EC%A0%B8%EC%98%A4%EA%B8%B0

출처 : http://whiteship.tistory.com/tag/selectKey
         http://theeye.pe.kr/entry/MySQL-LASTINSERTID-%EA%B0%80%EC%9E%A5-%EC%B5%9C%EA%B7%BC%EC%9D%98Auto-Increment%EA%B0%92%EC%9D%84-%EA%B0%80%EC%A0%B8%EC%98%A4%EA%B8%B0

데이터를 추가하는 경우에 다음과 같은 경우가 많이 있다.

"하나 의 글을 작성하는데 다수의 첨부파일을 작성할 수 있는 경우"
사용자 삽입 이미지

위의 ERD로 스크립트를 생성해 보면 다음과 같을 것이다.

CREATE TABLE POST (
  POST_IDX
int(11) AUTO_INCREMENT,
  SUBJECT varchar
(2000),
  NAME varchar
(200),
  CONTENT text
,
  WRITTEN datetime
,
  PRIMARY KEY
(POST_IDX)
)

CREATE TABLE ATTACHMENT
(
  ATTACH_IDX
int(11) AUTO_INCREMENT,
  POST_IDX
int(11),
  FILE_NAME varchar
(200),
  FILE_PATH varchar
(2000),
  UPLOADED datetime
,
  PRIMARY KEY
(ATTACH_IDX ),
  FOREIGN KEY POST_IDX REFERENCES POST
(POST_IDX)
)


글 이 작성된 후 저장될때 POST테이블에 하나의 값을 추가한후, 다수의 ATTACHMENT를 추가하여야 할것이다.

하지 만 어떻게 정확한 POST_IDX를 알아올 수 있는가?

POST를 저장할때 POST_IDX는 자동증가 인덱스를 가지고 있기 때문에 어떤 값을 부여받게 될지 알 수 없다.

다음과 같은 방법으로 처리할 수 있다.

INSERT INTO POST (
  SUBJECT
, NAME, CONTENT, WRITTEN
) VALUES (
 
"제목", "이름", "글내용", NOW()
);

INSERT INTO ATTACHMENT
(
  POST_IDX
, FILE_NAME, FILE_PATH, UPLOADED
) VALUES (
  LAST_INSERT_ID
(), "file.jpg", "/tmp/file.jpg", NOW()
);


위 와 같이 LAST_INSERT_ID()를 사용하면 가장 최근에 INSERT시에 입력된 INCREMENT ID값을 가져올 수 있다.

중간에 다른 사용자에 의해 글이 추가되더라도 내가 작성할때 부여된 INCREMENT값이 나온다.

단, 당연하겠지만 같은 커넥션 안에서만 정상적인 결과가 나온다.

------------------------------------------------------------

또 다른 참고 글 : http://reid.tistory.com/32

MySQL에서 데이터를 삽입 후 AUTO_INCREMENT 컬럼의 증가값을 가져오기 위해 last_insert_id()를 호출하는 경우, 걱정되는 점 중 하나는 멀티 쓰레드 환경에서 컨넥션들이 서로 race condition을 유발하지 않을까 하는 점이다. 즉, 두 컨넥션이 동시에 insert를 하고 last_insert_id()를 호출하였을 때, 우연히 두 번의 삽입 작업이 먼저 이루어지고 나서 last_insert_id()가 동작하여 같은 정수값을 가져오지 않을까 하는 우려이다. 하지만 이 점에 대해 MySQL은 분명히 명시하고 있다.

The ID that was generated is maintained in the server on a per-connection basis. This means that the value returned by the function to a given client is the first AUTO_INCREMENT value generated for most recent statement affecting an AUTO_INCREMENT column by that client. This value cannot be affected by other clients, even if they generate AUTO_INCREMENT values of their own. This behavior ensures that each client can retrieve its own ID without concern for the activity of other clients, and without the need for locks or transactions.

즉, ID를 생성해서 유지하는 것은 컨넥션 별로 따로 관리되며, 각각의 클라이언트가 정확한 수치를 가져오기 위해 테이블에 락을 걸거나 트랜잭션을 사용 할 필요가 없다는 것이다. 고로, 그냥 연달아 쿼리 날려주면 된다.

MySQL 매뉴얼, LAST_INSERT_ID(), LAST_INSERT_ID(expr) 항목을 참조

Posted by 노을지기