CRUD ๊ธฐ๋ณธ

CRUD ๊ธฐ๋ณธ

CRUD๋Š” Create(์ƒ์„ฑ), Read(์ฝ๊ธฐ), Update(์ˆ˜์ •), Delete(์‚ญ์ œ)์˜ ์•ฝ์ž๋กœ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๊ธฐ๋ณธ ์ž‘์—…์ž…๋‹ˆ๋‹ค.

0. ์‹ค์Šต ์ค€๋น„

-- ์‹ค์Šต์šฉ ํ…Œ์ด๋ธ” ์ƒ์„ฑ
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(255) UNIQUE NOT NULL,
    age INTEGER,
    city VARCHAR(100),
    created_at TIMESTAMP DEFAULT NOW()
);

1. INSERT - ๋ฐ์ดํ„ฐ ์‚ฝ์ž…

๋‹จ์ผ ํ–‰ ์‚ฝ์ž…

-- ๋ชจ๋“  ์ปฌ๋Ÿผ ์ง€์ •
INSERT INTO users (name, email, age, city)
VALUES ('๊น€์ฒ ์ˆ˜', 'kim@email.com', 30, '์„œ์šธ');

-- ์ผ๋ถ€ ์ปฌ๋Ÿผ๋งŒ ์ง€์ • (๋‚˜๋จธ์ง€๋Š” DEFAULT ๋˜๋Š” NULL)
INSERT INTO users (name, email)
VALUES ('์ด์˜ํฌ', 'lee@email.com');

๋‹ค์ค‘ ํ–‰ ์‚ฝ์ž…

INSERT INTO users (name, email, age, city) VALUES
('๋ฐ•๋ฏผ์ˆ˜', 'park@email.com', 25, '๋ถ€์‚ฐ'),
('์ตœ์ง€์˜', 'choi@email.com', 28, '๋Œ€์ „'),
('์ •์ˆ˜์ง„', 'jung@email.com', 35, '์„œ์šธ');

DEFAULT ๊ฐ’ ์‚ฌ์šฉ

-- ํŠน์ • ์ปฌ๋Ÿผ์— DEFAULT ์‚ฌ์šฉ
INSERT INTO users (name, email, age, city, created_at)
VALUES ('ํ™๊ธธ๋™', 'hong@email.com', 40, '์ธ์ฒœ', DEFAULT);

-- ๋ชจ๋“  ์ปฌ๋Ÿผ DEFAULT (id๋งŒ ์ž๋™ ์ƒ์„ฑ)
INSERT INTO users DEFAULT VALUES;  -- ์—๋Ÿฌ: NOT NULL ์ปฌ๋Ÿผ ๋•Œ๋ฌธ

RETURNING - ์‚ฝ์ž…๋œ ๋ฐ์ดํ„ฐ ๋ฐ˜ํ™˜

-- ์‚ฝ์ž… ํ›„ ์ƒ์„ฑ๋œ ID ๋ฐ˜ํ™˜
INSERT INTO users (name, email, age, city)
VALUES ('์‹ ์งฑ๊ตฌ', 'shin@email.com', 5, '๋–ก์žŽ๋งˆ์„')
RETURNING id;

-- ์—ฌ๋Ÿฌ ์ปฌ๋Ÿผ ๋ฐ˜ํ™˜
INSERT INTO users (name, email, age, city)
VALUES ('๊น€๋ฏธ์˜', 'mikim@email.com', 32, '์„œ์šธ')
RETURNING id, name, created_at;

-- ๋ชจ๋“  ์ปฌ๋Ÿผ ๋ฐ˜ํ™˜
INSERT INTO users (name, email)
VALUES ('ํ…Œ์ŠคํŠธ', 'test@email.com')
RETURNING *;

2. SELECT - ๋ฐ์ดํ„ฐ ์กฐํšŒ

๋ชจ๋“  ๋ฐ์ดํ„ฐ ์กฐํšŒ

-- ๋ชจ๋“  ์ปฌ๋Ÿผ
SELECT * FROM users;

-- ํŠน์ • ์ปฌ๋Ÿผ๋งŒ
SELECT name, email FROM users;

์ปฌ๋Ÿผ ๋ณ„์นญ (Alias)

SELECT
    name AS ์ด๋ฆ„,
    email AS ์ด๋ฉ”์ผ,
    age AS ๋‚˜์ด
FROM users;

-- AS ์ƒ๋žต ๊ฐ€๋Šฅ
SELECT name ์ด๋ฆ„, email ์ด๋ฉ”์ผ FROM users;

์ค‘๋ณต ์ œ๊ฑฐ (DISTINCT)

-- ์ค‘๋ณต ๋„์‹œ ์ œ๊ฑฐ
SELECT DISTINCT city FROM users;

-- ์—ฌ๋Ÿฌ ์ปฌ๋Ÿผ ์กฐํ•ฉ์˜ ์ค‘๋ณต ์ œ๊ฑฐ
SELECT DISTINCT city, age FROM users;

๊ณ„์‚ฐ ๋ฐ ํ‘œํ˜„์‹

-- ๊ณ„์‚ฐ
SELECT name, age, age + 10 AS age_after_10_years FROM users;

-- ๋ฌธ์ž์—ด ์—ฐ๊ฒฐ
SELECT name || ' (' || email || ')' AS user_info FROM users;

-- CONCAT ํ•จ์ˆ˜
SELECT CONCAT(name, ' - ', city) AS name_city FROM users;

์กฐ๊ฑด ์กฐํšŒ (๊ฐ„๋‹จํžˆ)

-- WHERE ์ ˆ (์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋‹ค์Œ ์žฅ)
SELECT * FROM users WHERE city = '์„œ์šธ';
SELECT * FROM users WHERE age >= 30;

3. UPDATE - ๋ฐ์ดํ„ฐ ์ˆ˜์ •

๊ธฐ๋ณธ UPDATE

-- ํŠน์ • ํ–‰ ์ˆ˜์ •
UPDATE users
SET age = 31
WHERE name = '๊น€์ฒ ์ˆ˜';

-- ์—ฌ๋Ÿฌ ์ปฌ๋Ÿผ ์ˆ˜์ •
UPDATE users
SET age = 26, city = '๋Œ€๊ตฌ'
WHERE email = 'park@email.com';

์กฐ๊ฑด ์—†๋Š” UPDATE (์ฃผ์˜!)

-- ๋ชจ๋“  ํ–‰์ด ์ˆ˜์ •๋จ!
UPDATE users SET city = '์„œ์šธ';  -- ์œ„ํ—˜!

-- ํ•ญ์ƒ WHERE ์ ˆ ํ™•์ธ

๊ณ„์‚ฐ์„ ์ด์šฉํ•œ UPDATE

-- ๋ชจ๋“  ์‚ฌ์šฉ์ž ๋‚˜์ด 1 ์ฆ๊ฐ€
UPDATE users SET age = age + 1;

-- ํŠน์ • ์กฐ๊ฑด ์‚ฌ์šฉ์ž๋งŒ
UPDATE users SET age = age + 1 WHERE city = '์„œ์šธ';

RETURNING์œผ๋กœ ์ˆ˜์ •๋œ ๋ฐ์ดํ„ฐ ํ™•์ธ

UPDATE users
SET age = 32
WHERE name = '์ด์˜ํฌ'
RETURNING *;

UPDATE users
SET city = '๊ด‘์ฃผ'
WHERE age < 30
RETURNING id, name, city;

NULL๋กœ ์„ค์ •

UPDATE users
SET city = NULL
WHERE name = 'ํ…Œ์ŠคํŠธ';

4. DELETE - ๋ฐ์ดํ„ฐ ์‚ญ์ œ

๊ธฐ๋ณธ DELETE

-- ํŠน์ • ํ–‰ ์‚ญ์ œ
DELETE FROM users WHERE name = 'ํ…Œ์ŠคํŠธ';

-- ์—ฌ๋Ÿฌ ์กฐ๊ฑด
DELETE FROM users WHERE city IS NULL AND age IS NULL;

์กฐ๊ฑด ์—†๋Š” DELETE (์ฃผ์˜!)

-- ๋ชจ๋“  ๋ฐ์ดํ„ฐ ์‚ญ์ œ!
DELETE FROM users;  -- ์œ„ํ—˜!

-- ํ…Œ์ด๋ธ”์€ ๋‚จ์•„์žˆ์Œ

RETURNING์œผ๋กœ ์‚ญ์ œ๋œ ๋ฐ์ดํ„ฐ ํ™•์ธ

DELETE FROM users
WHERE email = 'test@email.com'
RETURNING *;

TRUNCATE - ํ…Œ์ด๋ธ” ๋น„์šฐ๊ธฐ

-- DELETE๋ณด๋‹ค ๋น ๋ฆ„ (๋กœ๊ทธ ์—†์ด ์ „์ฒด ์‚ญ์ œ)
TRUNCATE TABLE users;

-- SERIAL ์žฌ์‹œ์ž‘
TRUNCATE TABLE users RESTART IDENTITY;

-- ๊ด€๋ จ ํ…Œ์ด๋ธ”๋„ ํ•จ๊ป˜ (์™ธ๋ž˜ํ‚ค)
TRUNCATE TABLE users CASCADE;

DELETE vs TRUNCATE

ํŠน์ง• DELETE TRUNCATE
WHERE ์กฐ๊ฑด ๊ฐ€๋Šฅ ๋ถˆ๊ฐ€๋Šฅ
์†๋„ ๋А๋ฆผ ๋น ๋ฆ„
ํŠธ๋žœ์žญ์…˜ ๋กค๋ฐฑ ๊ฐ€๋Šฅ ์ œํ•œ์ 
RETURNING ๊ฐ€๋Šฅ ๋ถˆ๊ฐ€๋Šฅ
ํŠธ๋ฆฌ๊ฑฐ ์‹คํ–‰ ์‹คํ–‰๋จ ์‹คํ–‰ ์•ˆ๋จ
SERIAL ๋ฆฌ์…‹ ์•ˆ๋จ ์„ ํƒ ๊ฐ€๋Šฅ

5. UPSERT (ON CONFLICT)

์‚ฝ์ž… ์‹œ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•˜๋ฉด ์—…๋ฐ์ดํŠธํ•˜๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.

์ถฉ๋Œ ์‹œ ๋ฌด์‹œ

-- ์ด๋ฏธ ์กด์žฌํ•˜๋ฉด ์•„๋ฌด๊ฒƒ๋„ ์•ˆ ํ•จ
INSERT INTO users (name, email, age, city)
VALUES ('๊น€์ฒ ์ˆ˜', 'kim@email.com', 35, '๋ถ€์‚ฐ')
ON CONFLICT (email) DO NOTHING;

์ถฉ๋Œ ์‹œ ์—…๋ฐ์ดํŠธ

-- ์ด๋ฏธ ์กด์žฌํ•˜๋ฉด ์—…๋ฐ์ดํŠธ
INSERT INTO users (name, email, age, city)
VALUES ('๊น€์ฒ ์ˆ˜', 'kim@email.com', 35, '๋ถ€์‚ฐ')
ON CONFLICT (email)
DO UPDATE SET
    age = EXCLUDED.age,
    city = EXCLUDED.city;

EXCLUDED ํ‚ค์›Œ๋“œ

EXCLUDED๋Š” ์‚ฝ์ž…ํ•˜๋ ค๊ณ  ํ–ˆ๋˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค.

INSERT INTO users (name, email, age, city)
VALUES ('๊น€์ฒ ์ˆ˜', 'kim@email.com', 35, '๋ถ€์‚ฐ')
ON CONFLICT (email)
DO UPDATE SET
    age = EXCLUDED.age,           -- ์ƒˆ ๊ฐ’ (35)
    city = users.city,            -- ๊ธฐ์กด ๊ฐ’ ์œ ์ง€
    name = EXCLUDED.name;         -- ์ƒˆ ๊ฐ’ (๊น€์ฒ ์ˆ˜)

์กฐ๊ฑด๋ถ€ UPSERT

INSERT INTO users (name, email, age, city)
VALUES ('๊น€์ฒ ์ˆ˜', 'kim@email.com', 35, '๋ถ€์‚ฐ')
ON CONFLICT (email)
DO UPDATE SET
    age = EXCLUDED.age,
    city = EXCLUDED.city
WHERE users.age < EXCLUDED.age;  -- ๊ธฐ์กด ๋‚˜์ด๋ณด๋‹ค ํด ๋•Œ๋งŒ ์—…๋ฐ์ดํŠธ

6. ์„œ๋ธŒ์ฟผ๋ฆฌ๋ฅผ ์ด์šฉํ•œ INSERT

SELECT ๊ฒฐ๊ณผ ์‚ฝ์ž…

-- ๋‹ค๋ฅธ ํ…Œ์ด๋ธ”์—์„œ ๋ณต์‚ฌ
CREATE TABLE users_backup AS SELECT * FROM users;

-- ๋˜๋Š”
INSERT INTO users_backup SELECT * FROM users;

-- ์กฐ๊ฑด๋ถ€ ๋ณต์‚ฌ
INSERT INTO users_backup
SELECT * FROM users WHERE city = '์„œ์šธ';

๊ณ„์‚ฐ๋œ ๊ฐ’ ์‚ฝ์ž…

INSERT INTO statistics (city, user_count)
SELECT city, COUNT(*) FROM users GROUP BY city;

7. ์‹ค์Šต ์˜ˆ์ œ

์‹ค์Šต ๋ฐ์ดํ„ฐ ์ค€๋น„

-- ํ…Œ์ด๋ธ” ์ดˆ๊ธฐํ™”
TRUNCATE TABLE users RESTART IDENTITY;

-- ์ƒ˜ํ”Œ ๋ฐ์ดํ„ฐ ์‚ฝ์ž…
INSERT INTO users (name, email, age, city) VALUES
('๊น€์ฒ ์ˆ˜', 'kim@email.com', 30, '์„œ์šธ'),
('์ด์˜ํฌ', 'lee@email.com', 25, '๋ถ€์‚ฐ'),
('๋ฐ•๋ฏผ์ˆ˜', 'park@email.com', 35, '์„œ์šธ'),
('์ตœ์ง€์˜', 'choi@email.com', 28, '๋Œ€์ „'),
('์ •์ˆ˜์ง„', 'jung@email.com', 32, '์„œ์šธ'),
('ํ™๊ธธ๋™', 'hong@email.com', 40, '์ธ์ฒœ'),
('๊ฐ•๋™์›', 'kang@email.com', 27, '๋ถ€์‚ฐ'),
('์†์˜ˆ์ง„', 'son@email.com', 33, '์„œ์šธ');

์‹ค์Šต 1: ๊ธฐ๋ณธ CRUD

-- 1. ์ƒˆ ์‚ฌ์šฉ์ž ์ถ”๊ฐ€
INSERT INTO users (name, email, age, city)
VALUES ('์‹ ๊ทœํšŒ์›', 'new@email.com', 22, '๊ด‘์ฃผ')
RETURNING *;

-- 2. ์„œ์šธ ์‚ฌ์šฉ์ž ์กฐํšŒ
SELECT * FROM users WHERE city = '์„œ์šธ';

-- 3. ๋‚˜์ด 30 ์ด์ƒ ์‚ฌ์šฉ์ž์˜ ๋„์‹œ๋ฅผ '์ˆ˜๋„๊ถŒ'์œผ๋กœ ๋ณ€๊ฒฝ
UPDATE users
SET city = '์ˆ˜๋„๊ถŒ'
WHERE age >= 30
RETURNING name, age, city;

-- 4. ๊ด‘์ฃผ ์‚ฌ์šฉ์ž ์‚ญ์ œ
DELETE FROM users
WHERE city = '๊ด‘์ฃผ'
RETURNING *;

์‹ค์Šต 2: UPSERT

-- ์ด๋ฉ”์ผ์ด ์ด๋ฏธ ์กด์žฌํ•˜๋ฉด ๋‚˜์ด์™€ ๋„์‹œ ์—…๋ฐ์ดํŠธ
INSERT INTO users (name, email, age, city)
VALUES ('๊น€์ฒ ์ˆ˜', 'kim@email.com', 31, '๊ฒฝ๊ธฐ')
ON CONFLICT (email)
DO UPDATE SET
    age = EXCLUDED.age,
    city = EXCLUDED.city
RETURNING *;

-- ์กด์žฌํ•˜์ง€ ์•Š๋Š” ์ด๋ฉ”์ผ์ด๋ฉด ์ƒˆ๋กœ ์‚ฝ์ž…
INSERT INTO users (name, email, age, city)
VALUES ('์ƒˆํšŒ์›', 'newuser@email.com', 29, '์ œ์ฃผ')
ON CONFLICT (email)
DO UPDATE SET age = EXCLUDED.age, city = EXCLUDED.city
RETURNING *;

์‹ค์Šต 3: ๋Œ€๋Ÿ‰ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ

-- ๋ฐฑ์—… ํ…Œ์ด๋ธ” ์ƒ์„ฑ ๋ฐ ๋ฐ์ดํ„ฐ ๋ณต์‚ฌ
CREATE TABLE users_backup AS
SELECT * FROM users WHERE 1=0;  -- ๊ตฌ์กฐ๋งŒ ๋ณต์‚ฌ

INSERT INTO users_backup
SELECT * FROM users;

-- ํŠน์ • ์กฐ๊ฑด ์‚ฌ์šฉ์ž๋งŒ ๋ฐฑ์—…
INSERT INTO users_backup
SELECT * FROM users WHERE city IN ('์„œ์šธ', '๋ถ€์‚ฐ');

-- ๋ฐฑ์—… ํ™•์ธ
SELECT COUNT(*) FROM users_backup;

8. ์ฃผ์˜์‚ฌํ•ญ ๋ฐ ํŒ

SQL Injection ๋ฐฉ์ง€

-- ๋‚˜์œ ์˜ˆ (๋ฌธ์ž์—ด ์ง์ ‘ ์—ฐ๊ฒฐ)
-- "SELECT * FROM users WHERE name = '" + userInput + "'"

-- ์ข‹์€ ์˜ˆ (ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฐ”์ธ๋”ฉ ์‚ฌ์šฉ - ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ)
-- "SELECT * FROM users WHERE name = $1"

UPDATE/DELETE ์ „ ํ™•์ธ

-- 1. ๋จผ์ € SELECT๋กœ ๋Œ€์ƒ ํ™•์ธ
SELECT * FROM users WHERE city = '์„œ์šธ';

-- 2. ํ™•์ธ ํ›„ UPDATE/DELETE ์‹คํ–‰
UPDATE users SET age = age + 1 WHERE city = '์„œ์šธ';

ํŠธ๋žœ์žญ์…˜ ํ™œ์šฉ

-- ์ค‘์š”ํ•œ ์ž‘์—…์€ ํŠธ๋žœ์žญ์…˜์œผ๋กœ
BEGIN;
UPDATE users SET age = age + 1 WHERE city = '์„œ์šธ';
-- ๊ฒฐ๊ณผ ํ™•์ธ ํ›„
COMMIT;  -- ๋˜๋Š” ROLLBACK;

๋‹ค์Œ ๋‹จ๊ณ„

05_Conditions_and_Sorting.md์—์„œ WHERE ์ ˆ๊ณผ ORDER BY๋ฅผ ์ž์„ธํžˆ ๋‹ค๋ค„๋ด…์‹œ๋‹ค!

to navigate between lessons