일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- chatGPT's answer
- 유닉스
- 시스템
- JVM
- GPT-4's answer
- 역학
- 데이터베이스
- 고전역학
- write by GPT-4
- 코틀린
- 소프트웨어공학
- 파이썬
- Java
- 자바
- jpa
- kotlin
- 인프라
- oracle
- python
- 웹 크롤링
- Database
- 자바암호
- android
- 리눅스
- spring data jpa
- Spring boot
- NIO
- write by chatGPT
- 자바네트워크
- flet
- Today
- Total
Akashic Records
PostgreSQL 알아보기 본문
PostgreSQL은 성능, 기능성, 그리고 오픈 소스 라이선스를 갖춘 인기 있는 관계형 데이터베이스 관리 시스템(RDBMS)입니다. 그 역사는 다음과 같습니다:
- 1986년 - POSTGRES 프로젝트 시작: PostgreSQL의 전신인 POSTGRES 프로젝트는 1986년 UC 버클리에서 마이클 스톤브레이커 교수가 주도하여 시작되었습니다. 이 프로젝트는 그의 이전 프로젝트인 Ingres 데이터베이스를 발전시키기 위한 것이었습니다.
- 1994년 - SQL 언어 도입: 초기의 POSTGRES는 SQL을 사용하지 않았지만, 1994년경 POSTGRES 프로젝트에 SQL 언어가 도입되면서 PostgreSQL로 이름이 변경되었습니다. 이때부터 SQL 쿼리 언어를 사용할 수 있게 되었고, 이는 데이터베이스 접근성을 크게 향상시켰습니다.
- 1996년 - 첫 공식 릴리즈: PostgreSQL 6.0은 1996년에 첫 공식 릴리즈가 되었습니다. 이 버전은 인터넷 커뮤니티에 의해 개발되었으며, 이후로 PostgreSQL은 전 세계 수많은 기여자들에 의해 지속적으로 발전해왔습니다.
- 2000년대 - 기능 확장: 2000년대에 들어서 PostgreSQL은 트랜잭션 격리, MVCC (Multi-Version Concurrency Control), 외부 키, 조인, 뷰 등과 같은 고급 기능들을 추가하여 엔터프라이즈 수준의 데이터베이스 시스템으로 성장하였습니다.
- 2010년대 - 성능 및 확장성 개선: 2010년대에 PostgreSQL은 복제(replication), 파티셔닝(partitioning), 그리고 인덱싱 등의 기능을 통해 성능과 확장성을 크게 향상시켰습니다. 이러한 기능들은 대용량 데이터 처리 및 분산 데이터베이스 시스템을 필요로 하는 기업에게 매우 중요했습니다.
- 최근 발전: 최근에는 클라우드 환경과 호환성, JSON 지원 확장, 보안 강화 등의 기능이 추가되어 현대적인 데이터베이스 요구사항을 충족시키고 있습니다.
PostgreSQL은 계속해서 커뮤니티 기반 개발 모델로 운영되며, 세계적으로 많은 기업과 조직에서 신뢰하고 사용하는 오픈 소스 데이터베이스로 자리 잡았습니다. 이런 이유로 PostgreSQL은 기술적 진화 뿐만 아니라, 커뮤니티의 지원과 기여를 통한 진화의 모범 사례로도 평가받고 있습니다.
PostgreSQL 데이터베이스 아키텍처
PostgreSQL의 아키텍처는 다양한 컴포넌트로 구성되어 있으며, 이러한 구성 요소들은 데이터베이스 서버의 효율적인 운영을 지원합니다. 이 아키텍처는 클라이언트/서버 모델을 기반으로 하고 있으며, 여러 프로세스와 모듈이 상호 작용하여 데이터베이스 작업을 처리합니다. 아래는 PostgreSQL 아키텍처의 주요 구성 요소입니다:
1. 서버 프로세스
- Postmaster: 데이터베이스 서버의 주 프로세스로, 서버가 시작될 때 생성됩니다. 클라이언트 연결을 수신하고, 새 클라이언트 세션을 위해 적절한 서버 프로세스(일반적으로
postgres
라 불리는 백엔드 프로세스)를 시작합니다. - Backend Processes: 각 클라이언트 연결에 대해 별도의 백엔드 프로세스가 생성됩니다. 이 프로세스는 SQL 명령을 실행하고, 데이터를 조작하며, 결과를 클라이언트에게 반환합니다.
2. 메모리 구조
- 공유 메모리: 모든 백엔드 프로세스가 접근할 수 있는 메모리 영역으로, 버퍼 캐시, WAL 버퍼, 락 테이블 등이 포함됩니다.
- 로컬 메모리: 각 백엔드 프로세스가 독립적으로 사용하는 메모리로, 작업 중인 쿼리의 실행 계획과 중간 결과 등을 저장합니다.
3. WAL
- WAL(Write-Ahead Logging): 데이터 무결성과 회복력을 보장하기 위해 모든 변경 사항을 로깅하는 기능입니다. 데이터 변경 내용은 실제 데이터를 디스크에 기록하기 전에 로그로 기록됩니다. 이 로그는 시스템 장애 후 데이터를 복구하는 데 사용됩니다.
4. 백그라운드 작업자
- Autovacuum Worker: 데이터베이스 내의 가비지 컬렉션을 자동으로 처리하고, 테이블을 정리하여 시스템 성능을 유지합니다.
- WAL Writer: WAL 레코드를 디스크에 주기적으로 플러시하여 시스템의 내구성을 강화합니다.
- Checkpoint Worker: 정기적인 체크포인트를 수행하여 데이터베이스의 회복 시간을 단축합니다.
5. 네트워크 인터페이스
- libpq: PostgreSQL의 C 클라이언트 라이브러리로, 서버와 클라이언트 간의 통신을 담당합니다. 이 라이브러리는 네트워크 프로토콜을 처리하고, 클라이언트 애플리케이션과 서버 간의 데이터 교환을 가능하게 합니다.
6. 쿼리 처리
- Parser: SQL 쿼리를 분석하고 구문 트리를 생성합니다.
- Planner/Optimizer: 구문 트리를 기반으로 최적의 쿼리 실행 계획을 생성합니다.
- Executor: 실행 계획에 따라 쿼리를 실행하고 결과를 반환합니다.
PostgreSQL의 이러한 아키텍처는 확장성, 복원력, 동시성을 지원하며, 큰 데이터베이스 시스템에서도 뛰어난 성능을 제공합니다. 데이터베이스 설계와 운영을 위해 이러한 구조적 이해는 필수적입니다.
PostgreSQL 데이터베이스 구조
PostgreSQL 데이터베이스 구조와 그 작동 방식은 관계형 데이터베이스 관리 시스템(RDBMS)의 특징을 잘 나타내며, 효율적인 데이터 관리와 다양한 데이터베이스 작업을 지원하는 데 필수적인 여러 구성 요소를 포함하고 있습니다. PostgreSQL의 주요 구성 요소와 데이터베이스 수행 방식을 이해하면 PostgreSQL 데이터베이스를 보다 효과적으로 설계하고 사용할 수 있습니다.
- 데이터베이스 서버와 인스턴스
- PostgreSQL 서버는 하나 이상의 데이터베이스 인스턴스로 구성됩니다. 각 인스턴스는 독립적인 데이터베이스 시스템으로서 서로 다른 데이터베이스와 통신할 수 있습니다.
- 데이터베이스
- 데이터베이스는 스키마, 테이블, 뷰, 인덱스 등 여러 데이터베이스 객체를 포함하는 컨테이너입니다. PostgreSQL에서는 여러 데이터베이스를 하나의 인스턴스에 생성할 수 있으며, 각 데이터베이스는 서로 독립적입니다.
- 스키마
- 스키마는 데이터베이스 내에서 관련 데이터 구조를 논리적으로 그룹화하는 방법을 제공합니다. 테이블, 뷰, 인덱스, 데이터 타입, 함수 등을 포함할 수 있습니다. 스키마를 사용하면 같은 데이터베이스 내에서 이름 충돌 없이 동일한 이름의 객체를 여러 개 생성할 수 있습니다.
- 테이블
- 테이블은 데이터를 저장하는 기본 단위입니다. 각 테이블은 여러 개의 열(column)과 행(row)을 가지며, 각 열은 특정 타입의 데이터를 저장합니다.
- 인덱스
- 인덱스는 데이터베이스 내의 데이터 검색 속도를 향상시키기 위한 데이터 구조입니다. 인덱스를 적절히 사용하면, 쿼리의 실행 시간을 단축시킬 수 있습니다.
- 뷰
- 뷰는 하나 이상의 테이블에서 데이터를 도출하는 가상 테이블입니다. 복잡한 쿼리를 단순화하고, 데이터 접근을 제한하는 데 유용합니다.
- 함수 및 저장 프로시저
- 함수와 저장 프로시저는 SQL과 PL/pgSQL, Python 등 여러 프로그래밍 언어로 작성할 수 있으며, 데이터베이스 작업을 자동화하고 재사용 가능한 코드 블록을 생성하는 데 사용됩니다.
데이터베이스 수행 방식
- 트랜잭션 관리
- PostgreSQL은 ACID(Atomicity, Consistency, Isolation, Durability) 속성을 준수하는 트랜잭션 관리를 지원합니다. 이는 데이터 무결성과 동시성을 보장합니다.
- 동시성 제어
- MVCC(Multi-Version Concurrency Control)를 사용하여 데이터베이스에서 동시에 여러 작업이 이루어질 수 있도록 지원합니다. 이는 읽기 작업이 쓰기 작업을 차단하지 않고, 쓰기 작업이 읽기 작업을 차단하지 않도록 함으로써 동시성을 향상시킵니다.
- 쿼리 실행
- 사용자 또는 응용 프로그램은 SQL 쿼리를 데이터베이스 서버로 전송하고, 서버는 쿼리를 해석하고 실행한 후 결과를 반환합니다. 쿼리 플래너 및 실행 엔진은 쿼리를 최적의 방식으로 실행하기 위해 실행 계획을 생성합니다.
PostgreSQL 데이터베이스의 이러한 구조와 수행 방식은 효과적인 데이터 관리와 높은 성능의 데이터베이스 시스템을 보장하는 데 중요한 역할을 합니다. 데이터베이스 설계, 구현 및 운영 과정에서 이러한 요소들을 잘 이해하고 활용하는 것이 중요합니다.
데이터 타입
PostgreSQL과 Oracle 데이터베이스는 각기 다른 데이터 타입을 지원합니다. 두 시스템 간의 주요 데이터 타입을 비교해 보겠습니다. 이 비교는 기본 데이터 타입에 중점을 둡니다.
숫자 데이터 타입
- 정수형:
- PostgreSQL:
SMALLINT
,INTEGER
,BIGINT
- Oracle:
NUMBER(precision, scale)
(precision과 scale을 조절하여 사용),BINARY_INTEGER
- PostgreSQL:
- 부동 소수점:
- PostgreSQL:
REAL
,DOUBLE PRECISION
- Oracle:
FLOAT
,BINARY_FLOAT
,BINARY_DOUBLE
- PostgreSQL:
- 고정 소수점:
- PostgreSQL:
NUMERIC(precision, scale)
,DECIMAL(precision, scale)
- Oracle:
NUMBER(precision, scale)
,DECIMAL(precision, scale)
- PostgreSQL:
문자열 데이터 타입
- 문자열:
- PostgreSQL:
CHAR(n)
,VARCHAR(n)
,TEXT
- Oracle:
CHAR(n)
,VARCHAR2(n)
,CLOB
- PostgreSQL:
날짜 및 시간 데이터 타입
- 날짜 및 시간:
- PostgreSQL:
DATE
,TIME
,TIMESTAMP
,INTERVAL
- Oracle:
DATE
,TIMESTAMP
,TIMESTAMP WITH TIME ZONE
,TIMESTAMP WITH LOCAL TIME ZONE
,INTERVAL YEAR TO MONTH
,INTERVAL DAY TO SECOND
- PostgreSQL:
Boolean 데이터 타입
- Boolean:
- PostgreSQL:
BOOLEAN
- Oracle: Oracle은 기본적으로 BOOLEAN 타입을 지원하지 않습니다. 대신
CHAR(1)
이나NUMBER(1)
로 대체하여 사용합니다.
- PostgreSQL:
바이너리 데이터 타입
- 바이너리:
- PostgreSQL:
BYTEA
- Oracle:
RAW
,BLOB
- PostgreSQL:
추가 데이터 타입
- PostgreSQL:
ARRAY
타입 지원, 사용자 정의 데이터 타입,JSON
,XML
,UUID
등 다양한 현대적 데이터 타입과 기능을 지원합니다.
- Oracle:
XMLTYPE
,JSON
데이터 타입 및 복잡한 객체 지향 데이터 타입을 지원합니다. 또한VARRAYS
,NESTED TABLES
등 고급 컬렉션 타입도 제공합니다.
데이터 타입 호환성
데이터 마이그레이션 또는 두 시스템 간의 데이터 통합 작업 시 데이터 타입 호환성은 매우 중요한 고려사항입니다. 위에서 언급한 기본 데이터 타입들은 서로 유사하게 매핑할 수 있지만, 세부적인 기능이나 제약 조건에서는 차이가 있을 수 있습니다. 데이터베이스 설계 시 각 데이터베이스의 고유 기능과 한계를 잘 이해하고 있어야 합니다.
아래는 PostgreSQL과 Oracle 간의 주요 데이터 타입을 비교한 표입니다:
분류 | PostgreSQL 데이터 타입
|
Oracle 데이터 타입 |
정수형 | SMALLINT, INTEGER, BIGINT | NUMBER(precision, scale) (적절한 설정으로 사용) |
부동 소수점 | REAL , DOUBLE PRECISION |
FLOAT , BINARY_FLOAT , BINARY_DOUBLE |
고정 소수점 | NUMERIC(precision, scale) , DECIMAL(precision, scale) |
NUMBER(precision, scale) , DECIMAL(precision, scale) |
문자열 | CHAR(n) , VARCHAR(n) , TEXT |
CHAR(n) , VARCHAR2(n) , CLOB |
날짜 및 시간 | DATE , TIME , TIMESTAMP , INTERVAL |
DATE , TIMESTAMP , TIMESTAMP WITH TIME ZONE , TIMESTAMP WITH LOCAL TIME ZONE , INTERVAL YEAR TO MONTH , INTERVAL DAY TO SECOND |
부울 | BOOLEAN |
(직접 지원하지 않음) CHAR(1) 이나 NUMBER(1) 으로 대체 사용 |
바이너리 | BYTEA |
RAW , BLOB |
추가 타입 | ARRAY , JSON , XML , UUID 등 |
XMLTYPE , JSON , VARRAYS , NESTED TABLES 등 |
이 표는 기본적인 데이터 타입 비교를 제공하며, 두 데이터베이스 시스템 간의 데이터 타입을 매핑할 때 유용할 수 있습니다. 각 시스템의 데이터 타입에 대한 더 깊은 이해와 사용 시 고려해야 할 특수 사항은 해당 데이터베이스의 공식 문서를 참조하는 것이 좋습니다
.
아래는 PostgreSQL의 수치형 데이터 타입에 대한 표로, 각 데이터 타입의 크기, 설명, 범위, 그리고 예시를 포함하고 있습니다:
데이터 타입 | 크기 (바이트) | 설명 | 범위 | 예시 |
SMALLINT | 2 | 작은 범위의 정수 | -32,768에서 32,767까지 | 1234 |
INTEGER |
4 | 표준 정수형 | -2,147,483,648에서 2,147,483,647까지 | 123456 |
BIGINT |
8 | 큰 범위의 정수 | -9,223,372,036,854,775,808에서 9,223,372,036,854,775,807까지 | 123456789012 |
REAL |
4 | 싱글 프리시전 부동 소수점 숫자 | 약 6-7자리 소수 정밀도 | 123.456 |
DOUBLE PRECISION |
8 | 더블 프리시전 부동 소수점 숫자 | 약 15-17자리 소수 정밀도 | 123.456789 |
NUMERIC |
가변 길이 | 사용자가 지정한 정밀도의 숫자 | 최대 131,072자리까지, 소수점 16,383자리까지 | 12345.67890 |
DECIMAL |
가변 길이 | NUMERIC 과 동일하지만 다른 이름 |
NUMERIC 과 동일 |
12345.67890 |
추가 설명:
SMALLINT
,INTEGER
,BIGINT
는 정수 데이터에 적합하며, 각각 다른 범위의 수를 저장할 수 있습니다.REAL
과DOUBLE PRECISION
은 부동 소수점 수를 저장하며, 싱글 및 더블 프리시전에서 정밀도가 다릅니다.NUMERIC
과DECIMAL
은 고정 소수점 수를 저장할 때 사용되며, 필요에 따라 매우 큰 수나 매우 정밀한 수를 저장할 수 있습니다. 둘은 기능적으로 동일하며 이름만 다릅니다.
아래는 PostgreSQL에서 사용되는 날짜/시간형 데이터 타입에 대한 상세 정보를 담은 표입니다. 이 표는 각 데이터 타입의 크기, 설명, 범위 및 예시를 포함하고 있습니다:
데이터 타입 |
크기 (바이트) | 설명 | 범위 | 예시 |
DATE | 4 | 날짜만을 저장 | 4713 BC에서 5874897 AD까지 | 2024-08-20 |
TIME |
8 | 시간만을 저장 (타임존 없음) | 00:00:00에서 24:00:00까지 | 23:59:59 |
TIMESTAMP |
8 | 날짜와 시간을 저장 (타임존 없음) | 4713 BC에서 294276 AD까지 | 2024-08-20 23:59:59 |
TIMESTAMPTZ |
8 | 날짜와 시간을 저장 (타임존 포함) | 4713 BC에서 294276 AD까지 | 2024-08-20 23:59:59+00 |
TIME WITH TIME ZONE |
12 | 시간을 저장 (타임존 포함) | 00:00:00+1459에서 24:00:00-1459까지 | 23:59:59+01 |
INTERVAL |
16 | 기간 또는 시간 간격을 저장 | -178000000 년에서 +178000000 년까지의 범위 | P1Y2M10DT2H30M |
추가 설명:
DATE
데이터 타입은 단순히 날짜 정보만을 저장합니다.TIME
및TIME WITH TIME ZONE
데이터 타입은 시간 정보를 저장하지만, 후자는 타임존 정보도 포함합니다.TIMESTAMP
및TIMESTAMPTZ
(TIMESTAMP WITH TIME ZONE) 데이터 타입은 날짜와 시간을 함께 저장하며, 후자는 타임존 정보도 포함합니다.INTERVAL
데이터 타입은 기간 또는 시간 간격을 표현하며, 날짜와 시간 단위로 표현될 수 있습니다.
이 데이터 타입들은 날짜와 시간 정보를 다룰 때 광범위하게 사용되며, 특히 타임존을 고려해야 할 경우 TIMESTAMPTZ
와 TIME WITH TIME ZONE
이 유용하게 사용됩니다.
아래는 PostgreSQL에서 사용되는 문자형 데이터 타입에 대한 상세 정보를 담은 표입니다. 이 표는 각 데이터 타입의 크기, 설명, 범위 및 예시를 포함하고 있습니다:
데이터 타입
|
크기 (바이트) | 설명 | 범위 | 예시 |
CHAR(n) | n | 고정 길이 문자열. 빈 공간은 공백으로 채워짐 | 1바이트당 1문자. 최대 길이는 시스템에 따라 다름 | 'Hello ' |
VARCHAR(n) |
가변 길이 | 가변 길이 문자열. 지정된 길이 n까지만 저장 | 1바이트당 1문자. 최대 길이는 시스템에 따라 다름 | 'Hello' |
TEXT |
가변 길이 | 가변 길이 문자열. 길이 제한 없음 | 실질적으로 저장 가능한 문자 수는 시스템 메모리에 의해 제한됨 | 'This is a long text string' |
추가 설명:
CHAR(n)
데이터 타입은 고정 길이를 가지며, 지정된 길이보다 짧은 문자열을 저장할 경우 나머지 공간을 공백으로 채웁니다. 이로 인해 데이터 저장 공간이 낭비될 수 있으나, 데이터 검색 속도가 빠를 수 있습니다.VARCHAR(n)
데이터 타입은 지정된 최대 길이까지만 문자를 저장할 수 있으며, 입력된 문자열 길이에 따라 필요한 저장 공간이 달라집니다. 이는 공간 효율성을 높이지만, 고정 길이 데이터에 비해 처리 속도가 느려질 수 있습니다.TEXT
데이터 타입은 길이 제한이 없어 매우 긴 텍스트를 저장할 수 있습니다. 저장할 수 있는 실제 길이는 시스템의 메모리 및 구성에 따라 달라질 수 있으며, 대량의 텍스트 데이터를 저장하는 데 적합합니다.
이러한 문자형 데이터 타입들은 다양한 용도로 사용되며, 선택 시 데이터의 특성 및 용도를 고려하는 것이 중요합니다. 데이터의 길이가 일정하거나 작은 경우 CHAR
를 사용하고, 길이가 가변적이거나 예측할 수 없는 경우 VARCHAR
나 TEXT
를 사용하는 것이 일반적입니다.
PostgreSQL과 Oracle 데이터베이스에서 데이터베이스, 스키마, 그리고 계정의 관계는 각 시스템의 아키텍처와 용어에서 약간의 차이를 보입니다. 이러한 차이를 명확하게 이해하는 것은 두 데이터베이스 시스템 간의 작업을 효과적으로 이해하고 관리하는 데 도움이 됩니다. 아래 표는 각 시스템에서 이 용어들이 어떻게 관련되어 있는지를 설명합니다:
구분 | PostgreSQL | Oracle |
데이터베이스 | 한 인스턴스에 여러 데이터베이스를 만들 수 있음 | 일반적으로 한 인스턴스에 하나의 데이터베이스만 존재 |
스키마 | 데이터베이스 내에서 별도의 스키마를 생성하여 객체(테이블, 뷰 등)를 그룹화 | 사용자(계정)마다 기본적으로 하나의 스키마가 할당되며, 스키마 이름은 사용자 이름과 동일 |
계정 | 사용자(계정)은 특정 데이터베이스에 접속하여 작업하며, 각 데이터베이스는 독립적인 권한과 객체를 가짐 | 계정(사용자)은 시스템 전체에서 유일하며, 사용자가 소유하는 객체는 해당 사용자의 스키마에 저장됨 |
추가 설명:
- PostgreSQL에서는 '데이터베이스'가 상대적으로 더 독립적인 저장 컨테이너 역할을 하며, 각 데이터베이스 내에 여러 '스키마'를 생성할 수 있습니다. 각 스키마는 그 안에 다양한 데이터베이스 객체를 포함할 수 있고, 다른 스키마의 객체와 독립적으로 존재할 수 있습니다.
- Oracle에서는 '데이터베이스'가 일반적으로 전체 시스템을 지칭하며, '스키마'와 '계정'은 거의 동일한 개념으로 사용됩니다. 각 계정은 자신만의 스키마를 가지고, 그 스키마 안에 데이터베이스 객체들을 소유합니다.
이러한 차이는 각 데이터베이스 시스템의 설계 철학과 관리 방식에 근거하며, 이를 이해하는 것은 데이터베이스 설계와 관리에 중요합니다.
기본적인 페이지네이션 쿼리
PostgreSQL에서 페이지네이션을 구현하는 방법은 LIMIT
와 OFFSET
구문을 사용하여 쿼리 결과의 개수와 시작점을 조절하는 것입니다. 이는 데이터가 많은 웹 페이지나 어플리케이션에서 특정 범위의 데이터를 순차적으로 표시할 때 유용합니다.
예시:
SELECT * FROM employees
ORDER BY employee_id
LIMIT 10 OFFSET 0;
위 쿼리는 employees
테이블에서 employee_id
를 기준으로 정렬하여 첫 번째 페이지의 데이터 10개를 가져옵니다. 여기서 OFFSET 0
은 첫 번째 행부터 시작한다는 의미입니다.
다음 페이지를 조회하기 위해 OFFSET
값을 조정합니다.
예시:
SELECT * FROM employees
ORDER BY employee_id
LIMIT 10 OFFSET 10;
이 쿼리는 두 번째 페이지의 데이터를 가져옵니다. OFFSET 10
은 처음 10개 행을 건너뛰고 다음 10개 행을 조회한다는 의미입니다.
페이지네이션을 위한 계산
일반적으로, 웹 페이지나 어플리케이션에서 페이지 번호와 페이지 크기를 기반으로 OFFSET
을 계산할 수 있습니다. 예를 들어, 사용자가 5번째 페이지를 요청하고 각 페이지당 10개의 데이터를 보여주길 원한다면, OFFSET
은 다음과 같이 계산됩니다.
계산식:
OFFSET = (페이지 번호 - 1) * 페이지 크기
쿼리 예시:
SELECT * FROM employees
ORDER BY employee_id
LIMIT 10 OFFSET 40;
위 쿼리는 5번째 페이지의 데이터를 조회합니다 (페이지 번호 5, 페이지 크기 10).
효율적인 페이지네이션
대용량 데이터를 다룰 때는 OFFSET
를 사용한 페이지네이션이 성능 저하를 일으킬 수 있습니다. 특히 높은 OFFSET
값은 데이터베이스가 많은 데이터를 건너뛰어야 하기 때문에 비효율적일 수 있습니다. 이를 개선하기 위한 한 가지 방법은 마지막으로 조회한 페이지의 최대 employee_id
를 사용하여 다음 페이지의 데이터를 조회하는 것입니다.
예시:
SELECT * FROM employees
WHERE employee_id > 마지막_employee_id
ORDER BY employee_id
LIMIT 10;
이 방식은 OFFSET
를 사용하지 않고도 다음 데이터 페이지를 효율적으로 조회할 수 있어 성능을 개선할 수 있습니다.
PostgreSQL에서 중복된 결과를 제거하는 가장 일반적인 방법은 DISTINCT
키워드를 사용하는 것입니다. DISTINCT
는
DISTINCT의 사용
쿼리의 결과로 나오는 행들 중에서 유일한 행만을 선택하여 반환합니다. 이는 특히 SELECT 문에서 여러 행이 동일한 값을 가질 때 유용하게 사용할 수 있습니다.
단일 컬럼에 대한 중복 제거
만약 특정 컬럼에서 중복된 값을 제거하고자 할 때, 해당 컬럼만 SELECT
절에 명시하면 됩니다.
예시:
SELECT DISTINCT column_name
FROM table_name;
이 쿼리는 table_name
테이블의 column_name
컬럼에서 중복을 제거한 모든 유니크한 값들을 반환합니다.
여러 컬럼에 대한 중복 제거
여러 컬럼의 조합에서 유니크한 행만을 반환하려면, SELECT
절에 여러 컬럼을 명시합니다.
예시:
SELECT DISTINCT column1, column2
FROM table_name;
이 쿼리는 table_name
테이블에서 column1
과 column2
의 조합이 유니크한 행들만을 반환합니다. 이는 두 컬럼의 조합으로 중복을 판단합니다.
고급 사용법: DISTINCT ON
PostgreSQL은 DISTINCT ON
이라는 더욱 강력한 기능을 제공합니다. 이는 특정 컬럼을 기준으로 중복을 제거할 때 다른 컬럼의 어떤 값이 반환될지 더 세밀하게 제어할 수 있게 합니다.
예시:
SELECT DISTINCT ON (column1) column1, column2
FROM table_name
ORDER BY column1, column2;
이 쿼리는 column1
을 기준으로 중복을 제거하되, ORDER BY
절에서 정의된 순서에 따라 column1
의 값이 같은 경우 column2
의 첫 번째 값을 선택합니다.
DISTINCT
와 DISTINCT ON
은 데이터에서 중복을 제거하고, 데이터 분석이나 결과의 정확성을 향상시키는 데 유용합니다. 적절한 컬럼을 선택하여 사용하는 것이 중요하며, 쿼리의 성능에도 영향을 미칠 수 있으니 사용 시 주의가 필요합니다.
연산자
PostgreSQL에서는 다양한 유형의 연산자들이 사용됩니다. 이 연산자들은 데이터를 비교, 평가 및 계산하는 데 사용됩니다. 아래는 PostgreSQL에서 흔히 사용되는 주요 연산자들의 종류와 예시입니다.
1. 산술 연산자
산술 연산자는 숫자 데이터 타입에 사용되어 값들을 계산합니다.
연산자 |
설명 | 예시 |
+ | 덧셈 | a + b |
- |
뺄셈 | a - b |
* |
곱셈 | a * b |
/ |
나눗셈 | a / b |
% |
나머지 | a % b |
^ |
거듭제곱 | a ^ b |
2. 비교 연산자
비교 연산자는 두 값이나 표현식을 비교하여 참 또는 거짓을 반환합니다.
연산자 | 설명 | 예신 |
= | 같음 | a = b |
!= 또는 <> |
같지 않음 | a != b |
> |
큼 | a > b |
< |
작음 | a < b |
>= |
크거나 같음 | a >= b |
<= |
작거나 같음 | a <= b |
3. 논리 연산자
논리 연산자는 하나 이상의 논리식을 결합하여 참 또는 거짓을 반환합니다.
연산자 | 설명 | 예신 |
AND | 둘 다 참일 때 참 | a > 10 AND b < 5 |
OR |
둘 중 하나라도 참일 때 참 | a > 10 OR b < 5 |
NOT |
부정 | NOT (a > 10) |
4. 문자열 연산자
문자열 연산자는 문자열을 조작하는 데 사용됩니다.
연산자 | 설명 | 예시 |
SUBSTRING | 문자열의 일부를 추출합니다. | SUBSTRING('Hello World' FROM 1 FOR 5) 결과: 'Hello' |
POSITION | 문자열 내 다른 문자열의 위치를 찾습니다. | POSITION('World' IN 'Hello World') 결과: 7 |
LENGTH | 문자열의 길이를 반환합니다. | LENGTH('Hello World') 결과: 11 |
LOWER | 문자열을 소문자로 변환합니다. | LOWER('Hello World') 결과: 'hello world' |
UPPER | 문자열을 대문자로 변환합니다. | UPPER('Hello World') 결과: 'HELLO WORLD' |
|| | 연결연산자 | 'Hello, ' || 'World!' |
5. 패턴 매칭 연산자
패턴 매칭 연산자는 특정 패턴이나 형식을 데이터와 비교하는 데 사용됩니다.
연산자
|
설명 | 예신 |
LIKE | 단순 패턴 매칭 | name LIKE 'A%' |
ILIKE |
대소문자를 구분하지 않는 패턴 매칭 | name ILIKE 'a%' |
SIMILAR TO |
SQL 표준에 따른 패턴 매칭 | name SIMILAR TO 'A%' |
6. 비트 연산자
비트 연산자는 비트 단위 연산을 수행합니다.
연산자 | 설명 | 예시 |
& | 비트 AND | b1 & b2 |
` | ` | 비트 OR |
# |
비트 XOR | b1 # b2 |
~ |
비트 NOT | ~ b1 |
<< |
왼쪽 시프트 | b1 << 2 |
>> |
오른쪽 시프트 | b1 >> 2 |
내장 함수
PostgreSQL은 다양한 내장 함수를 제공하여 데이터 조작, 변환, 계산 등을 효율적으로 수행할 수 있게 도와줍니다. 이 내장 함수들은 다양한 카테고리에 속하며, 각기 다른 용도로 사용됩니다. 여기 몇 가지 주요 카테고리와 그 예시를 소개합니다.
1. 수학 함수
PostgreSQL의 수학 함수들은 숫자 데이터 타입에 대한 다양한 계산을 수행합니다.
ABS(x)
: 숫자의 절대값을 반환합니다.CEIL(x)
또는CEILING(x)
: 숫자를 올림합니다.FLOOR(x)
: 숫자를 내림합니다.ROUND(x)
: 숫자를 반올림합니다.EXP(x)
: e (자연 로그의 밑)의 x 제곱을 계산합니다.LN(x)
: 숫자의 자연 로그 값을 계산합니다.LOG(b, x)
: 밑이 b인 x의 로그 값을 계산합니다.POWER(a, b)
: a의 b제곱을 계산합니다.SQRT(x)
: 숫자의 제곱근을 계산합니다.
2. 문자열 함수
문자열 함수는 텍스트 데이터를 조작하고 처리하는 데 사용됩니다.
LENGTH(string)
: 문자열의 길이를 반환합니다.LOWER(string)
: 문자열을 소문자로 변환합니다.UPPER(string)
: 문자열을 대문자로 변환합니다.TRIM(string)
: 문자열 앞뒤의 공백을 제거합니다.SUBSTRING(string FROM start FOR length)
: 문자열의 특정 부분을 추출합니다.POSITION(substring IN string)
: 주어진 부분 문자열이 시작되는 첫 위치를 반환합니다.REPLACE(string, from_string, to_string)
: 문자열에서 특정 문자열을 다른 문자열로 교체합니다.
3. 날짜 및 시간 함수
날짜와 시간 데이터를 처리하는 데 유용한 함수들입니다.
CURRENT_DATE
: 현재 날짜를 반환합니다.CURRENT_TIME
: 현재 시간을 반환합니다.EXTRACT(field FROM source)
: 날짜/시간에서 특정 부분(년, 월, 일 등)을 추출합니다.AGE(timestamp)
: 현재 날짜와 주어진 타임스탬프 사이의 시간 차이를 반환합니다.DATE_PART('field', source)
:EXTRACT
와 유사하게 날짜/시간에서 특정 부분을 추출합니다.TO_CHAR(timestamp, format)
: 날짜/시간을 문자열로 변환하여 주어진 포맷대로 출력합니다.
4. 변환 함수
데이터 타입을 변환하는 데 사용되는 함수들입니다.
CAST(expression AS type)
: 표현식을 지정된 데이터 타입으로 변환합니다.TO_NUMBER(string, format)
: 문자열을 숫자로 변환합니다.TO_DATE(string, format)
: 문자열을 날짜 타입으로 변환합니다.
5. 집계 함수
데이터를 요약하는 데 사용되는 함수들입니다.
COUNT(*)
: 테이블의 행 수를 반환합니다.SUM(column)
: 숫자 열의 합을 반환합니다.AVG(column)
: 숫자 열의 평균 값을 계산합니다.MAX(column)
: 열에서 최대값을 찾습니다.MIN(column)
: 열에서 최소값을 찾습니다.
이 외에도 PostgreSQL은 JSON 데이터 처리, 배열 조작, 지리적 데이터 처리 등을 위한 다양한 전문 함수를 제공합니다. 각 함수는 특정 데이터 타입이나 필요에 맞게 디자인되어 있으며, 효과적인 데이터베이스 설계와 쿼리 작성을 위해 이러한 함수들을 적절히 활용하는 것이 중요합니다.
타입변환
PostgreSQL에서 데이터 타입을 변환하는 데 사용할 수 있는 주요 함수와 기능은 몇 가지 있습니다. 이들은 다른 타입의 데이터를 원하는 타입으로 쉽게 변환할 수 있게 도와줍니다. 여기 몇 가지 주요 변환 메커니즘을 소개합니다:
1. CAST
연산자
CAST
연산자는 하나의 데이터 타입을 다른 데이터 타입으로 명시적으로 변환합니다. 이 연산자는 특히 SQL 쿼리에서 다른 타입의 데이터를 필요로 할 때 유용하게 사용됩니다.
문법:
CAST(expression AS type)
예시:
SELECT CAST('123' AS INTEGER);
위 예시는 문자열 '123'을 정수 123으로 변환합니다.
2. ::
타입 캐스트
PostgreSQL에서는 ::
연산자를 사용하여 더 간단하고 일반적인 방식으로 타입 캐스팅을 수행할 수 있습니다. 이 방식은 매우 직관적이고 SQL에서 자주 사용됩니다.
예시:
SELECT '123'::INTEGER;
이 예시는 문자열 '123'을 정수 123으로 변환합니다.
3. 변환 함수
PostgreSQL은 특정 데이터 타입으로 변환하는 데 사용할 수 있는 몇 가지 내장 함수를 제공합니다. 이들 함수는 특히 문자열 데이터를 다른 형식의 데이터로 변환할 때 유용합니다.
TO_CHAR
: 숫자나 날짜를 문자열로 변환합니다.SELECT TO_CHAR(123456, '999,999');
TO_DATE
: 문자열을 날짜로 변환합니다.SELECT TO_DATE('20240101', 'YYYYMMDD');
TO_NUMBER
: 문자열을 숫자로 변환합니다.SELECT TO_NUMBER('12,345.67', '999,999.99');
4. 명시적 변환 없이 사용
때로는 PostgreSQL이 컨텍스트에 따라 암묵적으로 타입을 변환할 수 있습니다. 예를 들어, 숫자 연산에서 문자열과 숫자를 함께 사용할 때 자동으로 변환을 시도합니다.
예시:
SELECT '100' + 20; -- 결과는 120
데이터 타입 변환은 데이터를 조작하고, 데이터베이스 간 호환성을 보장하며, 특정 기능을 사용하는 데 필수적인 작업입니다. 명시적인 타입 캐스팅을 사용할 때는 데이터의 손실이 없도록 주의하며, 변환을 수행해야 합니다. 변환 오류를 방지하기 위해 변환하려는 데이터가 타깃 데이터 타입과 호환되는지 항상 확인하는 것이 좋습니다.
NULL 핸들링
PostgreSQL에서 NULL
데이터를 적절히 처리하는 것은 데이터 무결성과 쿼리 결과의 정확성을 보장하는 데 중요합니다. NULL
은 '값이 없음' 또는 '알 수 없음'을 나타내며, 이를 잘못 처리하면 예상치 못한 결과나 오류가 발생할 수 있습니다. 여기 PostgreSQL에서 NULL
을 처리하는 몇 가지 방법을 소개합니다.
1. IS NULL
과 IS NOT NULL
NULL
값을 검사하기 위해 IS NULL
과 IS NOT NULL
연산자를 사용할 수 있습니다. 이 연산자들은 특정 컬럼의 값이 NULL
인지 아닌지를 확인할 때 사용됩니다.
예시:
-- NULL 값이 있는 행을 찾기
SELECT * FROM employees WHERE commission IS NULL;
-- NULL 값이 아닌 행을 찾기
SELECT * FROM employees WHERE commission IS NOT NULL;
2. COALESCE
COALESCE
함수는 주어진 리스트에서 첫 번째 NULL
이 아닌 값을 반환합니다. 이 함수는 NULL
값을 기본값으로 대체할 때 유용합니다.
예시:
SELECT COALESCE(commission, 0) FROM employees;
위 쿼리는 commission
컬럼의 값이 NULL
인 경우 0을 반환합니다.
3. NULLIF
NULLIF
함수는 두 인자가 같으면 NULL
을 반환하고, 다르면 첫 번째 인자를 반환합니다. 이 함수는 특정 조건에서 NULL
값을 생성할 때 사용됩니다.
예시:
SELECT NULLIF(division, 'None') FROM employees;
이 예시에서 division
컬럼이 'None'과 같다면 NULL
을 반환하고, 다르면 division
의 값을 그대로 반환합니다.
4. CASE
문
CASE
문을 사용하여 NULL
조건을 처리할 수 있습니다. 이는 복잡한 조건에서 NULL
값을 다룰 때 유용합니다.
예시:
SELECT
CASE
WHEN commission IS NULL THEN 'No commission'
ELSE 'Has commission'
END
FROM employees;
이 쿼리는 commission
컬럼이 NULL
인 경우 'No commission'을 반환하고, 그렇지 않은 경우 'Has commission'을 반환합니다.
5. 집계 함수에서의 NULL 처리
PostgreSQL의 대부분의 집계 함수(SUM
, AVG
, COUNT
등)는 NULL
값을 자동으로 무시합니다. 그러나 COUNT(*)
는 NULL
값을 포함한 행의 총 수를 계산합니다.
예시:
SELECT AVG(commission) FROM employees; -- NULL은 무시하고 평균을 계산
이와 같은 방법을 통해 PostgreSQL에서 NULL
데이터를 효과적으로 관리하고, 데이터 분석과 처리 과정에서의 잠재적인 오류를 줄일 수 있습니다. 각 상황에 맞게 적절한 NULL
처리 방법을 선택하는 것이 중요합니다.
'Database Learning Guide' 카테고리의 다른 글
Oracle Flashback Technology (0) | 2024.11.19 |
---|---|
데이터베이스 트랜젝션(Transactoin) - ACID (Atomicity) (0) | 2024.11.19 |
인덱스(Index)란 무엇인가? (0) | 2023.09.19 |
데이터베이스 마이그레이션(Database Migration) (0) | 2023.06.27 |
아카이브 로그 백업(RMAN) (0) | 2023.05.23 |