mysql에는 auto increment가 있었습니다. postgresql에는 없을까요? 문서의 8.1.4를 보시면, serial 시리즈가 비슷한 역할을 한다고 되어 있습니다.

 


 저는 도서관 api를 구현하는 토이 프로젝트를 하고 있어요. 이 중에, book 관련한 api는 얼추 만들었으니, 책을 빌리고 반납하는 api를 만들겠습니다. 그러려면, user 테이블하고, borrow 테이블이 필요한데요. 아직, login 기능은 만들 생각이 없으니, 그냥 borrow 테이블만 만들도록 하겠습니다.

 

 책을 빌리는데, 누가 빌리나요? 유저가 빌릴 겁니다. 즉, 책 아이디와, 유저 아이디가 필요합니다. 그리고 언제 빌렸는지 알기 위해서, 빌린 시각, borrow_time도 저장하겠습니다. 그런데, 빌린다. 요청에 가깝습니다. 그러니, 요청 id도 넣을 건데요. 이것을 serial로 처리하겠습니다.

 

 보시면 borrow_id를 bigserial로 처리하였는데요. bigserial은 8byte serial을 의미합니다.

 

 

 그러면, borrow_id는 pk로 들어가면 좋겠네요. 다음에, book_id는 unique로 넣었는데요. 이는 책을 두 명의 사람이 동시에 빌릴 수 없기 때문입니다. 테이블에 생성을 하고 더미 데이터 몇 개를 넣은 다음에, 장난을 쳐 보겠습니다.

 


 borrow 전체를 보겠습니다.

 

 

 그러면 이런 식으로 borrow_id와 빌린 유저의 id, 빌린 시각, 그리고 빌린 책 id가 뜹니다. 여기서, 8번 요청에 대해서 반납했다고 해 보겠습니다. 즉, 우리는 15번 책을 반납한 겁니다.

 

 

 그러면, borrow 테이블에서 삭제할 건데, borrow_id가 8인 레코드들을 삭제하면 됩니다. 8인 레코드는 하나이니, 하나만 지워질 겁니다. 그 다음에, user_id가 1이고, 15번 책을 빌리는 요청이 하나 추가됩니다.

 

 

 insert 문을 수행하고 다시 borrow 테이블을 보겠습니다.

 

 

 그러면 8이 아닌, 9가 들어오게 되는데요. 이는 8이 삭제 되었더라도, sequence 메타 데이터의 last_value는 8이다. 라는 정보가 삭제되지 않기 때문입니다. 그렇기에, insert 명령이 들어오면, nextValue 값인 9가 출력되게 됩니다.

 


 메타 데이터 이야기가 나온 김에, sequence에 대한 정보를 확인해 보면서 진행해 봅시다.

 

 pg_catalog의 pg_sequences를 보시면, 시퀀스들에 대한 메타 데이터가 있습니다.

 

 

 이 중에 last_value가 보이는데요. 15라는 값과 9라는 값이 어딘가 많이 익숙하지 않나요? 9는 borrow_id 중에 제일 큰 값이였습니다. 이것이 sequence로 관리되고 있었던 것입니다. 그러니, 스키마 이름과 시퀀스 이름, last_value을 pg_sequences로부터 뽑아오면 됩니다. 그리고 increment_by는 1인데요. 이는, nextval이 호출될 때 마다 1씩 증가됨을 의미합니다.

 

 다시, 해당 부분만 뽑아와 봅시다.

 

 

 그러면, borrow_borrow_id_seq의 last_value가 9라는 정보를 얻어올 수 있어요. 그러면, insert가 실패한 경우에는 어떨까요?

 

 위의 경우에는 book_id가 15가 있는 상태에서 id가 15인 책을 빌리겠다고 해서 실패가 된 상황입니다.

 

 

 메타 데이터를 확인해 보니, last_value가 10으로 올라갔음을 볼 수 있어요. 이는 문서에 나온 even if a row ~ never successfully inserted와 관련이 있어요. even if A가 A일 지라도로 해석이 될 것이니, even if 앞에 있는 구문이 중요할 겁니다. 앞에를 보니까, still "used up"이라는 것이 떡하니 있는데요. 여전히 (그럼에도) 소진되다. 사용되다. 이런 뉘앙스로 보시면 됩니다.

 

 

 book_id가 15인 책을 반납 (borrow 테이블에서 삭제) 하고, 다시 book id가 15인 책을 빌렸다는 정보를 추가하니, borrow_id가 10의 nextval 값인 11로 바뀌었음을 확인할 수 있어요. 문서에서 gap이라고 언급된 부분이 이런 부분입니다. 시퀀스 값이 3 다음에 4, 5 이런식으로 올 수도 있지만, 3, 5, 7 이렇게도 올 수 있다는 것입니다. 위 그림에서도 7 다음에 8이 오는 게 아니라 11이 왔다는 것을 참고하시면 됩니다. 이 글에서는 auto increment와 비슷한 역할을 하는 postgresql serial에 대해 알아보았습니다. nextval에 대한 자세한 것은 문서를 참고하시면 되겠습니다.