Dev/Mysql(MariaDB)

Database Modeling(DB Schema, 정규화)

OK-가자 2021. 10. 5. 15:52

DBMS (데이터 베이스) 설계

  • 어떤 데이터를 저장할 것인가?
  • 음원검색 ( 네이버 뮤직 )

  • 데이터베이스 설계를 하는 주된 목적
  • 중복성 제거
  • 정규화 (Normalization)
  • 데이터베이스 설계를 도식화한 도표
    • 엔티티(entity), 속성(attribute), 관계(relation)
    • 3가지 요소로 구성
  • 엔티티(entity)
    • 데이터가 저장되어야 하는 중요한 사물, 물체
    • 엔티티에 대한 정보는 속성, 관계의 폼으로 저장
  • 엔티티 속성(attribute)
    1. 엔티티의 정보들 (0 혹은 여러개)
    2. 엔티티 인스턴스(테이블에서의 열)는 각각 정확하게 하나의 값
    3. 또는 NULL(empty)일 수 있다.
      1. 각 속성의 값은 숫자, 문자열, 날짜, 시간, 혹은 다른 기본적인 데이터의 값
  • 어떤 것이 엔티티 이고 속성 일까?

  • 엔티티 네이밍 규칙
    엔티티 이름은 단수
  • 각 엔티티는 하나의 인스턴스로 명명

정규화

  • E.F.Codd의 정규화 개념 (1970년대)
  • 오늘날도 정규화의 목적은 동일
    • 데이터의 중복성을 제거
    • 갱신이상(update anomalies) 회피
  • 데이터 모델을 좀 더 구체적으로 해준다
  • 어떤 것이 엔티티 이고 속성 일까?

첫 번째 데이터 모델 (1NF)

  • 엔티티 네이밍 규칙
  • 엔티티 이름은 단수
  • 각 엔티티는 하나의 인스턴스로 명명

두 번째 데이터 모델

  • 1NF로 두 개의 엔티티가 생김
  • 속성의 중복성 제거
  • 두 엔티티간의 연관되는 어떤 방법이 필요
  • 관계(relation) 이 필요

유일한 식별자

  • 각각의 엔티티는 ID라고 불리는 유일한 식별자를
    가져야 한다.
  • ID는 다음 규칙을 가지는 엔티티의 속성
    • 엔티티의 모든 인스턴스에 유일
    • 인스턴스의 전체 라이프 타임 동안 NULL이 아니어야 한다.
    • 전체 라이프 타임 동안 변하지 않는 값
  • ID는 관계를 모델링 하기위한 중요 요소

세 번째 데이터 모델

  • 식별자 결정의 문제점
  • 엔티티와 전혀 무관한 인위적으로 만들어 냄

관계(Relation)

  • 엔티티 안에 존재하는 식별자는 엔티티 사이의 관계를 설정할 수 있게한다.
  • 관계안에서 설정된 엔티티는 각각에 대해 설명이 되고 관계 양단에는 이름(name)과 정도(degree)를 가진다

  • Entity1은 entity2와 [일대일 | 일대다] 관계를 갖는다
    1. 학생은 반과 ? 관계를 갖는다
    2. 반은 학생과 ? 관계를 갖는다

네 번째 데이터 모델 (1NF 완성)

  • 반복되었던 노래 속성이 새로운 엔티티로 정규화
  • 앨범과 노래간의 관계가 모델화

정규화 - 제 2정규화(2NF)

  • 하나의 엔티티가 이미 1NF로 되어 있고 모든 식별되지 않은 속성들이 엔티티의 유일한 식별자에 종속적이면 “제 2 정규형(2nd Normal form)” 이라 한다.
  • 앨범 엔티티의 가수이름은 앨범ID에 완전히 종속적이지 못하다.
    (씨스타는 두 개의 다른 CD의 가수 이름이다).
  • “가수이름은 무엇으로 나타나야 하는가?”

다섯 번째 데이터 모델

여섯 번째 데이터 모델

일곱 번째 데이터 모델

관계의 종류

  • 두 엔티티간의 양방향을 결정하는 것은 매우 중요
  • 1:1 (one-to-one, 1-to-1)
    매우 드물다
    음원 검색에서는 안 나타난다.
  • 1:M (one-to-many, 1-to-M)
    한 방향이 1:M, 다른 방향이 1:1 인 경우
    가장 흔하다.
  • M:M (many-to-many, M-to-M)
    양방향이 1:M인 경우
    음원 검색에서는 여섯 번째 데이터 모델

관계의 재정립

  • 1:1 (one-to-one, 1-to-1)
    • 설계 자체를 다시 점검해 볼 필요가 있음
    • 두 엔티티가 동일한 엔티티일 가능성을 함축
  • 1:M (one-to-many, 1-to-M)
    • 새로운 엔티티(교차 엔티티)를 생성하고 적당한 이름을 정한다. -> AritistAlbum
    • 새로운 엔티티를 원래의 두 개의 엔티티와 관계를 맺는다 -> 각 각의 원래 엔티티는 교차 엔티티와 1:M의 관계를 맺는다.여덟 번째 데이터 모델(2NF완성)사진

정규화 – 제 3 정규형(3NF)

  • 하나의 엔티티가 이미 2NF로 되어 있고 식별할 수
    없는 어떠한 속성도 어떤 다른 식별할 수 없는 속성들에게 종속적이지 않으면 “제 3 정규형(3nd Normal form)” 이라 한다.
  • 식별할 수 없는 다른 속성들에게 종속적인 속성들은 종속적인 속성과 새로운 엔티티에 종속적인 속성으로 이동

3NF 위반 데이터 모델

아홉 번째 데이터 모델 (3NF 완성)

물리 데이터베이스 설계

  • 논리적인 데이터 모델링을 하는 이유는 무엇인가?
  • 어떻게 이루어지는가?
    postgresSQL, mySQL, Oracle 등의 DBMS가 각각 정의한 SQL문들의 집합으로 변환
  • 규칙
    1. 엔티티는 물지적인 데이터베이스의 테이블
    2. 속성은 물리적 데이터베이스의 행(column)
    3. 유일한 식별자는 NULL 값이 될 수 없다.
      물리적 데이터베이스에서 Primary Key가 된다
    4. 관계에서 “일(one)”부분에 있는 Primary Key를 “다(many)”
      부분의 테이블에 배치함으로 맵핑
    5. 매핑된 속성은 Foreign Key가 된다.

SQL 변환(테이블생성스크립트)

 

-- MySQL Workbench Forward Engineering

SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';

-- -----------------------------------------------------
-- Schema cdmall
-- -----------------------------------------------------

-- -----------------------------------------------------
-- Schema cdmall
-- -----------------------------------------------------
CREATE SCHEMA IF NOT EXISTS `cdmall` DEFAULT CHARACTER SET utf8 ;
USE `cdmall` ;

-- -----------------------------------------------------
-- Table `cdmall`.`company`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `cdmall`.`company` ;

CREATE TABLE IF NOT EXISTS `cdmall`.`company` (
  `no` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(45) NOT NULL,
  `address` VARCHAR(45) NULL,
  PRIMARY KEY (`no`))
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `cdmall`.`album`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `cdmall`.`album` ;

CREATE TABLE IF NOT EXISTS `cdmall`.`album` (
  `no` INT(11) NOT NULL AUTO_INCREMENT,
  `title` VARCHAR(100) NOT NULL,
  `company_no` INT NOT NULL,
  PRIMARY KEY (`no`),
  CONSTRAINT `fk_album_company1`
    FOREIGN KEY (`company_no`)
    REFERENCES `cdmall`.`company` (`no`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `cdmall`.`artist`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `cdmall`.`artist` ;

CREATE TABLE IF NOT EXISTS `cdmall`.`artist` (
  `no` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`no`))
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `cdmall`.`song`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `cdmall`.`song` ;

CREATE TABLE IF NOT EXISTS `cdmall`.`song` (
  `no` INT(11) NOT NULL AUTO_INCREMENT,
  `title` VARCHAR(100) NOT NULL,
  `length` INT NULL,
  `album_no` INT(11) NOT NULL,
  `artist_no` INT NOT NULL,
  PRIMARY KEY (`no`),
  CONSTRAINT `fk_song_album`
    FOREIGN KEY (`album_no`)
    REFERENCES `cdmall`.`album` (`no`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_song_artist1`
    FOREIGN KEY (`artist_no`)
    REFERENCES `cdmall`.`artist` (`no`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `cdmall`.`genre`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `cdmall`.`genre` ;

CREATE TABLE IF NOT EXISTS `cdmall`.`genre` (
  `no` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(45) NOT NULL,
  `abbr` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`no`))
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `cdmall`.`genre_song`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `cdmall`.`genre_song` ;

CREATE TABLE IF NOT EXISTS `cdmall`.`genre_song` (
  `song_no` INT(11) NOT NULL,
  `genre_no` INT NOT NULL,
  CONSTRAINT `fk_genre_song_song1`
    FOREIGN KEY (`song_no`)
    REFERENCES `cdmall`.`song` (`no`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_genre_song_genre1`
    FOREIGN KEY (`genre_no`)
    REFERENCES `cdmall`.`genre` (`no`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;

'Dev > Mysql(MariaDB)' 카테고리의 다른 글

ERD, 계정 생성, 포워드 엔지니어링 정리  (0) 2021.10.05
MariaDB - DML  (0) 2021.10.05
MariaDB - 데이터타입과 DDL  (0) 2021.10.05
MariaDB - 데이터 검색 (SUBQUERY)  (0) 2021.10.05
MariaDB - 데이터 검색 (JOIN)  (0) 2021.10.05