아키텍처 구조 및 서비스 계층 분리

  • 기본 구조: 클라이언트(React, Web Browser)가 서버(Next, NodeJS)에 요청을 보내면, 서버는 Raw data API를 통해 데이터베이스(DB)와 통신하는 구조를 가집니다.
     
  • 계층 분리: 좋은 아키텍처를 위해 사용자 입/출력, 업무 처리, 데이터 처리 계층을 분리해야 합니다. 이는 업무 로직을 분리하여 객체로 만들고 역할을 나누는 것을 의미합니다.
     
  • DTO (Data Transfer Object): 계층 간에 데이터를 전달하는 객체로, 서비스 계층에서 생성될 수 있습니다.
     
  • 서비스와 리포지토리: DfMenuService는 사용자 요청을 처리하고, Repository는 DB와의 상호작용을 담당하는 저장소 역할을 합니다.
     
  • Use Case: 서비스 계층을 더 작게 나눈 단위로, 특정 사용자 요청 하나에 해당합니다.
     
  • API route와 레이아웃: route는 API를 목적으로 사용하는 파일이며, layout은 페이지를 만들기 위한 파일입니다.

클린 아키텍처 (Clean Architecture)
기본 철학: UI와 업무 로직을 분리하는 것입니다. 이는 UI, 데이터베이스, 프레임워크, 외부 라이브러리 등으로부터 독립적인 시스템을 만드는 것을 목표로 합니다.

의존성 규칙 (Dependency Rule): 모든 코드 의존성은 반드시 외부 계층에서 내부 계층으로만 향해야 합니다. 내부 계층은 외부 계층에 의존할 수 없습니다. 예를 들어, Use Case는 자신을 호출하는 UI를 몰라야 하며, 특정 데이터베이스(Supabase, MongoDB 등) 구현 방식도 알아서는 안 됩니다.

Domain 계층: 외부 기술의 영향을 받지 않는 순수 비즈니스 규칙을 처리합니다.

 

Application 계층 (Use Case): UI가 필요로 하는 방식으로 비즈니스 로직과 데이터를 처리합니다.

 

Interface Adapters 계층: 외부와 내부를 연결하고 데이터를 변환하거나 요청을 중계합니다.

 

Infrastructure 계층: 데이터베이스나 외부 API 같은 구체적인 기술 구현을 담당합니다.


관심사의 분리 (Separation of Concerns)
: 각 계층은 특정 역할에만 집중해야 합니다
.


제어의 역전(IoC)과 의존성 주입(DI)

제어의 역전 (IoC): 객체 생성 방식에 대한 제어권이 역전되는 것으로, 객체 간의 결합도를 낮추는 데 중요합니다.
의존성 주입 (DI): IoC 원칙을 구현하는 대표적인 방법입니다. 어떤 객체가 필요로 하는 다른 객체(의존성)를 내부에서 직접 생성하지 않고 외부에서 넣어주는(주입하는) 방식입니다.

728x90

데이터베이스의 발전과 기본 개념

  • DBMS의 등장: 과거에는 데이터베이스(DB)가 없어 정보처리가 어려웠습니다. 데이터를 한 군데에 모아 중복을 제거하는 데이터베이스 관리 시스템(DBMS)이 등장했습니다.

  • 핵심 동작 원리: DBMS는 데이터를 저장할 때는 자르고(정규화), 읽을 때는 합칩니다(JOIN). 데이터를 '자르는 것'이 정규화의 핵심 개념입니다.

  • DBMS의 종류: 과거에는 계층형, 네트워크형 DBMS가 있었으며, 이후 객체 지향형, 그리고 현재 주로 사용하는 관계형 DBMS(RDBMS)로 발전했습니다.

  • 테이블 관계: RDBMS에서 먼저 생성된 테이블은 부모 테이블, 나중에 생성되어 부모를 참조하는 테이블은 자식 테이블이 됩니다. 자식은 부모가 있어야만 생성될 수 있습니다.

  • 데이터 접근: 데이터베이스는 직접 사용하기보다 관리 시스템(DBMS)을 통해 간접적으로 사용해야 합니다. 이때 데이터를 수정하고 관리하기 위한 명령어를 쿼리 언어(Query Language), 즉 SQL이라고 합니다.

데이터 정규화 (Data Normalization)

제1정규형 (1NF) - 원자값 확보

  • 목표: 원자값(더 이상 쪼갤 수 없는 단일 값)이 아닌 도메인을 분해하는 것입니다.
    1. 각 속성에 들어갈 값은 원자값(단일 값)이어야 합니다 (반복 그룹 존재 X).
    2. 모든 행은 식별자로 완전하게 구분되어야 합니다.
  • 구현 방법 및 장단점

    구분자 사용: 간단하지만, 데이터 수정 및 삭제가 불편합니다.
    컬럼 확장: 원칙적이지만, 컬럼이 너무 많아지면 복잡도가 증가합니다.
    자식 테이블 생성(자식화): JOIN 시 이해하기 쉽고 개수에 제약이 없지만, 처리해야 할 테이블이 늘어납니다.

제2정규형 (2NF) - 부분 함수 종속 제거

  • 목표 : 부분적 함수 종속을 제거하는 것입니다.

    이 정규화는 복합 키(여러 컬럼을 합친 키)를 가진 테이블에 적용됩니다. 테이블의 일반 속성이 복합 키의 일부가 아닌, 키 전체에 종속되어야 2NF를 만족합니다.

제3정규형 (3NF) - 이행적 함수 종속 제거

  • 목표: 이행적(전이적) 함수 종속을 없애는 것입니다.
    A → B 이고 B → C 일 때 A → C가 성립하는 관계, 즉 일반 속성이 다른 일반 속성에 종속되는 관계를 제거합니다.

BCNF (Boyce-Codd Normal Form)
모든 결정자(Determinant)가 후보 키(Candidate Key)여야 한다는 더 엄격한 규칙을 적용합니다.

  • 결정자: 다른 속성의 값을 결정하는 속성 (X → Y에서 X).
  • 후보 키: 각 행을 유일하게 식별할 수 있는 기본 키 후보.

제4정규형 (4NF)

  • 목표: 다치 종속(Multi-valued Dependency)을 제거하는 것입니다.
728x90

데이터 정규화(Normalization)


데이터 정규화는 데이터베이스의 테이블을 가장 표준화된 방식으로 만드는 과정을 의미합니다. 이 과정의 핵심 목표는 데이터의 결함을 없애고 데이터의 중복을 제거하는 것입니다. 중복이 제거된 테이블 형태를 표준으로 보며 이 표준에 맞추기 위한 과정을 표준화, 정규화라고 합니다.


정규화가 필요한 이유

정규화의 가장 큰 목적은 데이터의 중복을 제거하여 나타날 수 있는 이상 현상을 방지하기 위함입니다. 이상 현상은 데이터를 삽입, 수정, 삭제할 때 예기치 않은 문제가 생기는 것을 말하며, 이상 현상의 내용은 아래와 같습니다.

  • 삽입 이상 (Insertion Anomaly): 불필요한 데이터가 없으면 새로운 데이터를 추가할 수 없는 문제입니다.
  • 갱신 이상 (Update Anomaly): 중복된 데이터 중 일부만 수정되어 데이터의 일관성이 깨지는 문제입니다.
  • 삭제 이상 (Deletion Anomaly): 특정 데이터를 삭제했을 뿐인데, 유지되어야 할 다른 정보까지 함께 사라지는 문제입니다.

정규화의 장점 

  • 데이터 중복 최소화: 중복되는 데이터를 제거하여 저장 공간을 효율적으로 사용합니다.
  • 데이터 무결성 보장: 정규회된 데이터는 중복이 없고 데이터의 정확성과 일관성이 향상됩니다.
  • 이상 현상(Anomaly) 방지: 데이터 정규화를 통하여 데이터 손실이나 불일치 위험을 줄입니다.
  • 구조의 유연성: 데이터베이스 구조를 변경하거나 확장하기 쉬워집니다.

데이터 정규화 과정 (1NF, 2NF, 3NF)

데이터 정규화는 여러 단계로 나뉘어 있으며, 일반적으로 제3정규형(3NF)까지 만족된다면 관계형 데이터베이스 설계로서 충분합니다.

제1정규형 (1NF: First Normal Form) :  테이블의 모든 컬럼은 반드시 '원자값(Atomic Value)'을 가져야 한다.

하나의 속성에는 오직 하나의 값만 저장될 수 있도록 테이블을 분해합니다.

제2정규형 (2NF: Second Normal Form) : 1NF를 만족하고, 모든 컬럼은 '기본 키(Primary Key) 전체'에 완전하게 종속되어야 한다. (부분 함수 종속 제거)

테이블의 주제와 관련 없는 데이터를 별도의 테이블로 분리하는 과정입니다.

제3정규형 (3NF: Third Normal Form) : 2NF를 만족하고, 기본 키가 아닌 모든 컬럼 간에는 서로 종속 관계가 없어야 한다. (이행적 함수 종속 제거)

일반 컬럼이 다른 일반 컬럼에 의해 결정되는 관계를 제거하는 과정입니다.


BCNF (Boyce-Codd Normal Form) : 테이블의 모든 결정자가 후보 키(Candidate Key)여야 한다.

3NF를 보완하는 강화된 정규형이며, 더욱 엄격한 기준을 가집니다.

  • 결정자(Determinant): 어떤 속성(컬럼)의 값을 결정하는 다른 속성. 즉, X → Y 라는 관계에서 X를 결정자라고 합니다. (X를 알면 Y를 알 수 있다)
  • 후보 키(Candidate Key): 테이블의 각 행을 유일하게 식별할 수 있는 속성의 최소 집합입니다. 기본 키(Primary Key)가 될 수 있는 후보들을 의미합니다.

어떤 값을 결정하는 키(결정자)는 그 자체로 기본 키가 될 자격이 있어야 한다는 강한 원칙입니다. 3NF는 이 규칙에 약간의 예외를 두지만 BCNF는 그 예외도 허용하지 않습니다.

 

 대부분의 경우 3NF를 만족하면 BCNF도 만족하므로, 일반적으로 3NF까지의 정규화를 목표로 합니다.

728x90

'CS' 카테고리의 다른 글

세션(Session)이란?  (1) 2025.08.03
Prisma ORM에 대하여  (0) 2025.08.02
클린 아키텍쳐(Clean Architecture)란?  (0) 2025.07.12
객체 지향이란?  (0) 2025.06.29
동기화와 비동기화  (0) 2025.06.20

Next.js와 데이터베이스

"use client" 지시어: 컴포넌트 파일 최상단에 "use client"를 선언하면, 해당 컴포넌트는 클라이언트(브라우저)에서 렌더링되고 실행됩니다. 이를 통해 useState, useEffect 같은 React Hook이나 브라우저 API를 사용할 수 있으며, 기존의 CSR 방식으로 개발 가능합니다. 이러한 CSR 방식을 사용할 경우, react-query와 같은 데이터 페칭 라이브러리를 적용하여 클라이언트 측에서 데이터를 관리할 수 있습니다.

서버 컴포넌트: "use client"가 없는 컴포넌트는 기본적으로 서버(Node.js 환경)에서 실행됩니다. 이는 데이터베이스 조회나 파일 시스템 접근 등 서버에서만 가능한 작업을 안전하게 처리하는 데 유리합니다.


실행 환경 구분: Next.js는 하나의 프로젝트 안에서 서버(Node.js 환경)와 클라이언트(웹 브라우저 환경) 코드를 모두 다룹니다.

 

이러한 Next.js는 핵심적인 렌더링 환경을 서버에서 사용할 것인지 웹에서 사용할 것인지 구분해야 하며, 이는 노드에서 사용할 것인지 브라우저에서 사용할 것인지 결정하는 것과 같습니다.

Link 컴포넌트와 Prefetch 기능

LinkPrefetch 기능은 Next.js의 사용자 경험을 극대화하는 요소입니다.

 
  • Link 컴포넌트: 페이지 간 이동을 위해 <a> 태그 대신 사용하는 Next.js의 기본 컴포넌트입니다. <a> 태그와 달리, Link 컴포넌트는 페이지 전체를 새로고침하지 않고 변경된 부분만 다시 그리는 클라이언트 사이드 네비게이션을 구현하여 매우 빠른 페이지 전환을 제공합니다.

  • Prefetch 기능: Link 컴포넌트의 핵심 기능 중 하나로, 사용자가 링크를 클릭하기 전에 해당 페이지에 필요한 데이터를 미리 불러오는 기술입니다. 화면에 Link 컴포넌트가 보이면 Next.js는 백그라운드에서 연결된 페이지의 코드와 데이터를 조용히 가져옵니다. 덕분에 사용자가 링크를 클릭했을 때, 거의 지연 시간 없이 즉시 페이지가 로드되는 것처럼 느껴집니다.

이미지 최적화 (<Image> 컴포넌트)

import Image from 'next/image'를 통해 사용하는 Image 컴포넌트는 웹 성능을 향상시킵니다.

 
  • 레이아웃 시프트(Layout Shift) 방지: 이미지가 로드될 공간을 미리 확보하여 이미지가 뒤늦게 로딩되면서 다른 요소들을 밀어내는 '레이아웃 시프트' 현상을 방지합니다.
     
  • 자동 최적화: 사용자의 기기(PC, 모바일 등)에 맞는 최적의 이미지 크기를 제공하고 WebP와 같은 최신 이미지 포맷으로 자동 변환하여 데이터 사용량을 줄이고 로딩 속도를 높입니다.

데이터베이스와 시스템 분석

시스템과 데이터의 본질

  • 시스템이란? 여러 구성 요소가 각자의 역할을 수행하며 유기적으로 결합된 집합체입니다. 만약 요소가 증거(데이터)를 남기지 않는 등 역할을 제대로 하지 않으면 시스템은 붕괴될 수 있습니다.
     
  • 데이터베이스: 정규화된 데이터의 베이스(기반)입니다.
     
  • 데이터의 의미: 시스템 안에서 발생하는 모든 행위의 '증거' 또는 '기록'입니다. 따라서 무엇을 데이터로 관리할지 결정하는 것은 "무엇을, 언제, 왜 저장하는가?"에 대한 답을 찾는 과정입니다.
     
  • 시스템 설계의 기준: 시스템을 만드는 기준은 결국 업무를 수행하는 사용자(액터)들의 행위, 즉 업무 로직(Business Logic) 입니다.
     

데이터 모델링 과정

데이터베이스를 설계하는 과정은 크게 3단계로 구성됩니다.

 
  1. 개념적 설계 (Concept Design): 업무적인 흐름을 분석하여 데이터베이스에 저장할 데이터를 선별하고, 각 요소(엔티티)와 그들 간의 관계를 정의하는 단계입니다.
    • 엔티티(Entity): 저장할 데이터의 대상. 다이어그램에서 사각형으로 표현됩니다. (예: 손님, 요리사, 메뉴)
    • 관계(Relation): 엔티티 간의 행위. 마름모로 표현됩니다. (예: 주문, 결제)
  2. 논리적 설계 (Logical Design): 개념적 설계의 결과를 관계형 데이터베이스(R-DB)의 테이블 구조로 변환하는 과정입니다. 이 단계에서 데이터 정규화가 이루어집니다.
     
  3. 물리적 설계 (Physical Design): 논리적 설계를 특정 DBMS(MySQL, PostgreSQL 등)의 실제 테이블 형태로 만드는 최종 단계입니다. 데이터 타입, 길이, 제약조건 등을 구체적으로 설정합니다.

데이터 정규화(Normalization)

  • 정규화란? 데이터베이스 테이블의 '표준화' 과정입니다. 데이터의 결함을 제거하고, 특히 중복을 제거하여 데이터의 일관성과 무결성을 확보하는 것을 목표로 합니다.
     
  • 목표: 중복이 제거된 파일(테이블) 형태가 표준이며, 그 표준에 맞추는 것이 정규화입니다.
728x90

 Next.js란 무엇인가?

  • 정의: React 라이브러리를 기반으로 구축된 오픈소스 풀스택(Full-stack) 웹 프레임워크입니다.

  • 핵심 개념: 프레임워크는 정해진 골격(구조)과 규칙을 제공하며, 개발자는 그 틀 안에서 코드를 작성합니다. 이는 라이브러리와의 가장 큰 차이점으로, 프레임워크가 코드의 흐름을 제어하는 '제어의 역전(IoC)' 개념이 적용됩니다.

제어의 역전 (IoC, Inversion of Control)

'제어의 역전'은 소프트웨어 공학의 중요한 원칙으로, 프레임워크를 이해하기 위해 도움이 됩니다.

전통적인 프로그래밍에서는 개발자가 작성한 코드가 프로그램의 전체 흐름을 직접 제어합니다. 그러나, 제어의 역전(IoC)에서는 프레임워크가 프로그램의 흐름을 주도하고, 개발자의 코드는 프레임워크에 의해 '호출'되어 사용됩니다. 이는 제어의 주체가 개발자에서 프레임워크로 넘어간(역전된) 것입니다.

  • 개발자의 집중도 향상: 개발자는 웹 서버를 만들고, URL을 분석하고, HTTP 요청을 처리하는 등 반복적이고 복잡한 기반 작업에 신경 쓸 필요가 없습니다. 프레임워크가 모두 처리해주므로, 오직 비즈니스 로직(실제 기능 구현)에만 집중할 수 있습니다.
  • 결합도 감소 (Decoupling): 컴포넌트나 모듈들이 서로에게 깊게 의존하지 않게 되어 코드를 더 모듈화하고 유지보수하기 쉬워집니다.
  • 재사용성 및 확장성 증가: 프레임워크라는 잘 짜인 구조 안에서 부품(컴포넌트)을 갈아 끼우기 쉽습니다. 새로운 기능을 추가하거나 기존 기능을 수정하기가 매우 용이해집니다.

 

 

Next.js를 사용하는 이유

  • 서버사이드 렌더링(SSR): 서버에서 페이지를 미리 그려 사용자에게 전달하므로, 초기 로딩 속도가 빠르고 검색 엔진 최적화(SEO)에 매우 유리합니다. (React는 전체 파일을 한 번에 보내지만, Next.js는 필요한 부분만 먼저 보냅니다.)

  • 파일 시스템 기반 라우팅: app 폴더 안에 폴더를 생성하면, 그 폴더명이 바로 URL 경로가 됩니다. React처럼 별도의 라우팅 설정이 필요 없어 직관적이고 편리합니다.

  • 최적화 기능: 코드 분할, 이미지 최적화 등 성능 향상을 위한 다양한 기능이 내장되어 있습니다.

프로젝트 구조와 컴포넌트 관리

  • app 폴더: 사용자가 요청하는 페이지(동적 문서)를 제공하는 핵심 공간입니다.

  • 컴포넌트 관리
    공용 컴포넌트: 여러 페이지에서 재사용되는 컴포넌트나 외부 라이브러리는 최상단에 components 폴더를 만들어 공동으로 관리하는 것이 효율적입니다.

    지역(특정 페이지) 컴포넌트: 해당 페이지에서만 사용되는 컴포넌트는 그 페이지 폴더 근처에 두어 관리하는 것이 좋습니다.

스타일링 (CSS)

  • global.css: app 폴더 내에 위치하며, 이름 그대로 프로젝트 전역에 적용될 공통 스타일을 정의합니다. 프레임워크의 규칙에 따라 이 파일명을 사용하는 것이 권장됩니다.

  • 저장 위치
    app 폴더: 컴포넌트와 함께 번들링되어 사용자에게 전달될 CSS 파일을 저장합니다. 애플리케이션 소스 코드를 저장하며,  폴더 안의 파일들은 컴포넌트와 함께 처리되고 번들링되어 최적화됩니다. 또한, Next.js가 빌드 시점에 코드를 분석하고 최적화하고 CSS 파일은 압축되어 이미지는 기기에 맞게 크기가 조절됩니다.

    public 폴더:
    서버에 저장해두고 직접 참조하는 이미지, 폰트 등 정적(Static) 파일을 보관하는 곳이며 파일 그대로 서버에 저장되고 제공됩니다. 특징으로는 Next.js가 코드를 압축하거나 최적화하지 않으며, 폴더 안의 경로가 그대로 URL 주소가 됩니다. (예: public/logo.png → 내사이트.com/logo.png)

 

 

728x90