본문 바로가기
개발 및 기타 등등/Database

PostgreSQL 기본 개념과 SQL에 대한 기본지식 파헤치기!

by 클수저 2026. 9. 2.
728x90
반응형

 

1. "SQL은 하나"라는 착각부터 깨기

SQL에는 ISO/IEC 9075라는 국제 표준이 있습니다.
그래서 SQL만 배우면 어느 DB든 통할 것 같지만, 실제 제품들은 각자 방언(dialect) 을 씁니다.

"상위 10건만 조회"라는 똑같은 요구사항이 제품마다 이렇게 갈립니다.

-- MySQL / MariaDB / PostgreSQL / SQLite
SELECT * FROM users LIMIT 10;

-- Oracle (12c 이상)
SELECT * FROM users FETCH FIRST 10 ROWS ONLY;

-- SQL Server
SELECT TOP 10 * FROM users;

그래서 학습을 시작하기 전에 내가 쓰는 DBMS를 확정하는 것이 첫 단계입니다. 그래야 볼 공식 문서가 정해집니다.

내 DBMS 판별하기

아래를 하나씩 실행해서, 성공하는 것 하나가 내가 쓰는 DBMS입니다.

SELECT VERSION();              -- 성공 → MySQL / MariaDB / PostgreSQL
SELECT * FROM v$version;       -- 성공 → Oracle
SELECT @@VERSION;              -- 성공 → SQL Server
SELECT sqlite_version();       -- 성공 → SQLite

SELECT VERSION()은 MySQL과 PostgreSQL 양쪽에서 다 동작하므로, 출력된 문자열 내용으로 구분합니다.

DBMS  출력형태
PostgreSQL PostgreSQL 16.x on x86_64-pc-linux-gnu, compiled by gcc...
MySQL 8.0.36 (버전 숫자만)

이 글의 나머지는 전부 PostgreSQL 기준입니다.

2. FROM 없는 SELECT : 첫 번째 방언 체험

위 판별 쿼리를 다시 보면 특이한 점이 있습니다. FROM 절이 없습니다.

SELECT 1 + 1;    -- PostgreSQL: 2

SQL 표준상 SELECT는 테이블 없이도 값을 계산해 반환할 수 있고, PostgreSQL · MySQL · SQL Server · SQLite는 이를 허용합니다. 반면 Oracle은 FROM 절을 필수로 요구합니다. 그래서 DUAL이라는 1행짜리 더미 테이블이 존재합니다.

-- Oracle에서는 이렇게 써야 한다
SELECT 1 + 1 FROM DUAL;

🔬 실험 1 :계산기로 써보기

FROM 없는 SELECT는 단순한 문법 잡학이 아니라, SQL 문법을 테이블 없이 실험하는 도구입니다.

SELECT 1 + 1                    AS 산술,
       'Post' || 'greSQL'       AS 문자열연결,
       upper('hello')           AS 대문자변환,
       length('안녕하세요')       AS 글자수,
       current_date             AS 오늘,
       10 > 3                   AS 비교결과;

실행 결과

 산술 | 문자열연결  | 대문자변환 | 글자수 |   오늘     | 비교결과
------+------------+-----------+--------+------------+----------
    2 | PostgreSQL | HELLO     |      5 | 2026-09-01 | t

여기서 두 가지를 얻습니다.

  1. ||가 문자열 연결 연산자입니다. 다른 언어의 +가 아닙니다. (SQL 표준)
  2. 10 > 3의 결과가 t(true)라는 값입니다. 비교는 boolean을 반환하는 연산이며, 이 사실이 나중에 WHERE를 이해하는 열쇠가 됩니다.

3. PostgreSQL의 킬러 기능 : 트랜잭션 DDL

실제 데이터가 든 DB에서 학습할 때 가장 무서운 건 되돌릴 수 없는 실수입니다.

DBeaver나 psql은 기본이 autocommit 켜짐 상태라, UPDATE나 DELETE를 그냥 실행하면 그 즉시 확정됩니다.
(Ctrl+Z는 없습니다.)

그래서 안전장치가 필요한데, 여기서 PostgreSQL의 중요한 특성이 등장합니다.

PostgreSQL은 DDL(CREATE / ALTER / DROP)도 트랜잭션으로 롤백됩니다. Oracle과 MySQL은 DDL 실행 시 암묵적으로 커밋되어 되돌릴 수 없습니다.

🔬 실험 2 : 테이블을 만들고 없던 일로 만들기

BEGIN;

CREATE TABLE test_rollback (id int);
INSERT INTO test_rollback VALUES (1), (2);

SELECT * FROM test_rollback;   -- ①

ROLLBACK;

SELECT * FROM test_rollback;   -- ②

① 실행 결과 : 정상적으로 2행이 보입니다.

 id
----
  1
  2

② 실행 결과 :  에러가 납니다.

ERROR:  relation "test_rollback" does not exist

이 에러 메시지가 핵심입니다. "테이블은 있는데 데이터만 없다"가 아니라 "테이블 자체가 존재하지 않는다" 고 나옵니다. CREATE TABLE이라는 DDL 자체가 되돌려졌다는 증거입니다.

🔬 실험 3 : 단어 하나만 바꿔보기

같은 코드에서 ROLLBACK을 COMMIT으로만 바꿔 실행해보세요.

BEGIN;
CREATE TABLE test_rollback (id int);
INSERT INTO test_rollback VALUES (1), (2);
COMMIT;                        -- ← ROLLBACK에서 COMMIT으로 변경

SELECT * FROM test_rollback;   -- 이번엔 1, 2가 그대로 조회된다

DROP TABLE test_rollback;      -- 실습 후 정리

같은 코드에서 마지막 한 단어만 바꿨는데 결과가 정반대입니다. 이것이 트랜잭션의 본질입니다.

💡 학습용 안전 패턴 이 시리즈의 모든 실험은 BEGIN ... ROLLBACK으로 감쌉니다. 실제 데이터가 든 DB에서도 흔적 없이 실험할 수 있습니다.

모든 것이 롤백되지는 않는다

다음 명령들은 트랜잭션 블록 안에서 실행 자체가 거부됩니다.

  • CREATE DATABASE
  • CREATE TABLESPACE
  • CREATE INDEX CONCURRENTLY
  • VACUUM

📖 근거: PostgreSQL 문서 → SQL Commands → 각 명령어 페이지의 Notes 항목

 

4. psql 메타명령어는 SQL이 아니다

PostgreSQL 학습 자료에서 자주 보는 이런 명령들이 있습니다.

\dt              -- 테이블 목록
\d 테이블명       -- 컬럼, 타입, 인덱스, 제약조건
\dn              -- 스키마 목록
\l               -- 데이터베이스 목록

역슬래시로 시작하는 이것들은 SQL이 아닙니다. psql이라는 클라이언트 프로그램의 기능입니다.

그래서 DBeaver, pgAdmin, 또는 애플리케이션 코드에서는 동작하지 않습니다. 어디서든 통하는 SQL 버전은 이렇습니다.

SELECT table_schema, table_name, table_type
FROM   information_schema.tables
WHERE  table_schema NOT IN ('pg_catalog', 'information_schema')
ORDER  BY table_schema, table_name;

🔬 실험 4 : WHERE 절의 존재 이유 체감하기

위 쿼리에서 WHERE 절을 지우고 실행해보세요.

조건 결과 행 수

조건 결과 행 수
WHERE 있음 내 테이블만 (수십~수백 건)
WHERE 없음 시스템 카탈로그 포함 (수백~수천 건)

pg_catalog와 information_schema는 PostgreSQL이 내부적으로 쓰는 시스템 스키마입니다. 이걸 걸러내지 않으면 내 테이블을 찾을 수 없습니다.

🔬 실험 5 : psql이 뒤에서 던지는 SQL 훔쳐보기

psql을 쓸 수 있는 환경이라면, 이 기능이 강력한 학습 도구가 됩니다.

\set ECHO_HIDDEN on
\dt

이렇게 하면 psql이 \dt를 처리하려고 내부적으로 실행하는 진짜 SQL이 화면에 출력됩니다.
pg_catalog.pg_class와 pg_namespace를 조인하는 쿼리가 나옵니다.

편리한 단축 명령어처럼 보였던 것이 결국 평범한 SELECT문이었다는 뜻입니다. 앞으로 "이건 어떻게 조회하지?" 싶을 때 이 기능이 정답지 역할을 합니다.

📖 근거: PostgreSQL 문서 → Reference → Client Applications → psql → Variables 항목

5. 정리

개념 요점

개념 요점
SQL 방언 표준은 있지만 제품마다 문법이 다르다. 내 DBMS를 먼저 확정할 것
FROM 없는 SELECT PostgreSQL은 허용, Oracle은 DUAL 필요. 문법 실험 도구로 활용 가능
|| 문자열 연결 연산자 (+ 아님)
비교 연산 boolean 을 반환하는 연산. WHERE 이해의 기초
트랜잭션 DDL PostgreSQL은 CREATE TABLE도 롤백된다. 학습 시 필수 안전장치
psql 메타명령 SQL이 아닌 클라이언트 기능. information_schema가 이식 가능한 대안

 

 

728x90
반응형