Data/PostgreSQL

PostgreSQL ์‹œ์ž‘ํ•˜๊ธฐ: Docker ์„ค์น˜๋ถ€ํ„ฐ DBeaver๋กœ ๋ฐ์ดํ„ฐ ๋‹ค๋ฃจ๊ธฐ

๋ˆ„๊ตฌ์„ธ์—ฐ 2025. 8. 24. 20:54

 

PostgreSQL

 

 

๐Ÿ˜ 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๏ธโƒฃ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ์‚ฌ์šฉ์ž ์ƒ์„ฑ

์‹ค์Šต์„ ์œ„ํ•ด ์ƒˆ๋กœ์šด DB์™€ ์œ ์ €๋ฅผ ๋งŒ๋“ค์–ด๋ด…์‹œ๋‹ค.
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 ์„ค์น˜

 

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 ํˆด์„ ์ด์šฉํ•˜๋ฉด ๋”์šฑ ํŽธ๋ฆฌํ•˜๊ฒŒ ํ•™์Šต ๊ฐ€๋Šฅ