오늘은 PostgreSQL에서 배열 다루는 재미있는 여정의 마지막이야. 오늘 주제는 — 배열 쓸 때 흔히 만나는 실수들, 그리고 그걸 어떻게 피할 수 있는지! 혹시라도 "이 배열 또 이상하게 굴잖아" 이런 생각 해본 적 있다면, 이 강의가 딱이야. 같이 파헤쳐보자.
배열 생성 시 실수: 배열 내부 데이터 타입 문제
PostgreSQL에서 배열 만들 때는, 배열 안의 모든 요소가 같은 타입이어야 한다는 걸 꼭 기억해야 해. 예를 들어:
SELECT ARRAY[1, 2, '셋'];
-- 에러: 배열의 요소는 같은 타입이어야 해
PostgreSQL은 숫자랑 문자열을 한 배열에 섞는 걸 허락하지 않아. 만약 꼭 섞어야 한다면, 타입 변환을 써야 해:
SELECT ARRAY[1::TEXT, 2::TEXT, '셋'];
-- 이제 배열은 문자열로만 구성됨
ARRAY[]에 여러 타입 쓸 때 실수
기본적으로 PostgreSQL은 배열의 내용을 보고 타입을 추론하려고 해. 만약 배열에 애매한 데이터를 넣으면, 에러가 날 수 있어:
SELECT ARRAY[1, NULL];
-- 에러: PostgreSQL은 NULL을 어떻게 해석할지 모름
이럴 땐, 데이터 타입을 명확하게 지정해주면 돼:
SELECT ARRAY[1, NULL]::INTEGER[];
-- 이제 제대로 동작함
데이터 추출 시 실수: 배열 인덱스 문제
Python이나 JavaScript처럼 0부터 인덱싱하는 언어에 익숙하다면, PostgreSQL에서 놀랄 수도 있어. 여기서는 배열 인덱스가 1부터 시작이야.
SELECT ARRAY[10, 20, 30][0];
-- 에러: 인덱스는 1부터 시작해야 해
정답은 이렇게:
SELECT ARRAY[10, 20, 30][1];
-- 결과: 10
데이터 추출 함수 쓸 때 실수
unnest() 같은 함수는 배열을 "펼쳐서" 여러 행으로 만들어주는데, 이걸 잘 모르면 헷갈릴 수 있어:
CREATE TEMP TABLE example (
id SERIAL PRIMARY KEY,
tags TEXT[]
);
INSERT INTO example (tags) VALUES (ARRAY['태그1', '태그2']), (ARRAY['태그3']);
SELECT unnest(tags) FROM example;
-- 결과:
-- 태그1
-- 태그2
-- 태그3
만약 행의 컨텍스트(예: id)도 같이 보고 싶으면, 명시적으로 추가해줘야 해:
SELECT id, unnest(tags) AS tag FROM example;
-- 결과:
-- id | tag
-- 1 | 태그1
-- 1 | 태그2
-- 2 | 태그3
배열 필터링 및 비교 시 실수
@>,<@,&&연산자 잘못 쓰기
이 연산자들은 특정 목적에 맞게 쓰는 거야:
@>는 한 배열이 다른 배열을 포함하는지 확인해.<@는 한 배열이 다른 배열 안에 포함되어 있는지 확인해.&&는 두 배열이 겹치는 요소가 있는지 확인해.
잘못 쓰면 에러가 나:
SELECT ARRAY[1, 2, 3] @> 2;
-- 에러: @> 연산자는 배열끼리만 써야 해
정답:
SELECT ARRAY[1, 2, 3] @> ARRAY[2];
-- 결과: true
- 인덱스 없을 때 성능 문제
배열 연산자를 자주 쓰는데 쿼리가 느려진다면, 인덱스를 안 만든 게 원인일 수 있어. 배열 인덱스 예시:
CREATE INDEX idx_tags ON example USING GIN (tags);
이제 @>랑 && 연산자 쿼리가 훨씬 빨라질 거야.
배열 수정 시 실수
- 값 삭제 및 추가
array_remove()랑 array_append() 함수는 배열을 "그 자리에서" 바꾸는 게 아니라, 새로운 배열을 반환해. 원래 배열이 바뀔 거라고 생각하면 실수야:
UPDATE example
SET tags = array_remove(tags, '태그1');
-- 이제 배열이 업데이트됨
SET tags =를 빼먹으면, SQL은 실행되지만 배열은 안 바뀌어.
array_append()쓸 때 데이터 중복
array_append()는 요소가 이미 있는지 확인 안 해. 그래서 중복이 생길 수 있어:
SELECT array_append(ARRAY['태그1', '태그2'], '태그1');
-- 결과: {태그1, 태그2, 태그1}
중복을 피하려면, 필터링을 써야 해:
SELECT array_remove(array_append(ARRAY['태그1', '태그2'], '태그1'), '태그1') || '태그1';
-- 결과: {태그1, 태그2}
실수 예방 꿀팁
배열 작업할 때 위에서 말한 실수를 피하려면:
- 데이터 타입 꼭 확인하기. 애매할 땐 배열 타입을 명확히 지정해.
- 인덱스 신경쓰기. PostgreSQL 배열은 1부터 인덱싱된다는 거 잊지 마.
- 배열 쿼리 최적화하기. 비교나 필터링 연산 빠르게 하려면 인덱스 활용해.
- 작은 데이터셋으로 먼저 테스트. 쿼리가 느리면, 적은 데이터로 먼저 돌려서 병목을 찾아봐.
- 중복 방지. 배열에 요소 추가할 때 중복이 안 생기게 체크해.
PostgreSQL의 배열은 강력한 무기인 만큼, 조심해서 써야 해. 이 팁들만 기억하면, 배열 때문에 밤새는 일은 이제 거의 없을 거야(아마도). 데이터베이스 설계랑 최적화, 화이팅!
GO TO FULL VERSION