Day 20 - DBMS, PK/FK, 정규화, MySQL Workbench

이유승·2024년 11월 25일
0

* 프로그래머스, 타입스크립트로 함께하는 웹 풀 사이클 개발(React, Node.js) 5기 강의 수강 내용을 정리하는 포스팅.

* 원활한 내용 이해를 위해 수업에서 제시된 자료 이외에, 개인적으로 조사한 자료 등을 덧붙이고 있음.

1. DB, DBMS

RDBMS는 왜 사용하는가?

  • 데이터가 표로 관리되어 데이터를 직관적으로 조회할 수 있고, 테이블 사이의 관계를 명확하게 정의할 수 있다.

  • 사용자가 데이터를 이해하기 쉽고, SQL을 통해 복잡한 DB를 제어하는 것도 간편하다.

  • 대규모 데이터를 처리하거나 새로운 테이블을 추가하는 등의 확장도 용이.

  • 특히 오랜 시간 동안 표준으로 자리 잡아 다양한 도구와 라이브러리, 커뮤니티 지원이 활발하다.



2. PK/FK

PK (Primary Key)

  • 테이블에서 각 행(row)을 고유하게 식별하는 데 사용되는 필드.
  • 값이 중복되어서는 안되고, 값이 없거나 NULL값으로 처리될 수도 없다.
    - 예: 회원 테이블의 id

FK (Foreign Key)

  • 한 테이블의 특정 필드가 다른 테이블의 Primary Key를 참조하여 테이블 간의 관계를 정의
    - 예: 주문 테이블의 user_id가 회원 테이블의 id를 참조



3. 정규화Normalization

  • 데이터의 중복을 최소화하고, 데이터 무결성을 유지하기 위해 테이블을 체계적으로 분리하는 과정.

1NF (제 1 정규형): 각 컬럼이 원자값(더 이상 나눌 수 없는 값)을 가져야 함
2NF (제 2 정규형): 부분적 종속성 제거 (모든 컬럼이 기본키에 완전히 종속)
3NF (제 3 정규형): 이행적 종속성 제거 (기본키가 아닌 다른 컬럼에 종속된 컬럼 제거)

  • 데이터베이스의 크기가 커질수록, 데이터의 CRUD 효율성은 점차 감소하게 된다.

  • 모든 데이터가 하나의 테이블에 모여있으니, 컬럼 하나를 추가하고 수정하고 삭제하는데 다른 수많은 컬럼들까지 신경써주어야 한다.

  • 그렇기에 테이블은 적절한 기준에 따라서 체계적으로 분리되어야 한다.



테이블 분리의 장점과 단점

테이블 분리의 장점

  • 데이터 중복 제거로 저장 공간 절약
    - 가령 회원/주문 테이블이 분리되어있지 않을 때, 하나의 회원이 여러 주문을 요청한다면? 동일한 회원 데이터가 중복으로 저장된다.
  • 데이터 무결성 유지
  • 데이터 수정 시 일관성 보장
    - 테이블이 적절하게 분리되어 있다면, 하나의 데이터만 수정해주어도 참조 관계에 놓인 다른 테이블들은 손을 댈 필요가 없다.

테이블 분리의 단점

  • 테이블이 많아져서 쿼리가 복잡해질 수 있음
  • 조인 연산이 많아지면 성능 저하 가능



장점 예시

CREATE TABLE customer_orders (
    customer_id INT,
    customer_name VARCHAR(50),
    email VARCHAR(100),
    order_id INT,
    order_date DATE,
    product_name VARCHAR(100),
    quantity INT
);
  • 한 고객이 여러 번 주문하면, customer_name과 email 같은 정보가 반복적으로 저장된다.

  • 이런 상황에서 데이터를 수정해야 한다면? 중복된 모든 데이터들을 다 업데이트해주어야 한다.

  • 이 과정에서 하나라도 실수가 발생하면 데이터 불일치로 문제가 발생하게 된다.
  • 더구나 나중에 테이블에 새로운 속성(예: 전화번호)을 추가되면? 이전에 저장되어 있던 데이터를 모두 수정해주어야 한다.
-- 고객 테이블
CREATE TABLE customers (
    customer_id INT PRIMARY KEY,
    customer_name VARCHAR(50),
    email VARCHAR(100)
);

-- 주문 테이블
CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    customer_id INT,
    order_date DATE,
    product_name VARCHAR(100),
    quantity INT,
    FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);
  • 그런데, 테이블을 이렇게 분리해주면?

  • 고객 정보는 customers 테이블에 한 번만 저장되고, 주문 정보를 추가해도 customer_name과 email이 중복되지 않는다.



단점 예시

SELECT c.customer_name, o.product_name
FROM customers c
INNER JOIN orders o
ON c.customer_id = o.customer_id;
  • 분리된 테이블을 사용할 경우, 데이터를 조회하려면 여러 테이블을 조인(Join)해주어야 한다.

  • 테이블이 많아질수록 쿼리가 복잡해지고 성능이 저하될 수밖에 없다는 것.

SELECT c.customer_name, o.product_name, p.payment_status
FROM customers c
INNER JOIN orders o ON c.customer_id = o.customer_id
INNER JOIN payments p ON o.order_id = p.order_id;
  • 테이블이 3가지만 되어도 쿼리문이 상당히 복잡해진다. DBMS의 성능도 더욱 떨어지게 된다.
INSERT INTO customers (customer_id, customer_name, email)
VALUES (2, 'Jane Smith', 'jane@example.com');

INSERT INTO orders (order_id, customer_id, order_date, product_name, quantity)
VALUES (102, 2, '2024-11-02', 'Smartphone', 2);
  • 여기에 데이터를 삽입하는 로직도 복잡해진다. 테이블이 많아질 수록 INSERT 쿼리문도 증가하기 때문.



데이터베이스 테이블 간 관계 유형

  • 데이터베이스의 테이블들을 설계할 때, 각 테이블들이 서로 어떤 관계에 놓여있는지 유형을 올바르게 설계할 필요가 있다.

  • 관계의 유형을 올바르게 설계하면 데이터베이스의 효율성과 무결성이 높아지기 때문.

  • 이를 경시할 경우, 다음과 같은 문제가 생길 가능성이 높아진다.
    - 동일한 데이터가 여러 테이블에 중복 저장.
    - 데이터 간의 논리적 관계가 없음.
    (고객 데이터가 삭제되었지만, 해당 고객의 주문 데이터가 남아있네?)
    - 데이터 검색 및 조작 시 비효율적인 쿼리가 발생.
    - 새로운 요구사항에 유연하게 대처하지 못함.
    (테이블 하나를 추가해야하는데, 이전에 구현한 다른 테이블 구조를 모조리 뜯어고쳐야한다고?)
    - 삽입, 삭제, 수정 작업에서 이상(Anomalies)이 발생할 수 있다.
    (테이터 하나를 추가해야하는데, 쓰지도 않을 더미 데이터를 넣어주어야 한다 / 데이터를 하나 지우는데, 다른 데이터까지 같이 지워진다 / 중복되어있는 모든 데이터를 수정해야하는데, 일부 데이터가 수정이 누락된다.)

1:1 관계 (One-to-One)

  • 한 테이블의 한 행이 다른 테이블의 한 행과 연결되는 관계.
CREATE TABLE users (
    user_id INT PRIMARY KEY,
    name VARCHAR(50)
);

CREATE TABLE user_details (
    user_id INT PRIMARY KEY,
    address VARCHAR(100),
    phone VARCHAR(20),
    FOREIGN KEY (user_id) REFERENCES users(user_id)
);

사용자 (user_id) → 사용자 상세정보 (user_id)



1:N 관계 (One-to-Many)

  • 한 테이블의 한 행이 다른 테이블의 여러 행과 연결되는 관계.
CREATE TABLE customers (
    customer_id INT PRIMARY KEY,
    name VARCHAR(50)
);

CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    customer_id INT,
    order_date DATE,
    FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);

고객 (customer_id) → 주문 (customer_id)



M:N 관계 (Many-to-Many)

  • 한 테이블의 여러 행이 다른 테이블의 여러 행과 연결되는 관계.
CREATE TABLE students (
    student_id INT PRIMARY KEY,
    name VARCHAR(50)
);

CREATE TABLE courses (
    course_id INT PRIMARY KEY,
    course_name VARCHAR(100)
);

CREATE TABLE student_courses (
    student_id INT,
    course_id INT,
    PRIMARY KEY (student_id, course_id),
    FOREIGN KEY (student_id) REFERENCES students(student_id),
    FOREIGN KEY (course_id) REFERENCES courses(course_id)
);

학생 (student_id) ↔ 강의 (course_id)



4. MySQL Workbench

  • MySQL 데이터베이스를 설계, 모델링, 관리, 쿼리 실행, 그리고 데이터 시각화를 제공하는 GUI 기반의 도구.

주요 기능

  • ERD 작성: 데이터베이스 설계 및 테이블 관계 시각화
  • 쿼리 실행: SQL 쿼리를 작성하고 실행할 수 있는 에디터 제공
  • 데이터베이스 관리: 사용자 관리, 데이터베이스 설정 변경, 백업 등
  • 모델링 도구: 기존 데이터베이스를 가져와서 모델링 가능

장점

  • 사용자 친화적 GUI 제공
  • 쿼리 실행 결과를 바로 확인 가능
  • 데이터베이스 설계 및 관리에 필요한 다양한 도구 포함

사용 방법

  • 데이터베이스 연결 (Connection 생성)
  • SQL Editor에서 쿼리 작성 및 실행
  • Schema 창에서 테이블, 뷰, 프로시저 등을 확인 및 수정
profile
프론트엔드 개발자를 준비하고 있습니다.

0개의 댓글