PostgreSQL 교재 · 5편 / 24편

INSERT·SELECT·UPDATE·DELETE — 첫 CRUD

데이터를 넣고·읽고·바꾸고·지우는 4종 + UPDATE/DELETE 의 한 가지 안전 규칙.

입문읽는 시간 7분2026-05-17
INSERT/SELECT/UPDATE/DELETE 4개의 SQL 키워드가 색상으로 강조된 일러스트

SQL 의 90% 는 4가지 동사로 끝납니다 — INSERT(넣기)·SELECT(읽기)·UPDATE(바꾸기)·DELETE(지우기). 합쳐서 CRUD(Create·Read·Update·Delete). 5편은 입문 파트의 마지막으로, 이 4가지를 한 화면에 익힙니다.

실습 테이블은 3편의 users 를 그대로 씁니다.

CREATE TABLE users (
  id     BIGSERIAL PRIMARY KEY,
  name   TEXT NOT NULL,
  email  TEXT UNIQUE,
  age    INTEGER CHECK (age >= 0),
  active BOOLEAN NOT NULL DEFAULT TRUE,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

INSERT — 데이터 넣기

-- 한 행
INSERT INTO users (name, email, age)
VALUES ('준성', '[email protected]', 39);

-- 여러 행 (한 번에)
INSERT INTO users (name, email, age) VALUES
  ('홍길동', '[email protected]',  30),
  ('김자바', '[email protected]',   25),
  ('박파이', '[email protected]',  45);

-- 결과 받아오기 (INSERT ... RETURNING)
INSERT INTO users (name, email, age)
VALUES ('이타입', '[email protected]', 28)
RETURNING id, created_at;
--  id |          created_at
-- ----+-------------------------------
--   5 | 2026-05-17 00:25:00.123+09

RETURNING 의 가치. 방금 만든 행의 자동 생성된 PK(id), 시각(created_at) 을 즉시 받습니다. 애플리케이션 코드에서 "INSERT 한 다음 다시 SELECT" 같은 두 번 왕복을 한 번으로 줄입니다. UPDATE·DELETE 에도 동일하게 붙일 수 있어요.

SELECT — 데이터 읽기

-- 전부 (작을 때만, 보통은 컬럼 지정 권장)
SELECT * FROM users;

-- 컬럼 지정 + 별칭
SELECT id AS user_id, name, age
FROM   users;

-- WHERE 조건
SELECT name, email
FROM   users
WHERE  active = true AND age >= 30;

-- 정렬·갯수 제한
SELECT name, age FROM users
WHERE  active
ORDER BY age DESC
LIMIT 5;

-- 함수·표현식
SELECT name,
       age + 1                   AS next_age,
       upper(email)              AS email_upper,
       extract(year from created_at) AS year_joined
FROM users;

SELECT * 는 학습·디버그용으로만, 운영 코드에서는 거의 항상 컬럼 명시. 이유: 스키마가 바뀌어도 코드가 영향 안 받고, 네트워크/메모리도 아낍니다. WHERE·ORDER BY·LIMIT 의 본격적인 사용법은 6·7편에서.

UPDATE — 데이터 바꾸기

-- 한 행
UPDATE users
SET    age = 40
WHERE  id = 1;

-- 여러 컬럼
UPDATE users
SET    age = age + 1,
       active = true
WHERE  email = '[email protected]';

-- 표현식
UPDATE users
SET    name = upper(name)
WHERE  active;

-- RETURNING 으로 변경 결과 확인
UPDATE users
SET    age = age + 1
WHERE  id = 1
RETURNING id, name, age;

DELETE — 데이터 지우기

-- 한 행
DELETE FROM users WHERE id = 5;

-- 조건에 맞는 모두
DELETE FROM users WHERE active = false AND created_at < NOW() - INTERVAL '1 year';

-- 전부 (조심!)
DELETE FROM users;
TRUNCATE users;       -- 더 빠름, 시퀀스도 리셋(RESTART IDENTITY 옵션)

UPDATE/DELETE 의 단 하나의 안전 규칙

"UPDATE / DELETE 를 칠 때 먼저 같은 WHERE 로 SELECT 를 친다."

운영 DB 에서 가장 흔한 사고가 WHERE 를 빼먹은 UPDATE/DELETE입니다. 한 행을 바꾸려다 100만 행을 날립니다. 다음 두 줄 패턴을 몸에 새기세요.

-- 1단계: 영향 받을 행을 먼저 확인
SELECT id, name, email FROM users WHERE id = 5;
-- 결과 1건 → 의도와 맞음 확인

-- 2단계: 같은 WHERE 로 실제 변경
DELETE FROM users WHERE id = 5;

또 하나의 안전망: 작업 전에 트랜잭션을 열어두기.

BEGIN;
DELETE FROM users WHERE active = false;
-- 영향 행 수 출력됨: 예) DELETE 7
-- 잘못 됐으면:
ROLLBACK;
-- 맞으면:
COMMIT;

트랜잭션은 14편에서 깊게 다룹니다. 입문 단계에서도 "운영 DB 에선 무조건 BEGIN/COMMIT 사이에" 라는 습관만 들이세요.

실전 패턴 — UPSERT 한 줄

-- "있으면 업데이트, 없으면 삽입" — PostgreSQL 정통 방식
INSERT INTO users (id, name, email, age)
VALUES (1, '준성', '[email protected]', 39)
ON CONFLICT (id) DO UPDATE
  SET name  = EXCLUDED.name,
      email = EXCLUDED.email,
      age   = EXCLUDED.age;

ON CONFLICT 는 충돌(PK/UNIQUE) 시 동작을 정합니다. DO NOTHING 으로 무시도 가능. 실무에서 동기화·재시도에 매우 자주 쓰는 패턴이에요.

6편 — WHERE 절 전문가 (기초 시작)

비교·BETWEEN·IN·LIKE·NULL — 조건 표현의 정석과 NULL 3값 논리의 함정.

📚 PostgreSQL 배우기 교재
이전: 4편 데이터 타입 · 현재: 5편 (입문 마지막) · 다음 → 6편 WHERE (SQL 기초 시작) · 진행: 5/24

© 2026 주나이테크(주) @JUNAITECH