# PostgreSQL ์ค์ ๊ฐ์ด๋
## ํ์ต ๋ชฉํ
๊ฐ๋ ฅํ ์คํ์์ค ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค PostgreSQL์ ๋ง์คํฐํฉ๋๋ค.
## 1. PostgreSQL์ด๋?
๊ฐ์ฅ ์ง๋ณด๋ ์คํ์์ค ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์
๋๋ค.
- ACID ์๋ฒฝ ์ง์
- JSON/JSONB ๋ค์ดํฐ๋ธ ์ง์
- ๊ฐ๋ ฅํ ํ์ฅ์ฑ
- ํ๋ถํ ๋ฐ์ดํฐ ํ์
## 2. ์ค์น ๋ฐ ์ ์
Docker:
docker run -d -p 5432:5432 -e POSTGRES_PASSWORD=password postgres
์ ์:
psql -U postgres -h localhost
psql -d mydb -U myuser
๊ธฐ๋ณธ ๋ช
๋ น:
\l - ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ชฉ๋ก
\c mydb - ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ํ
\dt - ํ
์ด๋ธ ๋ชฉ๋ก
\d users - ํ
์ด๋ธ ๊ตฌ์กฐ
\q - ์ข
๋ฃ
## 3. ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ด๋ฆฌ
CREATE DATABASE mydb;
DROP DATABASE mydb;
CREATE USER myuser WITH PASSWORD "password";
GRANT ALL PRIVILEGES ON DATABASE mydb TO myuser;
## 4. ํ
์ด๋ธ ์์ฑ
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(255) UNIQUE,
age INTEGER CHECK (age >= 0),
balance DECIMAL(10,2) DEFAULT 0,
metadata JSONB,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE posts (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
title VARCHAR(255) NOT NULL,
content TEXT,
tags TEXT[],
published_at TIMESTAMP
);
## 5. ๊ธฐ๋ณธ CRUD
INSERT:
INSERT INTO users (name, email, age) VALUES ("Kim", "kim@test.com", 25);
INSERT INTO users (name, email) VALUES ("Lee", "lee@test.com") RETURNING id;
SELECT:
SELECT * FROM users;
SELECT name, email FROM users WHERE age >= 20;
SELECT * FROM users ORDER BY created_at DESC LIMIT 10 OFFSET 20;
UPDATE:
UPDATE users SET age = 26 WHERE name = "Kim";
UPDATE users SET age = age + 1 RETURNING *;
DELETE:
DELETE FROM users WHERE id = 1;
## 6. JSON/JSONB ํ์ฉ
์ ์ฅ:
INSERT INTO users (name, metadata) VALUES ("Kim",
{"address": {"city": "Seoul"}, "tags": ["vip", "premium"]}
);
์กฐํ:
SELECT metadata->"address"->"city" FROM users;
SELECT metadata->>"address" FROM users;
SELECT * FROM users WHERE metadata @> {"tags": ["vip"]};
SELECT * FROM users WHERE metadata ? "address";
์์ :
UPDATE users SET metadata = jsonb_set(metadata, "{address,zip}", "12345");
## 7. ๋ฐฐ์ด ํ์
์ ์ฅ:
INSERT INTO posts (title, tags) VALUES ("Hello", ARRAY["tech", "news"]);
์กฐํ:
SELECT * FROM posts WHERE "tech" = ANY(tags);
SELECT * FROM posts WHERE tags @> ARRAY["tech"];
SELECT unnest(tags) FROM posts;
## 8. ์ธ๋ฑ์ค
๊ธฐ๋ณธ ์ธ๋ฑ์ค:
CREATE INDEX idx_users_email ON users(email);
CREATE UNIQUE INDEX idx_users_email_unique ON users(email);
๋ณตํฉ ์ธ๋ฑ์ค:
CREATE INDEX idx_posts_user_date ON posts(user_id, published_at DESC);
JSONB ์ธ๋ฑ์ค:
CREATE INDEX idx_users_metadata ON users USING GIN(metadata);
๋ถ๋ถ ์ธ๋ฑ์ค:
CREATE INDEX idx_active_users ON users(email) WHERE active = true;
## 9. JOIN
INNER JOIN:
SELECT u.name, p.title FROM users u INNER JOIN posts p ON u.id = p.user_id;
LEFT JOIN:
SELECT u.name, COUNT(p.id) FROM users u LEFT JOIN posts p ON u.id = p.user_id GROUP BY u.id;
## 10. CTE์ ์๋์ฐ ํจ์
CTE:
WITH active_users AS (
SELECT * FROM users WHERE last_login > NOW() - INTERVAL "30 days"
)
SELECT * FROM active_users WHERE age > 20;
์๋์ฐ ํจ์:
SELECT name, age, RANK() OVER (ORDER BY age DESC) FROM users;
SELECT name, age, AVG(age) OVER () as avg_age FROM users;
SELECT name, created_at, LAG(created_at) OVER (ORDER BY created_at) as prev FROM users;
## 11. ํธ๋์ญ์
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;
-- ์๋ฌ ์
ROLLBACK;
๊ฒฉ๋ฆฌ ์์ค:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
## 12. ๋ฐฑ์
๋ฐ ๋ณต์
๋ฐฑ์
:
pg_dump -U postgres mydb > backup.sql
pg_dump -U postgres -Fc mydb > backup.dump
๋ณต์:
psql -U postgres mydb < backup.sql
pg_restore -U postgres -d mydb backup.dump
## ์ถ์ฒ ํ์ต ์์
1. ๊ธฐ๋ณธ SQL ๋ฌธ๋ฒ
2. JSON/๋ฐฐ์ด ํ์
ํ์ฉ
3. ์ธ๋ฑ์ค ์ ๋ต
4. ์๋์ฐ ํจ์
5. ์ฑ๋ฅ ์ต์ ํ