PostgreSQL에서 테이블 칼럼 순서 지정
PostgreSQL 테이블에서 칼럼 순서를 최적화하여 스토리지 공간을 절약하는 방법과 실제 예시를 설명합니다.
GitLab에서는 새로운 테이블의 칼럼이 최소한의 공간을 사용하도록 순서를 정하도록 요구합니다. 이를 위한 쉬운 방법은 타입 크기를 기준으로 내림차순으로 정렬하되, 가변 크기( text , varchar , 배열, json , jsonb 등)를 마지막에 배치하는 것입니다. C 구조체와 마찬가지로 테이블의 공간은 칼럼 순서에 따라 달라집니다. 이는 칼럼의 크기가 다음 칼럼의 타입에 따라 정렬되기 때문입니다. 다음 예시를 살펴보겠습니다: id (integer, 4바이트) name (text, 가변) user_id (integer, 4바이트) 첫 번째 칼럼은 4바이트 정수입니다. 다음은 가변 길이의 text입니다. text 데이터 타입은 1워드 정렬이 필요하며, 64비트 플랫폼에서 1워드는 8바이트입니다. 정렬 요구 사항을 충족하기 위해 첫 번째 칼럼 바로 뒤에 4개의 0이 추가되므로, id 는 4바이트를 차지하고, 이후 4바이트의 정렬 패딩이 추가된 다음에야 name 이 저장됩니다. 따라서 이 경우 4바이트 정수를 저장하는 데 8바이트가 사용됩니다. 행과 행 사이의 공간도 정렬 패딩의 영향을 받습니다. user_id 칼럼은 4바이트만 사용하지만, 64비트 플랫폼에서는 다음 행이 "깔끔한" 워드로 시작할 수 있도록 4개의 0이 정렬 패딩으로 추가됩니다. 결과적으로 각 칼럼의 실제 크기는 (가변 길이 데이터와 24바이트 튜플 헤더 제외) 8바이트, 가변, 8바이트가 됩니다. 이는 두 개의 4바이트 정수에 대해 각 행이 최소 16바이트를 필요로 한다는 의미입니다. 테이블에 행이 몇 개 없다면 문제가 되지 않지만, 수백만 건의 행을 저장하기 시작하면 순서를 바꾸어 공간을 절약할 수 있습니다. 위의 예시에서 이상적인 칼럼 순서는 다음과 같습니다: id (integer, 4바이트) user_id (integer, 4바이트) name (text, 가변) 또는 name (text, 가변) id (integer, 4바이트) user_id (integer, 4바이트) 이 예시에서 id 와 user_id 칼럼이 함께 묶이므로, 두 칼럼을 저장하는 데 8바이트만 필요합니다. 즉, 각 행이 8바이트 적은 공간을 차지하게 됩니다. Ruby on Rails 5.1부터 ID의 기본 데이터 타입은 8바이트를 사용하는 bigint 입니다. 위 예시에서는 더 현실적인 재정렬 시나리오를 보여주기 위해 integer 를 사용하였습니다. 타입 크기 # PostgreSQL 문서 에 많은 정보가 있지만, 자주 사용하는 타입의 크기를 여기서 정리하여 쉽게 참조할 수 있도록 합니다. 여기서 "워드"는 워드 크기를 의미하며, 32비트 플랫폼에서는 4바이트, 64비트 플랫폼에서는 8바이트입니다. 타입 크기 필요한 정렬 smallint 2바이트 1워드 integer 4바이트 1워드 bigint 8바이트 8바이트 real 4바이트 1워드 double precision 8바이트 8바이트 boolean 1바이트 불필요 text / string 가변, 1바이트 + 데이터 1워드 bytea 가변, 1