게시판 헤더 테이블과, 실제 콘텐츠를 담고 있는 테이블 2개가 있다고 생각해 봅시다. 하나는, 글 id랑, 제목, 작성자, 조회수, 작성 날짜를 담고 있습니다. 다른 하나는 글 id와 실제 post 내용을 담고 있습니다. 그러면 게시글을 추가하는 이벤트가 발생했을 때, 헤더 테이블에 추가한 다음에, 콘텐츠를 담고 있는 테이블에 추가를 해야 할 겁니다. 이 때 콘텐츠에 들어가는 글 id랑, 헤더에 들어가는 글 id가 같기 때문에, contents를 가지고 있는 테이블에 추가하기 전에, 추가된 글 번호를 가져와야 합니다. 어떻게 해야 할까요?
board_header DDL문입니다. id가 NOT NULL이면서, AUTO_INCREMENT입니다. 그리고 primary key입니다. 그러면, 인덱스가 걸렸다는 이야기입니다. 그러면 그냥 select max(id) from board_header; 해도 무난할 거 같습니다. 정말 그런지는 밑에서 알아보도록 합시다.
sys 데이터베이스에 보시면, 이상한 테이블과 view가 가득 있는 것을 볼 수 있습니다. 스크롤을 쭉 내리시다 보면, 아래와 같은 이름을 가지는 테이블이 있음을 볼 수 있어요.
환경에 따라 다르긴 할 텐데요. 제 MYSQL 버전에서는 schema_auto_increment_columns라고 뜨네요. 이 테이블은, 실제로 auto_increment가 붙어있는 속성들을 모두 가져와서 저장하는 테이블이에요. 그러면, select 문을 써서, 이 테이블이 어떠한 정보를 가지고 있는지 출력해 보도록 하겠습니다.
쿼리문은 위와 같을 겁니다.
그러면 요렇게 뜬다는 것을 알 수 있는데요. table_schema는 데이터 베이스를, table_name은 테이블을, column_name은 열 이름을 나타냅니다. 제가 필요로 하는 것은, my_database의 board_header 테이블에 있는 auto_increment가 걸려 있는 id 필드 값입니다.
따라서, 아래와 같이 가져와 주시면 됩니다.
그러면 결과값이 하나 나올 텐데요. 이 중, auto_increment 열의 값이 15라는 사실에 주목할 필요가 있어요. 이것이 뭘 의미할까요? bh 테이블로 가 봅시다.
bh에 있는 것들을 모두 꺼내는 명령어입니다.
이들 중, id 값이 가장 큰 것은 오늘따라코딩이하고싶네요 라는 제목을 가진 id가 15번인 글임을 알 수 있습니다. 저는 어떤 과정을 거쳐서 쿼리를 작성했나요? 먼저 auto_increment에 대한 정보를 가지고 있는 테이블을 sys 데이터 베이스에서 찾았습니다. 그 중에서, 필요한 열만 필터링을 한 것 뿐입니다.
그런데, id가 primary key이면서, autoincrement로 되어 있다면 어떨까요? 테이블 정보를 봅시다.
그러면 id가 type이 BTREE인 인덱스를 쓴다는 건데요. 아직 이것에 대해 아실 필요는 없습니다. 다만, 어떠한 값을 빠르게 찾게 해주는 자료구조라고만 이해하셔도 무난합니다. 이러한 자료 구조 중에는 rb 트리라던지, avl 등이 있는데, 사실 이 둘은 자식 최대 갯수가 2이고요. 이 친구는 그것보다 더 클 수도 있어요. 한 노드에 걸리는 자식이 많으면, 뭐가 좋을까요? 탐색 깊이가 작아집니다. 예를 들어 자식이 최대 2개라면, 100만개짜리 데이터가 있는 경우에, 최소 깊이가 20이지만, 32개라면 겨우 4밖에 되지 않습니다.
균형적인 Tree라면, 당연하게도 어떠한 값을 찾는 연산이라던지, 제일 큰 것과 작은 것을 찾는 operation에는 특화되어 있을 겁니다. %..%라던지 %.. 이런 것도 인덱스를 타는지는 조금만 생각해 보시면 쉽게 아실 듯 싶어요. c++의 set이나 map이 어떠한 연산에 강한지 생각해 보시면 쉽게 이해가 가실 거에요. 큰 그림은 이 정도만 그려주셔도 됩니다.
이 쿼리는, board_header에 있는 레코드의 id 값들 중 가장 큰 값을 추출합니다.
간략하게 도식화된, explain을 보시면, Full Table scan이 아님을 알 수 있는데요. 최솟값이나 최댓값은 그냥 한 포인터만 타고 내려가면 되기 때문에, 전수 탐색을 할 필요가 없어요. 그러니, Full scan을 하지 않아도 결과를 얻어올 수 있습니다.
15라는 값을 얻어올 수 있었습니다. 제 web 게시판에서는, 위 쿼리를 서브 쿼리로 사용하였습니다.
'코딩 > Sql' 카테고리의 다른 글
mysql length 함수 : 문자열이 차지하는 byte 수를 리턴한다. (6) | 2019.10.16 |
---|---|
mysql left, right, mid 함수 : 부분 문자열을 추출한다. (2) | 2019.10.08 |
mysql unix timestamp 함수 : 기준 시간으로부터 몇 초나 흘렀을까? (4) | 2019.09.20 |
mysql datetime형 : 어떤 타입일까? (13) | 2019.09.19 |
mysql instr 함수 : string에서 pattern이 나타나는 최초 위치를 찾아보자. (6) | 2019.09.17 |
최근댓글