
๐ PostgreSQL์ด๋?
PostgreSQL์ ๋ฐ์ดํฐ๋ฅผ ์์ ํ๊ฒ ์ ์ฅํ๊ณ ๊บผ๋ด ์ฐ๊ฒ ํด์ฃผ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค(DB)์
๋๋ค.
ํ์ง๋ง ๋จ์ํ ๋ฐ์ดํฐ๋ฅผ ๋ฃ๊ณ ๋นผ๋ ์์ค์ ๋์ด, ๋ณต์กํ ๋ฐ์ดํฐ๊น์ง ๋๋ํ๊ฒ ๋ค๋ฃฐ ์ ์๋ ๊ณ ๊ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ผ๊ณ ๋ณผ ์ ์์ต๋๋ค.
์ฆ, PostgreSQL์ ์ผ๋ฐ์ ์ธ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค(RDBMS) ๊ฐ ๊ฐ์ง ๊ธฐ๋ฅ์ ๋ชจ๋ ์ ๊ณตํ๋ฉด์๋,
๊ทธ ์ด์์ผ๋ก ๋ ๋ค์ํ ๊ธฐ๋ฅ๊ณผ ํ์ฅ์ฑ์ ์ง์ํฉ๋๋ค.
โ PostgreSQL์ ํน์ง
1. ๋ ๋ค์ํ ๋ฐ์ดํฐ ํ์ ์ง์
์ผ๋ฐ์ ์ธ RDBMS(MySQL ๋ฑ)๋ INT, VARCHAR, DATE ๊ฐ์ ๊ธฐ๋ณธ ํ์
์์ฃผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํฉ๋๋ค.
๋ฐ๋ฉด PostgreSQL์ ํจ์ฌ ๋ค์ํ ํ์
์ ๊ธฐ๋ณธ์ผ๋ก ์ง์ํฉ๋๋ค.
- JSON / JSONB → JSON ๋ฐ์ดํฐ๋ฅผ ํจ์จ์ ์ผ๋ก ์ ์ฅํ๊ณ ๊ฒ์
- ARRAY → ๋ฐฐ์ด ํํ ๋ฐ์ดํฐ ์ ์ฅ ๊ฐ๋ฅ
- UUID → ๊ณ ์ ์๋ณ์ ์ ์ฅ์ฉ ํ์
- RANGE → ๋ฒ์(์: 1~10, ๋ ์ง ๊ตฌ๊ฐ) ํ์
- HSTORE → Key-Value ํํ ๋ฐ์ดํฐ ์ ์ฅ
๐ ์ฆ, PostgreSQL์ ๋จ์ํ ํ ์ด๋ธ ๊ตฌ์กฐ๋ฟ ์๋๋ผ, ๋ฐ์ ํ/๋น์ ํ ๋ฐ์ดํฐ๊น์ง ์ฝ๊ฒ ๋ค๋ฃฐ ์ ์๋ ์ฅ์ ์ด ์์ต๋๋ค.
2. ์์ ์ฑ๊ณผ ์ ๋ขฐ์ฑ (ACID ๋ณด์ฅ)
PostgreSQL์ ํธ๋์ญ์
์์ ์ฑ์ ์๊ฒฉํ ๋ณด์ฅํฉ๋๋ค.
์ํ ์ด์ฒด ๊ฐ์ ์์
์์ “์ค๊ฐ์ ์คํจํ๋ฉด ์๋์ผ๋ก ์ทจ์(ROLLBACK)”๋๋ ๊ตฌ์กฐ๋ผ, ๋ฐ์ดํฐ ์ ํฉ์ฑ์ด ๋งค์ฐ ๋์ต๋๋ค.
3. ๋์์ฑ ์ฒ๋ฆฌ (MVCC)
์ฌ๋ฌ ์ฌ์ฉ์๊ฐ ๋์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ณ ์ฐ๋ ์ํฉ์์๋ ์ถฉ๋์ด ์ต์ํ๋ฉ๋๋ค.
์ด๋ PostgreSQL์ MVCC(Multi-Version Concurrency Control) ๋๋ถ์ธ๋ฐ,
์ฝ๋ ์ฟผ๋ฆฌ๋ ์ ๊ธ(Lock) ์์ด ์งํ๋์ด ์ฝ๊ธฐ ์ฑ๋ฅ์ด ๋ฐ์ด๋ฉ๋๋ค.
MySQL(InnoDB)์์์ MVCC
- InnoDB๋ Undo Log(Undo ์์ญ) ๋ฅผ ์ด์ฉํด MVCC๋ฅผ ๊ตฌํํฉ๋๋ค.
- ์ฆ, ๋ฐ์ดํฐ๋ฅผ ์์ ํ ๋ ์๋ณธ ๊ฐ์ Undo ์์ญ์ ๊ธฐ๋กํด ๋๊ณ , ๋ค๋ฅธ ํธ๋์ญ์ ์ด ๊ณผ๊ฑฐ ๋ฐ์ดํฐ๋ฅผ ํ์๋ก ํ๋ฉด Undo Log๋ฅผ ์ฐธ์กฐํฉ๋๋ค.
- ์ฃผ์ ํน์ง
- ์ฝ๊ธฐ(SELECT) ๋ Undo Log๋ฅผ ์ฐธ์กฐ → REPEATABLE READ ์์ค์์ ๋์ผํ ์ค๋ ์ท ๋ณด์ฅ
- ์ฐ๊ธฐ(UPDATE, DELETE) ๋ ๋ ์ฝ๋์ ์ ๊ธ(Lock) ์ ๊ฑธ์ด์ผ ํจ
- ๋ฐ๋ผ์ ์ฝ๊ธฐ์ ์ฐ๊ธฐ๋ ๋์์ ๊ฐ๋ฅํ์ง๋ง, ์ถฉ๋ ๊ฐ๋ฅ์ฑ์ ์ฌ์ ํ ์กด์ฌ
PostgreSQL์์์ MVCC
- PostgreSQL์ ๊ฐ ํ(Row)์ ๋ฒ์ ์ ๋ณด(xmin/xmax) ๋ฅผ ์ ์ฅํฉ๋๋ค.
- ๋ฐ์ดํฐ๋ฅผ ์ ๋ฐ์ดํธํ๋ฉด → ๊ธฐ์กด ํ์ ์ง์ฐ์ง ์๊ณ ์ ๋ฒ์ ์ ํ์ ์ถ๊ฐํฉ๋๋ค.
- ํธ๋์ญ์ ์ ์์ ์ด ์์ํ ์์ ์ ์ ํจํ ๋ฒ์ ๋ง ๋ณด๊ฒ ๋ฉ๋๋ค.
- ์ฃผ์ ํน์ง
- Undo ์์ญ์ด ์๋๋ผ ํ ์ด๋ธ ์์ฒด์์ ๋ฒ์ ๊ด๋ฆฌ
- SELECT๋ ์ ๋ Lock์ ๊ฑธ์ง ์์ → ์ฝ๊ธฐ ์ฑ๋ฅ์ด ๋งค์ฐ ๋ฐ์ด๋จ
- ๋จ์ : ์ค๋๋ ๋ฒ์ ์ด ๊ณ์ ์์ด๋ฏ๋ก VACUUM(์ฒญ์ ์์ ) ํ์
4. ๊ณ ๊ธ SQL ๊ธฐ๋ฅ
- Window ํจ์: ์์ ๋งค๊ธฐ๊ธฐ, ๋์ ํฉ๊ณ, ์ด๋ ํ๊ท ๋ฑ
- CTE (WITH ๊ตฌ๋ฌธ): ๋ณต์กํ ์ฟผ๋ฆฌ๋ฅผ ๋ณด๊ธฐ ์ข๊ฒ ๋ถ๋ฆฌ
- JSON ์ฟผ๋ฆฌ: JSON ๋ฐ์ดํฐ๋ฅผ SQL๋ก ์ง์ ๊ฒ์
๐ ๋๋ถ์ ๋จ์ ์ ์ฅ์๊ฐ ์๋๋ผ, ๋ฐ์ดํฐ ๋ถ์·์ง๊ณ๊น์ง PostgreSQL์์ ๊ฐ๋ฅํด์ง๋๋ค.
๐ PostgreSQL ๊ฐ๋จ ์ค์ต
1๏ธโฃ ํ๊ฒฝ ์ค๋นํ๊ธฐ
๊ฐ์ฅ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ Docker๋ฅผ ์ด์ฉํ๋ ๊ฒ์ ๋๋ค.
docker run --name pg-test -e POSTGRES_PASSWORD=pass -p 5432:5432 -d postgres
๐ ์คํ ํ, localhost:5432 ํฌํธ์ PostgreSQL์ด ์คํ๋ฉ๋๋ค.
๐ ๊ธฐ๋ณธ ๊ณ์ : postgres / ๋น๋ฐ๋ฒํธ: pass
2๏ธโฃ PostgreSQL ์ ์ํ๊ธฐ
์ปจํ ์ด๋ ์์์ ๋ฐ๋ก psql์ ์คํํด๋ด ๋๋ค.
docker exec -it pg-test psql -U postgres
๐ ์ ์ ์ ์๋๋ฉด ์๋์ ๊ฐ์ ํ๋กฌํํธ๊ฐ ๋น๋๋ค.

3๏ธโฃ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฌ์ฉ์ ์์ฑ
CREATE DATABASE test_db;
CREATE USER test_user WITH PASSWORD 'testpass';
GRANT ALL PRIVILEGES ON DATABASE test_db TO test_user;
๐ ์ด์ ์์ผ๋ก๋ test_user ๊ณ์ ์ผ๋ก test_db๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
4๏ธโฃ ํ ์ด๋ธ ๋ง๋ค๊ณ CRUD ์ค์ต
ํ ์ด๋ธ ์์ฑ
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(100) UNIQUE,
created_at TIMESTAMP DEFAULT NOW()
);
๋ฐ์ดํฐ ์ฝ์
INSERT INTO users (name, email) VALUES ('ํ๊ธธ๋', 'hong@test.com');
INSERT INTO users (name, email) VALUES ('๊ฐ๊ฐ์ฐฌ', 'kang@test.com');
๋ฐ์ดํฐ ์กฐํ
SELECT * FROM users;
๐ ์๋์ฒ๋ผ ๊ฒฐ๊ณผ๊ฐ ๋์ต๋๋ค.

๋ฐ์ดํฐ ์์ /์ญ์
UPDATE users SET name = '์ด์์ ' WHERE id = 1;
DELETE FROM users WHERE id = 2;
5๏ธโฃ PostgreSQL๋ง์ ํน์ง – JSONB ์ค์ต
PostgreSQL์ JSON ๋ฐ์ดํฐ๋ฅผ ํจ์จ์ ์ผ๋ก ๋ค๋ฃฐ ์ ์๋ JSONB ํ์ ์ ์ง์ํฉ๋๋ค.
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
details JSONB
);
INSERT INTO products (name, details)
VALUES ('๋
ธํธ๋ถ', '{"brand":"Apple","spec":{"cpu":"M1","ram":"16GB"}}');
SELECT name, details->'spec'->>'cpu' AS cpu_spec
FROM products;
๐ ๊ฒฐ๊ณผ

6๏ธโฃ ๋ทฐ(View) ๋ง๋ค๊ธฐ
์์ฃผ ์ฐ๋ ์ฟผ๋ฆฌ๋ฅผ ๋ทฐ(View)๋ก ์ ์ฅํ ์ ์์ต๋๋ค.
CREATE VIEW recent_users AS
SELECT id, name, email, created_at
FROM users
ORDER BY created_at DESC
LIMIT 5;
SELECT * FROM recent_users;
๐ ํ ์ด๋ธ์ฒ๋ผ recent_users์์ ๋ฐ์ดํฐ๋ฅผ ์กฐํํ ์ ์์ต๋๋ค.

7๏ธโฃ ํธ๋์ญ์ ์ฒดํ
ํธ๋์ญ์ ์ ๋ฐ์ดํฐ ์ ํฉ์ฑ์ ๋ณด์ฅํ๋ ํต์ฌ ๊ธฐ๋ฅ์ ๋๋ค.
BEGIN;
UPDATE users SET name = '์ธ์ข
๋์' WHERE id = 1;
-- ์ทจ์ํ๊ณ ์ถ์ ๋
ROLLBACK;
-- ํ์ ํ๊ณ ์ถ์ ๋
COMMIT;
๐ฅ DBeaver๋ก PostgreSQL ์ ์ํ๊ธฐ
CLI(psql) ํ๊ฒฝ๋ ์ข์ง๋ง, GUI ํด์ ์ฐ๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ตฌ์กฐ์ ๋ฐ์ดํฐ๋ฅผ ์ง๊ด์ ์ผ๋ก ํ์ธํ ์ ์์ต๋๋ค.
์ฌ๊ธฐ์๋ ๋ง์ด ์ฌ์ฉํ๋ ๋ฌด๋ฃ ํด์ธ DBeaver๋ฅผ ์ด์ฉํด PostgreSQL์ ์ฐ๊ฒฐํด๋ณด๊ฒ ์ต๋๋ค.
1๏ธโฃ DBeaver ์ค์น
- DBeaver ๊ณต์ ์ฌ์ดํธ์์ ๋ค์ด๋ก๋ ๋ฐ ์ค์น
- Mac, Windows, Linux ๋ชจ๋ ์ง์
2๏ธโฃ ์๋ก์ด ์ฐ๊ฒฐ ๋ง๋ค๊ธฐ
1. ์๋จ ๋ฉ๋ด์์ Database > New Database Connection ํด๋ฆญ
2. ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ชฉ๋ก์์ PostgreSQL ์ ํ

3. ์ฐ๊ฒฐ ์ ๋ณด ์ ๋ ฅ
- Host: localhost
- Port: 5432
- Database: postgres
- User: test_user
- Password: testpass

๐ “Test Connection” ๋ฒํผ ํด๋ฆญ → ์ฑ๊ณต ๋ฉ์์ง๊ฐ ๋จ๋ฉด Finish

3๏ธโฃ ๋ฐ์ดํฐ ํ์ธํ๊ธฐ
- ์ข์ธก ํจ๋์ test_db๊ฐ ๋ํ๋ฉ๋๋ค. (public ํ์์์ ํ์ธํ ์ ์์)

- users ํ ์ด๋ธ์ ๋๋ธํด๋ฆญ → Data ํญ์์ GUI๋ก ๋ฐ์ดํฐ ํ์ธ ๊ฐ๋ฅ
- SQL Editor์์ ์ง์ ์ฟผ๋ฆฌ๋ฅผ ์คํํ ์๋ ์์ต๋๋ค.

4๏ธโฃ JSONB ๋ฐ์ดํฐ๋ ์ฝ๊ฒ
์์ ๋ง๋ products ํ ์ด๋ธ๋ ํ์ธํด๋ด ์๋ค.
- JSON ์ปฌ๋ผ์ DBeaver์์ ๊ณ์ธต ๊ตฌ์กฐ(Tree) ๋ก ํ์ธํ ์ ์์ด ๊ฐ๋ ์ฑ์ด ์ข์ต๋๋ค.
- PostgreSQL์ ์ฅ์ ์ธ JSONB ์ฟผ๋ฆฌ๋ GUI์์ ์คํ ๊ฐ๋ฅ
๐ ๋ง๋ฌด๋ฆฌ
- PostgreSQL์ ๊ด๊ณํ DB์ ์์ ์ฑ + NoSQL์ ์ ์ฐ์ฑ์ ๋์์ ์ ๊ณต
- Docker๋ก ์์ฝ๊ฒ ํ๊ฒฝ ๊ตฌ์ฑ ๊ฐ๋ฅ
- CRUD, JSONB, View, ํธ๋์ญ์ ๋ฑ ๊ธฐ๋ณธ ๊ธฐ๋ฅ์ ์ค์ตํ๋ฉฐ ํน์ง์ ์ฒด๊ฐํ ์ ์์
- DBeaver ๊ฐ์ GUI ํด์ ์ด์ฉํ๋ฉด ๋์ฑ ํธ๋ฆฌํ๊ฒ ํ์ต ๊ฐ๋ฅ