본문 바로가기
MySQL별책부록

InnoDB 컬럼 저장 순서

by 모모레 2019. 2. 15.

갑자기 지인으로 부터 질문을 받고 궁금하여 테스트를 진행한다. 

"테이블을 생성할 때 멀티 컬럼으로 PK를 지정하는 경우에, PK 순과 컬럼 순이 다르게 정의 된다면 데이터는 어떻게 저장될까?" 

이것이 지인의 질문이었다. 생각으로는 정의 순서와 상관없이 PK 순으로 저장될거라고 생각했다. 그것이 논리적으로 맞다고 생각했기 때문에....

헌데 정말 그러한 것인지 궁금하여 직접 테스트를 해보기로 했다. 


테이블은 다음과 같이 생성하였다. 

mysql> show create table tb;

+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

| Table | Create Table                                                                                                                                                                                                                                            |

+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

| tb    | CREATE TABLE `tb` (

  `name` varchar(10) NOT NULL,

  `extr` varchar(10) NOT NULL,

  `id` int(11) NOT NULL,

  `address` varchar(100) DEFAULT NULL,

  PRIMARY KEY (`extr`,`name`,`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |

+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

1 row in set (0.01 sec)


컬럼 정의 순서와 PK 순서는 완벽하게 다르게 선언하였고, 

바이너리 파일 확인을 쉽게 하기 위해 varchar와 int 형으로 데이터 타입을 선언하였다. 

어쨌든 순서를 보는것에 초점을 맞춰야 하니...


데이터는 다음과 같이 입력하였다. 

mysql> insert into tb values ( 'aaa','bbb',1, 'address');

Query OK, 1 row affected (0.01 sec)


mysql> insert into tb values ( 'aaaa','bbbbb',2, 'address');

Query OK, 1 row affected (0.00 sec)


mysql> insert into tb values ( 'aaaaaa','bbbbbb',3,'addfdfdf');

Query OK, 1 row affected (0.00 sec)


그리고 xxd를 통해 다음과 같이 tb.idb 파일을 뜨고, 

xxd tb.ibd > tb.file


데이터 저장 부분을 찾아서 보았다. 

00010060: 0200 1e69 6e66 696d 756d 0004 000b 0000  ...infimum......

00010070: 7375 7072 656d 756d 0703 0300 0000 1000  supremum........

00010080: 2762 6262 6161 6180 0000 0100 0000 0006  'bbbaaa.........

00010090: 0f81 0000 0106 0110 6164 6472 6573 7307  ........address.

000100a0: 0405 0000 0018 002a 6262 6262 6261 6161  .......*bbbbbaaa

000100b0: 6180 0000 0200 0000 0006 1082 0000 0105  a...............

000100c0: 0110 6164 6472 6573 7308 0606 0000 0020  ..address......

000100d0: ff9e 6262 6262 6262 6161 6161 6161 8000  ..bbbbbbaaaaaa..

000100e0: 0003 0000 0000 0615 8100 0001 0801 1061  ...............a

000100f0: 6464 6664 6664 6600 0000 0000 0000 0000  ddfdfdf.........

00010100: 0000 0000 0000 0000 0000 0000 0000 0000  ................


역시.....

지정 순서에 따라 저장됨을 확인할 수 있다. int 형은 ascii 변환으로 해서 문자로 보이지는 않았지만, hexa 코드로 보면 

2762 6262 6161 6180 0000 0100 0000 0006


80 0000 01 이 숫자 부분이다. int 는 4바이트로 표현되기 때문이다. 


다른 일반 컬럼은 그 뒤에 생성되는 것을 확인할 수 있다. 

다른 것들은 선언된 순서대로 저장되지만, PK는 컬럼 순이 아니라 key 지정 순임을 확인할 수 있다.