
백엔드 개발자를 준비한 한 지원자의 쇼핑몰 프로젝트를 검토한 적이 있습니다. 포트폴리오에는 자바와 스프링, 관계형 데이터베이스를 사용해 회원가입과 상품 주문 기능을 구현했다고 적혀 있었습니다. 하지만 테이블 구조를 살펴보니 주문이 생성될 때마다 회원 이름과 이메일, 주소가 같은 형태로 반복 저장되고 있었습니다. 회원이 주소를 변경하면 이전 주문의 배송지까지 모두 바뀌어야 하는지, 주문 당시 정보를 유지해야 하는지도 정해져 있지 않았습니다. 이메일 중복은 저장 전에 조회하는 코드만 있었고 동시에 같은 이메일로 요청하면 두 건이 저장될 가능성도 있었습니다. 데이터베이스를 사용했다는 결과는 있었지만 정보를 어떤 기준으로 나누고 관계를 만들었는지는 설명하지 못했습니다.
이 사례에서 부족했던 것은 복잡한 SQL 문법이 아니었습니다. 서비스에서 어떤 데이터를 관리해야 하는지 구분하고, 각 정보가 어떻게 연결되며, 중복과 잘못된 변경을 어떻게 막을 것인지 설계하는 기초가 필요했습니다. 데이터베이스는 정보를 보관하는 표 하나가 아니라 서비스의 상태를 일관되게 유지하고 필요한 내용을 정확하게 조회하기 위한 구조입니다. 개념 이해와 정보 관리, 서버를 통한 처리 흐름을 함께 알아야 프로젝트에서도 데이터 저장 기능을 넘어 설계와 문제해결 경험을 보여줄 수 있습니다.
데이터베이스 개념 이해는 정보를 나누고 연결하는 기준에서 시작합니다
- 파일과 표로 저장하는 것과 데이터베이스는 다릅니다
작은 자료는 텍스트 파일이나 스프레드시트에 저장할 수 있습니다. 그러나 여러 사용자가 동시에 정보를 조회하고 수정하는 서비스에서는 데이터가 빠르게 늘어나고 서로 연결됩니다. 회원 한 명은 여러 주문을 할 수 있고 주문 한 건에는 여러 상품이 포함될 수 있습니다.
데이터베이스는 일정한 구조에 따라 데이터를 저장하고 필요한 조건으로 조회하며 여러 사용자의 변경을 관리합니다. 이를 운영하는 소프트웨어를 데이터베이스 관리 시스템이라고 합니다. 개발자는 관리 시스템을 이용해 정보를 추가하고 조회하고 수정하고 삭제합니다.
- 파일은 단순한 자료 보관에는 편리하지만 여러 사용자의 동시 변경과 관계있는 정보의 관리가 어려울 수 있습니다. 어떤 값이 최신인지와 잘못된 수정이 발생했을 때의 복구도 별도로 고려해야 합니다.
- 데이터베이스는 데이터 형식과 관계, 제약조건을 정의할 수 있습니다. 중복되면 안 되는 값과 반드시 필요한 값, 다른 정보와 연결되는 기준을 구조로 표현할 수 있습니다.
- 데이터베이스를 사용한다고 모든 정보가 자동으로 올바르게 관리되는 것은 아닙니다. 서비스의 요구사항을 이해하고 테이블과 관계, 저장 규칙을 적절하게 설계해야 합니다.
- 테이블과 행, 열은 정보 구조의 기본입니다
관계형 데이터베이스에서는 데이터를 테이블이라는 구조로 관리합니다. 회원 테이블에는 회원번호와 이메일, 이름, 가입일처럼 회원을 설명하는 항목이 들어갈 수 있습니다. 각각의 항목은 열에 해당하고 한 명의 회원 정보는 하나의 행으로 저장됩니다.
상품 테이블에는 상품번호와 상품명, 가격, 재고 상태가 들어갈 수 있습니다. 주문 테이블에는 주문번호와 회원번호, 주문일, 주문 상태가 포함될 수 있습니다. 여러 상품이 하나의 주문에 들어간다면 주문 상품을 별도의 테이블로 두고 주문과 상품을 연결할 수 있습니다.
기본키는 각 행을 구분하는 기준입니다. 회원 이메일처럼 변경될 수 있거나 개인정보가 포함된 값보다 별도의 회원번호를 사용하는 방식이 일반적입니다. 다른 테이블에서 회원번호를 참조하면 주문이 어느 회원과 연결되는지 표현할 수 있습니다.
- 회원과 주문 정보를 한 테이블에 저장한 사례
쇼핑몰 프로젝트를 만든 지원자는 주문 정보를 쉽게 조회하기 위해 주문 테이블에 회원 이름과 이메일, 주소, 상품명, 상품 가격을 모두 저장했습니다. 한 사용자가 여러 번 주문하면 같은 회원 정보가 반복됐고 상품명이 변경되면 과거 주문 기록도 함께 수정해야 하는지 판단하기 어려웠습니다.
처음에는 한 테이블에서 모든 정보를 조회할 수 있으니 더 단순하고 편리하다고 생각했습니다. 그러나 회원 이메일을 수정했을 때 여러 주문 행의 값이 서로 달라졌고 같은 상품도 주문마다 다른 이름으로 저장되는 문제가 생겼습니다.
지원자는 회원과 상품, 주문, 주문 상품의 역할을 구분했습니다. 주문은 회원과 연결하고 주문 상품에는 주문 당시의 수량과 가격을 저장했습니다. 배송지는 회원의 현재 주소와 주문 당시 주소를 구분해 요구사항에 맞게 관리했습니다.
- 결과 중심 설명: 쇼핑몰의 회원과 상품, 주문 데이터를 데이터베이스에 저장했습니다.
- 구조가 보이는 설명: 회원과 상품, 주문을 각각 분리하고 회원번호와 상품번호를 이용해 관계를 연결했습니다.
- 설계 판단이 담긴 설명: 회원과 상품 정보를 주문마다 반복 저장해 수정할 때 값이 달라지는 문제를 발견했습니다. 현재 회원 정보와 주문 당시 유지해야 할 배송 및 가격 정보를 구분하고 주문과 주문 상품의 관계를 다시 설계했습니다.
이 사례에서 중요한 것은 테이블 개수를 늘린 것이 아닙니다. 어떤 정보가 독립적으로 관리되어야 하고 어떤 값은 주문 시점의 기록으로 남아야 하는지 요구사항을 기준으로 판단한 과정입니다.
- 정규화는 무조건 테이블을 많이 나누는 작업이 아닙니다
데이터베이스 기초를 공부하면 정규화라는 개념을 접하게 됩니다. 정규화는 중복과 변경 과정의 문제를 줄이기 위해 정보를 적절한 구조로 나누는 과정입니다. 그러나 모든 값을 가능한 한 많은 테이블로 분리하는 것이 목표는 아닙니다.
회원 정보가 여러 주문 행에 반복되면 이름이나 연락처를 수정할 때 일부 행만 바뀌는 문제가 생길 수 있습니다. 반대로 주문 당시 가격처럼 이후 상품 가격이 변경되어도 과거 기록에 유지되어야 하는 정보는 주문 시점의 값으로 남길 필요가 있습니다.
서비스의 요구사항과 조회 방식에 따라 필요한 구조가 달라집니다. 정규화 개념을 적용하되 어떤 정보를 현재 상태로 관리하고 어떤 정보를 과거 기록으로 보관할지를 함께 판단해야 합니다.
정보 관리는 중복과 오류를 막고 일관된 상태를 유지하는 일입니다
- 제약조건은 잘못된 데이터가 들어오는 것을 막습니다
데이터베이스에는 각 열에 들어갈 값의 형식과 필수 여부, 중복 허용 여부를 정할 수 있습니다. 회원 이메일이 반드시 필요하다면 빈 값이 저장되지 않도록 하고, 하나의 이메일로 한 계정만 만들 수 있다면 중복을 제한할 수 있습니다.
애플리케이션에서 입력값을 검증하더라도 데이터베이스의 제약조건이 필요할 수 있습니다. 화면을 거치지 않은 요청이나 동시에 들어오는 요청, 다른 프로그램의 저장 작업에서도 최종 데이터 상태가 지켜져야 하기 때문입니다.
- 필수값 제약은 서비스 운영에 반드시 필요한 데이터가 비어 있는 상태로 저장되는 것을 막습니다.
- 고윳값 제약은 이메일과 상품 코드처럼 중복되면 안 되는 값의 저장을 제한합니다.
- 관계 제약은 존재하지 않는 회원번호나 상품번호가 주문에 들어가는 문제를 줄입니다.
- 값의 범위와 상태는 애플리케이션 로직과 함께 관리해야 합니다. 재고가 음수가 되지 않도록 어떤 단계에서 확인할지도 고민해야 합니다.
- 중복 이메일이 동시에 저장된 회원가입 사례
한 지원자는 회원가입 전에 같은 이메일이 있는지 조회하고 결과가 없으면 사용자 정보를 저장하도록 구현했습니다. 한 명씩 요청할 때는 중복 가입이 차단됐습니다. 그러나 거의 같은 시간에 같은 이메일로 두 요청을 보내면 모두 중복된 값이 없다고 판단한 뒤 저장을 시도할 수 있었습니다.
처음에는 저장 전에 조회했으므로 충분하다고 생각했습니다. 하지만 조회와 저장 사이에 다른 요청이 들어오는 상황을 고려하지 않았습니다. 지원자는 동시에 회원가입을 요청하는 테스트를 만들고 요청 시각과 조회 및 저장 결과를 비교했습니다.
이후 데이터베이스에도 이메일 중복을 막는 제약조건을 설정했습니다. 저장 과정에서 중복이 확인되면 내부 오류를 그대로 전달하지 않고 사용자가 이해할 수 있는 가입 실패 응답으로 바꿨습니다. 정상 가입과 순차적인 중복 요청, 동시 요청을 각각 검증했습니다.
- 기능 중심 설명: 이메일 중복 확인이 포함된 회원가입 기능을 구현했습니다.
- 데이터 관리가 보이는 설명: 저장 전 이메일을 조회하고 데이터베이스에도 중복을 막는 기준을 적용했습니다.
- 검증까지 담긴 설명: 조회와 저장 사이에 동시에 요청이 들어오면 같은 이메일이 저장될 수 있다는 점을 확인했습니다. 데이터베이스 제약조건과 오류 응답을 추가하고 동시 요청에서 하나의 회원만 생성되는지 테스트했습니다.
이 사례는 애플리케이션의 검증과 데이터베이스의 최종 보호 기준이 서로 다른 역할을 한다는 점을 보여줍니다.
- 트랜잭션은 여러 변경을 하나의 작업으로 관리합니다
서비스 기능은 하나의 데이터만 바꾸지 않을 수 있습니다. 상품 주문에서는 주문 정보를 저장하고 재고를 감소시키며 결제 상태를 변경할 수 있습니다. 이 중 일부만 성공하면 데이터가 실제 상황과 맞지 않을 수 있습니다.
트랜잭션은 관련된 여러 작업을 하나의 처리 단위로 묶어 모두 성공하거나 필요한 경우 함께 취소되도록 관리하는 개념입니다. 주문은 저장됐지만 재고가 줄지 않거나 송금 기록은 남았지만 잔액이 변경되지 않는 상황을 방지하는 데 활용할 수 있습니다.
다만 외부 결제 서비스처럼 하나의 데이터베이스 밖에서 실행되는 작업은 같은 트랜잭션만으로 모두 처리하기 어렵습니다. 서비스의 범위와 실패 가능성을 구분하고 상태 관리와 보완 절차를 별도로 설계해야 합니다.
- 주문 저장과 재고 감소가 어긋난 사례
백엔드 프로젝트에서 주문 정보를 먼저 저장한 뒤 상품 재고를 감소시키도록 구현했습니다. 정상 주문에서는 문제가 없었지만 재고 감소 단계에서 오류가 발생하면 주문은 저장되고 재고는 그대로 남았습니다.
지원자는 처음에 오류가 발생하면 사용자에게 실패 응답을 보내므로 데이터 문제도 없다고 생각했습니다. 그러나 데이터베이스를 확인하니 실패한 요청의 주문 기록이 남아 있었습니다. 사용자는 실패로 안내받았지만 관리자 화면에는 주문이 존재하는 상태였습니다.
주문 생성과 재고 감소를 하나의 처리 범위로 묶고 재고 단계에서 예외를 발생시켜 주문 저장도 함께 취소되는지 확인했습니다. 재고 부족과 존재하지 않는 상품, 정상 주문을 나누어 데이터 상태를 다시 검증했습니다.
- 정의 중심 설명: 트랜잭션을 적용해 데이터 일관성을 보장했습니다.
- 프로젝트 연결 설명: 주문 저장과 재고 감소 중 하나가 실패하면 두 작업이 함께 취소되도록 처리했습니다.
- 문제해결이 담긴 설명: 재고 감소 오류에서도 주문만 남는 문제를 발견했습니다. 재고 단계에서 예외를 발생시켜 주문 정보도 함께 취소되는지 확인하고 정상 주문과 재고 부족, 잘못된 상품 요청을 다시 테스트했습니다.
트랜잭션의 정의를 외운 답변보다 어떤 데이터가 어긋났고 수정 후 무엇을 확인했는지를 설명하는 편이 기술면접에서도 더 구체적인 근거가 됩니다.
- 인덱스는 조회 속도와 저장 비용을 함께 고려해야 합니다
데이터가 많아지면 필요한 행을 찾는 데 시간이 걸릴 수 있습니다. 인덱스는 특정 열의 값을 기준으로 데이터를 더 빠르게 찾도록 도와주는 구조입니다. 책의 모든 페이지를 넘기지 않고 색인을 이용해 필요한 내용을 찾는 방식과 비슷하게 이해할 수 있습니다.
모든 열에 인덱스를 추가하면 조회가 무조건 빨라지는 것은 아닙니다. 인덱스도 저장 공간을 사용하고 데이터가 추가되거나 변경될 때 함께 관리되어야 합니다. 조회 조건과 정렬 방식, 데이터의 분포를 확인해 필요한 위치를 선택해야 합니다.
주문 내역에서 사용자와 주문 상태, 기간을 자주 조건으로 사용한다면 실제 조회 방식을 확인할 수 있습니다. 데이터가 적은 개인 프로젝트에서는 성능 차이가 크지 않을 수 있으므로 임의로 높은 개선 수치를 만들기보다 실행 과정과 한계를 솔직하게 기록하는 것이 좋습니다.
- 백업과 권한도 정보 관리의 일부입니다
데이터를 정상적으로 저장하는 것만큼 손실과 잘못된 접근을 막는 일도 중요합니다. 실수로 데이터를 삭제하거나 시스템 장애가 발생했을 때 복구할 방법이 있어야 합니다. 백업이 존재한다는 사실뿐 아니라 실제로 복원할 수 있는지도 확인해야 합니다.
접근 권한도 필요한 범위로 제한해야 합니다. 애플리케이션이 사용하는 계정에 모든 관리 권한을 부여하면 편리할 수 있지만 문제가 발생했을 때 영향 범위가 커질 수 있습니다. 개발과 테스트, 운영 환경의 접속 정보도 구분하는 것이 좋습니다.
포트폴리오를 공개할 때 데이터베이스 주소와 계정, 비밀번호를 코드에 포함하지 않아야 합니다. 이미 공개 저장소에 올라갔다면 파일만 삭제하지 말고 해당 정보를 교체하고 다시 노출되지 않도록 관리 기준을 마련해야 합니다.
서비스 구조에서는 클라이언트와 서버, 데이터베이스의 역할을 나눠야 합니다
- 클라이언트가 데이터베이스에 직접 접근하지 않는 이유가 있습니다
웹 서비스에서 사용자는 화면을 통해 정보를 입력하고 기능을 요청합니다. 클라이언트는 요청을 서버에 전달하고 서버는 입력과 인증, 권한, 업무 규칙을 확인한 뒤 데이터베이스를 조회하거나 변경합니다.
클라이언트가 데이터베이스에 직접 접근하면 접속 정보와 내부 구조가 노출될 수 있습니다. 사용자마다 동일한 업무 규칙을 적용하기 어렵고 허용되지 않은 정보까지 조회하거나 변경할 위험도 커집니다.
- 클라이언트는 사용자 입력과 화면 상태, 서버 요청과 응답 처리를 담당합니다. 데이터가 저장됐다고 추측하지 않고 서버의 처리 결과에 따라 화면을 변경해야 합니다.
- 서버는 요청값을 검증하고 사용자의 인증과 권한을 확인합니다. 서비스의 규칙에 따라 필요한 데이터를 조회하고 저장합니다.
- 데이터베이스는 서버가 전달한 작업에 따라 정보를 관리합니다. 정의된 제약조건과 관계, 트랜잭션을 통해 데이터의 상태를 보호합니다.
각 영역은 분리되어 있지만 하나의 요청 흐름으로 연결됩니다. 어느 구간에서 문제가 생겼는지 확인하려면 실제 요청과 서버 로그, 데이터 상태를 함께 살펴봐야 합니다.
- 게시글은 저장됐지만 화면에는 실패로 보인 사례
프런트엔드와 백엔드 팀 프로젝트에서 게시글 작성 버튼을 누르면 서버에는 데이터가 정상적으로 저장됐지만 화면에는 오류 안내가 나타나는 문제가 있었습니다. 사용자가 다시 버튼을 누르면 같은 게시글이 여러 건 등록됐습니다.
처음에는 데이터베이스 저장 오류라고 생각했습니다. 네트워크 응답을 확인해 보니 서버는 저장에 성공했지만 클라이언트가 기대한 응답 항목과 실제 항목명이 달랐습니다. 화면에서는 게시글 번호를 찾지 못해 실패 상태로 처리했습니다.
두 담당자는 게시글 생성 응답에 필요한 항목과 이름을 다시 정리했습니다. 클라이언트에서는 요청 중 버튼을 비활성화하고 서버의 성공 응답을 확인한 뒤 목록 화면으로 이동하도록 수정했습니다. 정상 등록과 응답 지연, 잘못된 입력, 서버 오류를 나누어 테스트했습니다.
- 결과 중심 설명: 게시글 작성 기능의 저장 오류를 수정했습니다.
- 연결 흐름이 보이는 설명: 서버 저장 결과와 클라이언트의 응답 처리 항목을 비교해 화면 오류의 원인을 찾았습니다.
- 문제해결이 담긴 설명: 데이터는 저장됐지만 응답 항목명이 달라 화면에서 실패로 처리되는 문제를 발견했습니다. 요청과 응답 기준을 문서로 맞추고 반복 클릭을 막은 뒤 정상 등록과 지연 응답을 다시 검증했습니다.
이 사례에서 데이터베이스는 정상적으로 동작했지만 서버 응답과 클라이언트 처리가 어긋나 문제가 발생했습니다. 서비스 구조 전체를 이해해야 원인을 정확하게 구분할 수 있습니다.
- 테이블 설계는 화면 기능이 아니라 업무 규칙에서 시작합니다
화면에 입력란이 있다고 해서 각 항목을 그대로 하나의 테이블에 넣는 방식은 적절하지 않을 수 있습니다. 서비스에서 독립적으로 관리되는 정보와 여러 기능에서 함께 사용하는 정보, 과거 시점의 상태로 남겨야 하는 정보를 먼저 구분해야 합니다.
주문 화면에 회원 이름과 주소, 상품명과 가격이 함께 보이더라도 회원과 상품, 주문은 각각 다른 생명주기를 가집니다. 회원 이름이 바뀌어도 과거 주문의 결제금액이 달라져서는 안 됩니다. 상품이 판매 중지되어도 기존 주문 내역은 유지되어야 합니다.
테이블을 설계할 때는 화면의 위치보다 업무 규칙을 질문해야 합니다. 한 회원이 여러 주문을 할 수 있는지, 하나의 주문에 여러 상품이 들어가는지, 삭제 대신 상태를 변경해야 하는 정보는 무엇인지 확인해야 합니다.
- 포트폴리오에서는 SQL보다 설계와 검증 근거를 보여줘야 합니다
데이터베이스를 사용했다고 적은 뒤 테이블 목록과 SQL 코드만 넣으면 지원자가 구조를 이해했는지 확인하기 어렵습니다. 각 테이블의 역할과 관계, 주요 제약조건, 대표적인 조회와 저장 흐름을 설명해야 합니다.
백엔드 지원자는 회원가입과 주문 기능을 기준으로 요청이 어느 데이터를 조회하고 변경하는지 보여줄 수 있습니다. 중복 이메일과 동시 주문, 재고 부족처럼 잘못된 상태가 생길 수 있는 조건을 테스트한 경험도 좋은 근거가 됩니다.
프런트엔드 지원자도 데이터베이스에 직접 접근하지는 않지만 서버에서 전달되는 데이터의 구조를 이해해야 합니다. 목록과 상세 정보, 페이지 단위 결과, 데이터 없음 상태를 화면에서 어떻게 처리했는지 설명할 수 있습니다.
기술면접에서는 데이터베이스의 정의만 말하지 않고 프로젝트에서 테이블을 나눈 기준과 발생한 데이터 오류, 적용한 제약조건, 수정 후 검증 결과를 연결하는 것이 좋습니다. 개념이 실제 서비스 구조에서 어떻게 사용됐는지를 보여줘야 합니다.
- conclusion
데이터베이스는 정보를 저장하는 표 하나가 아닙니다. 서비스에서 회원과 상품, 주문처럼 서로 연결된 데이터를 기준에 맞게 보관하고 필요한 내용을 조회하며 잘못된 변경과 중복을 줄이는 구조입니다.
현재 자신의 이해와 프로젝트는 다음 내용을 중심으로 점검할 수 있습니다.
- 테이블과 행, 열, 기본키의 의미를 설명하고 서비스의 정보를 어떤 기준으로 나누었는지 말할 수 있어야 합니다. 화면에 함께 표시된다는 이유만으로 서로 다른 정보를 한 테이블에 반복 저장하고 있지는 않은지 확인해야 합니다.
- 정보 관리에서는 애플리케이션 검증뿐 아니라 필수값과 고윳값, 관계 제약, 트랜잭션을 함께 고려해야 합니다. 주문 저장과 재고 감소처럼 여러 데이터가 바뀌는 기능에서는 일부만 성공할 때 어떤 문제가 생기는 지도 테스트해야 합니다.
- 서비스 구조에서는 클라이언트와 서버, 데이터베이스의 역할을 구분해야 합니다. 화면에서 보낸 요청이 서버의 검증과 업무 로직을 거쳐 저장되고, 처리 결과가 다시 응답되는 흐름을 설명할 수 있어야 합니다.
실제 프로젝트를 검토하면 데이터베이스를 사용했다고 적었지만 회원과 주문 정보를 한 테이블에 반복 저장하거나 중복 이메일을 코드 조회만으로 막는 경우가 있습니다. 기능이 실행되는 결과보다 어떤 기준으로 구조를 설계하고 데이터가 어긋나는 상황을 방지했는지가 중요합니다.
테이블 관계를 설계한 경험은 개념 이해의 근거가 되고 중복과 잘못된 저장을 막은 기록은 문제해결 사례가 됩니다. 요청부터 서버 처리와 데이터 저장까지 이어지는 흐름을 정리하면 포트폴리오와 기술면접에서도 데이터베이스 기초를 실제 경험으로 설명할 수 있습니다.