웹 애플리케이션이 데이터베이스를 사용해야 하는 이유
지금까지 만든 상품 관리 애플리케이션은 데이터를 리스트에 담아두는 방식으로 동작했다.
학습용으로는 이 방식이 단순하고 이해하기 쉽기 때문에 충분히 의미가 있다.
하지만 실제 서비스 관점에서 보면, 메모리 안의 리스트에만 데이터를 저장하는 구조에는 분명한 한계가 있다.
가장 먼저 떠올릴 수 있는 문제는 데이터의 휘발성이다.
리스트에 저장한 데이터는 애플리케이션이 실행되는 동안에만 유지된다.
즉, 서버가 종료되거나 애플리케이션이 재시작되면 그 안에 있던 데이터는 모두 사라진다.
학습이나 테스트용 예제에서는 괜찮을 수 있지만,
실제 서비스에서 사용자의 데이터가 애플리케이션 종료와 함께 사라진다면 그건 치명적인 문제다.
그렇다면 데이터를 파일에 저장하면 되지 않을까 생각할 수도 있다.
실제로 파일 저장은 “메모리만 사용하면 데이터가 사라진다”는 문제를 해결하는 하나의 방법이 될 수 있다.
하지만 여기에도 또 다른 한계가 있다. 바로 애플리케이션 간 데이터 공유 문제다.
실제 서비스를 운영하다 보면 하나의 애플리케이션만 띄워두는 경우보다,
여러 개의 애플리케이션 인스턴스를 동시에 띄워서 트래픽을 분산 처리하거나,
서비스 중단 없이 배포하기 위해 무중단 배포 구조를 사용하는 경우가 많다.
이런 상황에서 각 애플리케이션이 자기 로컬 파일에만 데이터를 저장한다면,
어떤 요청은 A 서버에서 처리되고 어떤 요청은 B 서버에서 처리될 때 데이터가 서로 다르게 보일 수 있다.
그래서 필요한 것이 공통된 데이터 저장소다.
여러 애플리케이션이 함께 바라볼 수 있는 하나의 저장소가 있어야,
어떤 서버가 요청을 처리하든 같은 데이터를 기준으로 동작할 수 있다.
데이터베이스는 바로 이런 역할을 한다.
데이터베이스를 사용하는 방법
데이터베이스를 사용하려면, 당연히 먼저 데이터베이스를 실행할 수 있어야 한다.
보통 방법은 크게 두 가지로 생각할 수 있다.
첫 번째는 데이터베이스를 직접 설치하는 방법이다.
예를 들어 내 컴퓨터에 MySQL을 직접 설치하고, 운영체제 환경에서 실행하는 방식이다.
이 방법은 실제 설치 경험을 할 수 있다는 장점이 있지만, 설정 과정이 번거롭고 환경이 꼬였을 때 되돌리기 어려울 수 있다.
두 번째는 도커를 설치하고, 도커 컨테이너 안에서 데이터베이스를 실행하는 방법이다.
이번 실습에서는 이 방법을 사용할 예정이다.
이유는 간단하다. 학습용 실습에서는 “쉽게 실행하고, 쉽게 지우고, 다시 처음 상태로 돌릴 수 있는가”가 굉장히 중요하기 때문이다.
도커를 사용하면 MySQL을 내 컴퓨터 운영체제에 직접 설치하는 것이 아니라,
격리된 컨테이너 환경 안에서 실행하게 된다. 이렇게 하면 실습 환경을 만들고 없애는 것이 훨씬 쉬워진다.
예를 들어 설정이 꼬였거나 다시 처음부터 실습하고 싶다면, 도커 컨테이너를 삭제하고 다시 실행하면 된다.
Docker 설치
도커를 사용하려면 먼저 Docker Desktop을 설치해야 한다.
https://www.docker.com/products/docker-desktop/
Docker 공식 사이트에서 운영체제에 맞는 설치 파일을 내려받아 설치하면 된다.
설치 후 실행했을 때 Docker Desktop 화면 왼쪽 아래에 Engine running 같은 표시가 보이면,
도커 엔진이 정상적으로 실행 중이라는 뜻이다.
이제 MySQL을 도커 컨테이너로 실행할 수 있다.
예를 들어 CMD에 다음 명령어를 입력해 사용할 수 있다.
docker run --name some-mysql -p 3306:3306
-e MYSQL_ROOT_PASSWORD=root -d mysql:8.0.29
--character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci

처음 보면 길고 복잡해 보일 수 있지만, 각각의 부분은 역할이 분명하다.
docker run : 새로운 컨테이너를 실행하겠다는 명령어
--name some-mysql : 이 컨테이너의 이름을 some-mysql로 지정
-p 3306:3306 : 내 컴퓨터의 3306 포트와 컨테이너 내부의 3306 포트를 연결
-e MYSQL_ROOT_PASSWORD=root : MySQL root 계정 비밀번호를 root로 설정
-d : 백그라운드에서 컨테이너를 실행
mysql:8.0.29 : MySQL 8.0.29 버전 이미지를 사용
--character-set-server=utf8mb4 : 문자 인코딩 설정
--collation-server=utf8mb4_general_ci : 정렬 및 비교 규칙 설정
즉, 이 명령어 하나로 “MySQL 8.0.29를 root 비밀번호 root로 설정하고,
내 컴퓨터 3306 포트로 접근할 수 있게 백그라운드 실행하라”는 의미가 된다.
컨테이너가 실행된 뒤에는 Docker Desktop에서 실행 중인 컨테이너를 확인할 수 있다.

그리고 메뉴에서 Open in terminal 같은 기능을 사용하면, 컨테이너 내부의 터미널 환경으로 들어갈 수 있다.
여기서 중요한 점은, 지금 보고 있는 명령줄 환경이 내 컴퓨터 본체 운영체제가 아니라 도커 컨테이너 안의 가상 환경이라는 점이다.
이후 MySQL에 접속하려면 다음 명령어를 사용할 수 있다.
mysql -u root -p

엔터를 치면 비밀번호 입력을 요구하고, 앞서 지정한 root를 입력하면 MySQL에 root 권한으로 접속할 수 있다.
이렇게 하면 이제 단순히 “도커 컨테이너를 띄운 상태”를 넘어서,
실제로 MySQL 서버 안으로 들어와 SQL 명령을 실행할 준비가 된 것이다.
데이터베이스 안에 스키마, 테이블 만들기
MySQL에 접속했다고 해서 바로 상품 데이터를 넣을 수 있는 것은 아니다.
먼저 어디에 저장할지 구조를 만들어야 한다.
먼저 스키마를 만든다.
CREATE SCHEMA product_management;
여기서 스키마는 데이터를 담는 큰 논리적 공간이라고 보면 된다.
MySQL에서는 데이터베이스와 비슷한 개념으로 이해해도 무방하다.
즉, product_management라는 이름의 데이터 저장 공간을 만든 것이다.
이후 현재 존재하는 데이터베이스 목록을 보고 싶다면 다음 명령어를 사용할 수 있다.
SHOW DATABASES;
그리고 이제부터는 그 스키마를 사용하겠다고 명시해야 한다.
USE product_management;
이 명령어를 입력하면 이후에 실행하는 테이블 생성, 조회, 삽입 명령은
모두 product_management 스키마 기준으로 동작하게 된다.
그다음에는 테이블을 만든다.
CREATE TABLE products (
id BIGINT PRIMARY KEY NOT NULL AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
price INT NOT NULL,
amount INT NOT NULL
);

이 테이블은 지금까지 자바 코드에서 사용하던 Product 구조와 거의 대응된다.
id, name, price, amount라는 컬럼을 가지고 있고,
id는 기본 키이면서 자동 증가하도록 설정되어 있다.
즉, 지금까지 메모리 안에서 Product 객체로만 존재하던 데이터 구조를,
이제는 관계형 데이터베이스의 테이블 구조로 옮겨놓은 셈이다.
테이블이 잘 만들어졌는지 보고 싶다면 다음 명령어를 사용할 수 있다.
SHOW TABLES;
그다음에는 실제 데이터를 넣어볼 수 있다.
INSERT INTO products(name, price, amount) VALUES ('product1', 100, 10);
INSERT INTO products(name, price, amount) VALUES ('product2', 100, 10);
INSERT INTO products(name, price, amount) VALUES ('product3', 100, 10);
이 구문은 products 테이블의 name, price, amount 컬럼에 각각 값을 넣겠다는 뜻이다.
id는 AUTO_INCREMENT로 설정했기 때문에 직접 넣지 않아도 자동으로 증가하면서 채워진다.
마지막으로 전체 데이터를 보고 싶다면 다음과 같이 조회할 수 있다.
SELECT * FROM products;
다음 편에서...
지금까지는 MySQL 터미널에 직접 접속해서 스키마를 만들고, 테이블을 만들고, 데이터를 직접 넣고 조회했다.
즉, 아직은 데이터베이스를 사람이 수동으로 다루고 있는 상태다.
하지만 실제 웹 애플리케이션에서는 사용자가 터미널에 직접 들어와서 INSERT INTO를 치지는 않는다.
사용자가 상품 추가 요청을 보내면, 애플리케이션이 그 요청을 받아 데이터베이스에 SQL 형태로 반영하게 된다.
즉, 지금까지 직접 했던 작업을 다음 단계부터는 애플리케이션이 대신 수행하게 되는 것이다.
다음 편에서는 상품 관리 애플리케이션에서 상품 추가 API를 호출하면
그 결과가 리스트가 아니라 실제 MySQL 데이터베이스에 저장되도록 바꾸게 된다.
즉, 이전까지의 “메모리 기반 저장소”가 이제는 “데이터베이스 기반 저장소”로 교체되는 셈이다.
'공부 기록 > 이것이 백엔드 개발이다 With Java' 카테고리의 다른 글
| EP22. 상품 관리 애플리케이션에 데이터베이스 연동하기 3편 (0) | 2026.04.24 |
|---|---|
| EP21. 상품 관리 애플리케이션에 데이터베이스 연동하기 2편 (0) | 2026.04.23 |
| EP19. 상품 관리 애플리케이션에 유효성 검사 추가하기 2편 (0) | 2026.04.21 |
| EP18. 상품 관리 애플리케이션에 유효성 검사 추가하기 1편 (0) | 2026.04.20 |
| EP17. List를 이용한 상품 관리 애플리케이션 만들기 5편 (0) | 2026.04.10 |