PostgreSQL 주니어 기술면접
새 면접Q. PostgreSQL에서 트랜잭션 격리 수준(Isolation Level) 중 READ COMMITTED와 REPEATABLE READ의 차이점을 설명하고, 각각 어떤 동시성 문제를 해결할 수 있나요?
READ COMMITTED는 커밋된 데이터만 읽을 수 있으며, 같은 트랜잭션 내에서도 다른 시점에 같은 쿼리를 실행하면 다른 결과를 얻을 수 있습니다(Non-Repeatable Read 발생 가능). REPEATABLE READ는 트랜잭션이 시작된 시점의 스냅샷을 기준으로 데이터를 읽어 같은 쿼리는 항상 같은 결과를 반환하며, Non-Repeatable Read 문제를 방지합니다. PostgreSQL의 기본 격리 수준은 READ COMMITTED이며, 데이터 일관성이 중요한 경우 REPEATABLE READ를 사용합니다.
- • READ COMMITTED는 커밋된 데이터만 읽고 Non-Repeatable Read 발생 가능
- • REPEATABLE READ는 트랜잭션 시작 시점의 스냅샷 사용으로 일관된 읽기 보장
- • PostgreSQL 기본값은 READ COMMITTED
- • 데이터 일관성 요구사항에 따라 격리 수준 선택
SERIALIZABLE 격리 수준은 언제 사용하며, 성능에 어떤 영향을 미치나요?
Q. PostgreSQL에서 B-tree 인덱스와 Hash 인덱스의 차이점을 설명하고, 각각 어떤 쿼리 패턴에 적합한가요?
B-tree 인덱스는 정렬된 트리 구조로 범위 검색, 정렬, 부등호 비교 등 다양한 연산을 지원하며 PostgreSQL의 기본 인덱스 타입입니다. Hash 인덱스는 해시 함수를 사용해 등호(=) 비교만 지원하지만 단순 동등 비교에서는 B-tree보다 빠를 수 있습니다. 실무에서는 대부분의 경우 B-tree를 사용하며, WHERE 절에 범위 검색이나 정렬이 필요한 경우 B-tree가 필수입니다. Hash 인덱스는 PostgreSQL 10 이후 안정화되었으나 여전히 제한적으로 사용됩니다.
- • B-tree는 범위 검색, 정렬, 부등호 비교 등 다양한 연산 지원
- • Hash 인덱스는 등호 비교만 지원하며 특수한 경우에만 사용
- • B-tree가 PostgreSQL의 기본이자 가장 범용적인 인덱스
- • 쿼리 패턴에 따라 적절한 인덱스 타입 선택 필요
GiST와 GIN 인덱스는 어떤 경우에 사용하나요?
Q. PostgreSQL에서 NULL 값의 특성과 NULL을 비교할 때 사용하는 IS NULL, IS NOT NULL을 = 연산자 대신 사용해야 하는 이유를 설명해주세요.
NULL은 '값이 없음' 또는 '알 수 없음'을 나타내는 특수한 상태로, 어떤 값과도 같지 않으며 NULL 자기 자신과도 같지 않습니다. NULL = NULL은 NULL을 반환하며 TRUE가 아니기 때문에, WHERE 절에서 = NULL을 사용하면 의도한 결과를 얻을 수 없습니다. 따라서 NULL 여부를 확인할 때는 반드시 IS NULL 또는 IS NOT NULL을 사용해야 합니다. 이는 SQL 표준에 정의된 3값 논리(TRUE, FALSE, NULL) 체계 때문입니다.
- • NULL은 값이 없거나 알 수 없는 상태를 나타냄
- • NULL = NULL은 FALSE가 아닌 NULL을 반환
- • NULL 비교는 IS NULL, IS NOT NULL 사용 필수
- • 3값 논리 체계로 인한 특수 처리 필요
COALESCE 함수와 NULLIF 함수의 사용 목적과 차이점은 무엇인가요?
Q. PostgreSQL에서 서브쿼리(Subquery)와 CTE(Common Table Expression, WITH 절)의 차이점을 설명하고, CTE를 사용하는 것이 유리한 경우는 언제인가요?
서브쿼리는 다른 쿼리 내부에 중첩된 SELECT 문이며, CTE는 WITH 절을 사용해 임시 결과 집합에 이름을 부여하는 방식입니다. CTE는 가독성이 높고 같은 결과를 여러 번 참조할 때 코드 중복을 줄일 수 있으며, 재귀 쿼리 작성이 가능합니다. 복잡한 쿼리를 단계별로 나누어 표현할 때나, 같은 서브쿼리를 여러 곳에서 사용할 때 CTE가 유리합니다. 다만 PostgreSQL 12 이전 버전에서는 CTE가 항상 materialize되어 성능 이슈가 있을 수 있으므로 상황에 따라 선택해야 합니다.
- • CTE는 WITH 절로 임시 결과에 이름을 부여하는 방식
- • CTE는 가독성이 높고 재사용 가능하며 재귀 쿼리 지원
- • 복잡한 쿼리를 논리적 단계로 분리할 때 유용
- • 버전에 따라 성능 특성이 다를 수 있음
재귀 CTE(Recursive CTE)는 어떤 경우에 사용하며, 어떻게 작성하나요?
Q. PostgreSQL에서 정규화(Normalization)의 목적과 제1정규형, 제2정규형, 제3정규형의 기본 개념을 설명하고, 실무에서 역정규화(Denormalization)를 고려하는 경우는 언제인가요?
정규화는 데이터 중복을 최소화하고 무결성을 보장하기 위해 테이블을 분리하는 과정입니다. 제1정규형은 모든 속성이 원자값을 가져야 하고, 제2정규형은 부분 함수 종속을 제거하며, 제3정규형은 이행 함수 종속을 제거합니다. 정규화는 데이터 일관성과 저장 공간 효율성을 높이지만, 과도한 JOIN으로 조회 성능이 저하될 수 있습니다. 실무에서는 읽기 성능이 중요한 경우, 복잡한 JOIN을 피해야 하는 경우, 집계 데이터를 자주 조회하는 경우에 의도적으로 역정규화를 적용합니다.
- • 정규화는 데이터 중복 제거와 무결성 보장이 목적
- • 1NF는 원자값, 2NF는 부분 종속 제거, 3NF는 이행 종속 제거
- • 정규화는 일관성 향상, 과도하면 조회 성능 저하
- • 읽기 성능이 중요하거나 복잡한 JOIN 회피 시 역정규화 고려
역정규화를 적용할 때 데이터 일관성을 유지하기 위한 방법에는 어떤 것들이 있나요?
아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!