전통적인 SQL은 하나의 셀에 여러 값을 저장하는 것을 지원하지 않습니다. 관계형 모델은 정규화를 요구합니다. 그러나 현대의 과제에서는 "태그 목록", "평가 척도"와 같은 필드가 자주 등장하고, 이러한 경우에는 개별 행 수준에서 여러 값을 조작하는 것이 편리합니다. 일부 DBMS(예: PostgreSQL, Oracle)는 ARRAY 데이터 유형이나 유사한 메커니즘을 제공합니다.
배열 사용은 정규화 원칙을 위반하고, 많은 작업(필터링, 업데이트, 인덱싱)을 복잡하게 만들며, 코드의 이식성도 떨어뜨립니다. 하지만 캐싱이나 소규모 값 목록에 대한 빠른 검색을 위해 편리하거나 불가피할 수 있습니다.
CREATE TABLE products ( id SERIAL PRIMARY KEY, tags TEXT[] ); -- 삽입: INSERT INTO products(tags) VALUES (ARRAY['eco','sale','hot']); -- 배열로 검색: SELECT * FROM products WHERE 'eco' = ANY (tags);
주요 특징:
배열의 개별 요소에 인덱스를 생성할 수 있습니까?
PostgreSQL에서는 예, GIN/GIST 인덱스를 통해 가능합니다:
CREATE INDEX idx_tags ON products USING GIN (tags);
구분자가 있는 문자열 열에서 값의 포함 여부를 더 빠르게 확인하는 방법은 무엇입니까?
SQL은 기본적으로 이 작업을 수행하지 않으며, 패턴 검색을 사용합니다:
SELECT * FROM users WHERE ',admin,' like concat('%,',role,',%');
하지만 이 접근 방식은 신뢰할 수 없고 느립니다.
배열에 얼마나 많은 값을 저장할 수 있으며, 무엇이 제한합니까?
제한은 DBMS에 따라 다릅니다. 예를 들어 PostgreSQL의 경우 문자열 크기에 대한 제한(1–2MB)만 있습니다.
전자상거래 프로젝트에서 제품 태그를 하나의 열에 쉼표로 저장하기로 결정했습니다. 태그로 제품을 빠르게 검색하는 것이 매우 어려워졌고, 필터링 오류와 태그 중복이 파싱 오류로 인해 발생했습니다.
장점:
단점:
PostgreSQL에서 작은 불변 집합(사용자 역할)에 ARRAY와 GIN 인덱스를 사용했습니다. 큰 경우에는 역할을 위한 별도 테이블을 사용했습니다.
장점:
단점: