데이터 직렬화
GitLab v19.4요약
요약: 직렬화한 데이터는 데이터베이스에 저장하지 말고, 별도의 칼럼이나 테이블을 사용합니다. Rails는 직렬화한 데이터를 JSON, YAML 등의 형식으로 저장할 수 있게 해 줍니다. 직렬화한 데이터를 데이터베이스에 저장하고 싶을 수 있지만, 이 방식에는 여러 문제가 있습니다.
요약: 직렬화한 데이터는 데이터베이스에 저장하지 말고, 별도의 칼럼이나 테이블을 사용합니다. 쉼표로 구분한 값을 문자열로 저장하는 방식도 여기에 해당합니다.
Rails는 직렬화한 데이터를 JSON, YAML 등의 형식으로 저장할 수 있게 해 줍니다. 이런 필드는 다음과 같이 정의합니다.
class Issue < ActiveRecord::Model
serialize :custom_fields
end
직렬화한 데이터를 데이터베이스에 저장하고 싶을 수 있지만, 이 방식에는 여러 문제가 있습니다. 이 문서에서는 그 문제를 정리하고 대안을 제시합니다.
직렬화한 데이터의 기능적 한계#
관계형 데이터베이스를 사용하면 개별 필드를 조회하고, 스키마를 변경하고, 데이터를 인덱싱하는 등의 작업을 할 수 있습니다. 직렬화한 데이터를 사용하면 이런 작업이 매우 어려워지거나 아예 불가능해집니다. PostgreSQL 이 JSON 필드를 조회하는 기능을 제공하기는 하지만, 이는 대부분 매우 특수한 용도를 위한 것이지 일반적인 용도를 위한 것이 아닙니다. YAML을 사용하면 데이터를 조회할 방법이 아예 없습니다.
공간 낭비#
JSON 이나 YAML 같은 직렬화 데이터를 저장하면 공간을 많이 낭비하게 됩니다. 이런 형식에는 저장하려는 데이터 외에 큰따옴표나 줄바꿈 같은 추가 문자가 포함되는 경우가 많기 때문입니다.
관리의 어려움#
직렬화한 데이터에 새 필드를 추가하거나 기존 필드를 변경해야 할 때가 옵니다. 직렬화한 데이터에서는 저장된 값을 전부 다시 쓰는 방법밖에 없어 이 작업이 어렵고 시간도 매우 오래 걸립니다. 다음 절차를 거쳐야 합니다.
- 데이터를 가져옵니다.
- Ruby 구조체로 파싱합니다.
- 값을 변경합니다.
- 다시 String으로 직렬화합니다.
- 데이터베이스에 저장합니다.
반면 일반 칼럼을 사용한다면 칼럼 추가는 다음과 같습니다.
ALTER TABLE table_name ADD COLUMN column_name type;
이 쿼리는 시간이 거의 들지 않고, 큰 JSON 이나 YAML 구조를 다시 쓸 필요 없이 모든 행에 즉시 적용됩니다.
끝으로, JSON 이나 YAML 구조로는 더 이상 충분하지 않아 다른 방식으로 이전해야 할 때가 옵니다. 행이 몇 개뿐이라면 문제가 되지 않을 수 있지만, 수백만 행을 저장하고 있다면 이런 마이그레이션은 완료까지 몇 시간에서 며칠까지 걸릴 수 있습니다.
관계형 데이터베이스와 문서 저장소의 차이#
데이터를 JSON 이나 YAML로 저장한다는 것은 데이터베이스를 MongoDB 같은 문서 저장소처럼 쓰는 것이나 마찬가지입니다. 다만 일반적인 RDBMS가 제공하는 강력한 기능도, 일반적인 문서 저장소가 제공하는 기능(예를 들어 필드가 가변인 문서의 필드를 인덱싱하는 기능)도 전혀 활용하지 못합니다. 다시 말해 낭비입니다.
일관된 필드#
직렬화 데이터를 옹호하는 근거로 값과 필드가 크게 달라지는 데이터를 저장해야 한다는 점이 거론되기도 합니다. 실제로 그런 경우라면 직렬화 데이터를 사용하는 편이 타당할 수 있습니다. 하지만 99% 의 경우 저장되는 필드와 타입은 모든 행에서 동일합니다. 약간의 차이가 있더라도 별도의 칼럼을 사용하고 필요 없는 칼럼은 설정하지 않으면 됩니다.
해결 방법#
해결 방법은 별도의 칼럼이나 별도의 테이블을 사용하는 것입니다. 그러면 데이터베이스가 제공하는 모든 기능을 활용할 수 있습니다. 데이터를 관리하고 마이그레이션하기가 쉬워지고 공간도 절약됩니다. 데이터를 효율적으로 인덱싱하는 것도 가능합니다.