๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
  • ์žฅ์›์ต ๊ธฐ์ˆ ๋ธ”๋กœ๊ทธ
๐Ÿ”ฌweb application/- Database

100๋งŒ๊ฐœ 1000๋งŒ๊ฐœ์˜ ๋”๋ฏธ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฐ€์žฅ ์‰ฌ์šด ๋ฐฉ๋ฒ•

by Wonit 2024. 10. 20.

TL;DR

 

์ด๋ฒˆ ๊ธ€์˜ ํ•ต์‹ฌ์„ ์š”์•ฝํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค

 

  • ๊ฐ€์žฅ ํšจ์œจ์ ์ธ ๋”๋ฏธ๋ฐ์ดํ„ฐ ์ƒ์„ฑ ๋ฐฉ๋ฒ•
    • temp table ์„ ์ด์šฉํ•˜์—ฌ insert Query ๋‚ ๋ฆฌ๊ธฐ
      • temp table ์ƒ์„ฑ
      • generate_series ์™€ random ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ insert
  • docker-compose ๋กœ ์‹คํ–‰
    • docker-compose ์ด์šฉํ•˜๊ธฐ
    • application runner ์ด์šฉํ•˜๊ธฐ
    • ๋“ฑ๋“ฑ

 

๊ฐ€์žฅ ํšจ์œจ์ ์ธ ๋”๋ฏธ๋ฐ์ดํ„ฐ ์ƒ์„ฑ ๋ฐฉ๋ฒ•

 

DB ๋‚˜ Application ์˜ ์ฒ˜๋ฆฌ๋Ÿ‰ ํ˜น์€ ํŠน์ • ๋Œ€๋Ÿ‰ ๋ฐ์ดํ„ฐ์˜ ์ƒํ™ฉ์„ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์œ„ํ•ด ๋”๋ฏธ ๋ฐ์ดํ„ฐ๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

 

excel, mockaroo, bulk insert ๋“ฑ๋“ฑ ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์„ ์ด์šฉํ•ด์„œ ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š” ์‹ค์Šต ํ™˜๊ฒฝ์„ ๊ตฌ์„ฑํ•ด๋ดค๋Š”๋ฐ ์ผ€์ด์Šค์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒ ์ง€๋งŒ ์ด ๋ฐฉ๋ฒ•์ด ๊ฐ€์žฅ ํšจ์œจ์ ์ด์—ˆ๋‹ค.

 

์•„๋ž˜์˜ ํ•ต์‹ฌ ์ปจ์…‰๋งŒ ์ดํ•ดํ•œ๋‹ค๋ฉด ์–ด๋– ํ•œ ๊ตฌ์กฐ์˜ ๋ฐ์ดํ„ฐ๋„, ์–ด๋– ํ•œ ํฌ๊ธฐ์˜ Dataset ์ด ํ•„์š”ํ•˜๋”๋ผ๋„ ๊ณผ์žฅ ์„ž์–ด 10์ดˆ ์•ˆ์— ์ƒ์„ฑ ๊ฐ€๋Šฅํ•˜๋‹ค.

์šฐ์„  ์ง„ํ–‰ ์ˆœ์„œ๋‚˜ ์ปจ์…‰์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

  1. ๋”๋ฏธ๋ฐ์ดํ„ฐ์˜ ์ปฌ๋Ÿผ ๊ฐ’์„ ์œ„ํ•œ ํ…Œ์ด๋ธ” ๊ตฌ์„ฑ
  2. ์ปฌ๋Ÿผ ๊ฐ’์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋”๋ฏธ๋ฐ์ดํ„ฐ ์ƒ์„ฑ ํ›„ ์ž„์‹œํ…Œ์ด๋ธ”์— insert
  3. ์ž„์‹œ ํ…Œ์ด๋ธ”์—์„œ ๋”๋ฏธ ๋ฐ์ดํ„ฐ ํ…Œ์ด๋ธ”๋กœ insert

 

Step 1. ๊ฐ’์„ ์œ„ํ•œ ์ž„์‹œํ…Œ์ด๋ธ” ๊ตฌ์„ฑ

 

names ๋Š” ๋”๋ฏธ๋ฐ์ดํ„ฐ ์ปฌ๋Ÿผ์˜ ๋žœ๋คํ•œ ๊ฐ’์„ ์œ„ํ•œ ๋‹จ์ˆœ ํ…Œ์ด๋ธ”๋กœ ๋”๋ฏธ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์— ๋งž๊ฒŒ ์ด๋Ÿฌํ•œ ๊ฐ’ ํ…Œ์ด๋ธ” ๋“ค์„ ์–ผ๋งˆ๋“ ์ง€ ์ถ”๊ฐ€ํ•ด๋„ ์ข‹๋‹ค.

 

์•„๋ž˜์—์„œ ๋ณด๊ฒ ์ง€๋งŒ ๋”๋ฏธ ๋ฐ์ดํ„ฐ ์ƒ์„ฑํ•  ๋•Œ ์œ„์˜ 5๊ฐ€์ง€ ๊ฐ’๋“ค ์ค‘ ๋žœ๋คํ•˜๊ฒŒ ์„ธํŒ… ๋  ๊ฒƒ์ด๋‹ค.

 

-- value ํ…Œ์ด๋ธ” ์ƒ์„ฑ
CREATE TABLE names
(
    id   SERIAL PRIMARY KEY,
    name TEXT
);

-- ์ž„์˜ ์ด๋ฆ„ value ์‚ฝ์ž…
INSERT INTO names (name)
VALUES ('Ann'),
       ('Bill'),
       ('Cindy'),
       ('Diane'),
       ('Emma');

 

 

Step 2. ๊ฐ’ ํ…Œ์ด๋ธ”์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋”๋ฏธ๋ฐ์ดํ„ฐ๋ฅผ temp ํ…Œ์ด๋ธ”์— insert

 

์ด๋ฒˆ ๋‹จ๊ณ„์—์„œ๋Š” ๋”๋ฏธ ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•˜๊ณ  ์•ž์„œ ๋งŒ๋“  ๊ฐ’ ํ…Œ์ด๋ธ”์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ž„์‹œ ํ…Œ์ด๋ธ”์„ ๋งŒ๋“ค ๊ฒƒ์ด๋‹ค.

 

๊ทธ ์ž„์‹œ ํ…Œ์ด๋ธ”์—๋Š” generate_series() ํ•จ์ˆ˜๋กœ id ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  random() ์„ ์ด์šฉํ•ด ๊ฐ’๋“ค์„ ์„ธํŒ…ํ•  ๊ฒƒ์ด๋‹ค.

 

-- Step 3: ๋”๋ฏธ ํ…Œ์ด๋ธ” ์ƒ์„ฑ
CREATE TABLE person_data
(
    id   INTEGER PRIMARY KEY,
    name TEXT,
    age  INTEGER
);

-- generate_series๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ 100๋งŒ ๊ฐœ์˜ ๋ฐ์ดํ„ฐ ์‚ฝ์ž…
WITH tmp AS (
    SELECT
        generate_series(1, 1000000) AS id,  -- 1๋ถ€ํ„ฐ 100๋งŒ๊นŒ์ง€์˜ id ์ƒ์„ฑ
        (random() * 4 + 1)::integer AS idx, -- ๋žœ๋คํ•œ ์ด๋ฆ„์„ ์„ ํƒํ•˜๊ธฐ ์œ„ํ•œ ์ธ๋ฑ์Šค (1-5)
        (random() * 79 + 1)::integer AS age -- ๋žœ๋คํ•œ ๋‚˜์ด ์ƒ์„ฑ (1-80)
)

 

์œ„์— ๋ณด์ด๋Š” generate_series ์— ๋”ฐ๋ผ ๋”๋ฏธ ๋ฐ์ดํ„ฐ์…‹์˜ ํฌ๊ธฐ๊ฐ€ ๊ฒฐ์ •๋˜๋ฏ€๋กœ ์ž์œจ์ ์œผ๋กœ ๋Š˜๋ ค์ฃผ๊ฑฐ๋‚˜ ์ค„์—ฌ์ฃผ๋ฉด ๋œ๋‹ค.

 

Step 3. ์ž„์‹œ ํ…Œ์ด๋ธ”์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋”๋ฏธ ๋ฐ์ดํ„ฐ insert

 

์ด์ œ ์‹ค์ œ ๋”๋ฏธ ํ…Œ์ด๋ธ” (person_data) ์— insert ๋ฅผ ํ•˜๋ฉด ๋œ๋‹ค.

 

temp table ์—์„œ ์ƒ์„ฑํ•œ ๊ฐ’์„ sub query ๋กœ ์กฐํšŒํ•ด์„œ insert ํ•˜๋Š” ๋‹จ์ˆœํ•œ ๋ฐฉ๋ฒ•์ด๋‹ค

 

INSERT
INTO person_data (id, name, age)
SELECT tmp.id,
       (SELECT name FROM names WHERE names.id = tmp.idx) AS name,
       tmp.age
FROM tmp;

 

์ „์ฒด init.sql

 

์•ž์„œ ์ด์•ผ๊ธฐ ํ•œ ์ „์ฒด ๊ณผ์ •์„ ํ•˜๋‚˜์˜ sql ํŒŒ์ผ๋กœ ๋งŒ๋“ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

 

CREATE TABLE names
(
    id   SERIAL PRIMARY KEY,
    name TEXT
);

INSERT INTO names (name)
VALUES ('Ann'),
       ('Bill'),
       ('Cindy'),
       ('Diane'),
       ('Emma');

CREATE TABLE person_data
(
    id   INTEGER PRIMARY KEY,
    name TEXT,
    age  INTEGER
);

WITH tmp AS (
    SELECT
        generate_series(1, 1000000) AS id,
        (random() * 4 + 1)::integer AS idx,
        (random() * 79 + 1)::integer AS age
)

INSERT
INTO person_data (id, name, age)
SELECT tmp.id,
       (SELECT name FROM names WHERE names.id = tmp.idx) AS name,
       tmp.age
FROM tmp;

 

์ด์ œ ์ด sql ํŒŒ์ผ๋กœ ์‰ฝ๊ฒŒ n ๊ฐœ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

docker-compose ๋กœ ์‹คํ–‰

 

๋‚˜๋Š” ์ด๋ ‡๊ฒŒ ๋”๋ฏธ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๋ฉด ๋ณดํ†ต Spring Application ๊ณผ ํ†ตํ•ฉํ•˜์—ฌ ํ…Œ์ŠคํŠธ๋‚˜ ๊ฒ€์ฆ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

 

์ด๋•Œ ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์ด ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๊ฒ ์ง€๋งŒ ๋‚˜๋Š” ๋ณดํ†ต docker-compose ๋กœ ์‹คํ–‰ํ™˜๊ฒฝ์„ ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ์„ ์ฆ๊ฒจ ํ•˜๋ฏ€๋กœ ๋‚ด๊ฐ€ ์„ค์ •ํ•˜๋Š” docker-compose ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

 

version: "3.8"
services:
  order-db:
    image: postgres:14
    container_name: order-db
    environment:
      POSTGRES_DB: orderdb
      POSTGRES_USER: orderuser
      POSTGRES_PASSWORD: orderpassword
    ports:
      - "5432:5432"
    volumes:
      - ./sql/init.sql:/docker-entrypoint-initdb.d/init.sql

 

volumes ๋ฅผ ๋ณด๋ฉด ์•Œ๊ฒ ์ง€๋งŒ dc ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ์œ„์น˜์— /sql ํ•˜์œ„ ๋””๋ ‰ํ† ๋ฆฌ์— ์•ž์„  sql ๋ฌธ์ด init.sql ๋กœ ๋“ค์–ด๊ฐ€ ์žˆ์–ด์•ผ ํ•œ๋‹ค.

 

์ด์™ธ์—๋„ spring application runner ๋‚˜ Bean Initializer ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ https://engineerinsight.tistory.com/71 ์—์„œ ์ž˜ ์ •๋ฆฌ๋˜์–ด ์žˆ์œผ๋‹ˆ ์ฐธ๊ณ ํ•˜๋Š” ๊ฒƒ๋„ ์ถ”์ฒœํ•œ๋‹ค.

 

[Spring/DB] ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋”๋ฏธ ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€ํ•˜๋Š” 4๊ฐ€์ง€ ๋ฐฉ๋ฒ•: data.sql, @PostConstruct, @EventListener(Applica

๐Ÿ’‹ ๋”๋ฏธ ๋ฐ์ดํ„ฐ๋ž€? ๋”๋ฏธ ๋ฐ์ดํ„ฐ๋ž€, ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ํŠน์ • ๋ฐ์ดํ„ฐ๋ฅผ ํ…Œ์ŠคํŠธ๋‚˜ ๋ฐ๋ชจ ์šฉ๋„๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์ž„์˜๋กœ ๋งŒ๋“  ๋ฐ์ดํ„ฐ์ด๋‹ค. ์‹ค์ œ ์šด์˜ ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์•„๋‹ˆ๋ฉฐ, ๊ฐœ๋ฐœ์ž๋‚˜ ํ…Œ์Šค

engineerinsight.tistory.com

 

๋Œ“๊ธ€