MySQL 리뷰

영태·2022년 8월 8일
0

[REVIEW]

목록 보기
3/7
post-thumbnail

MySQL

  • mysql은 제가 가장 많이 사용한 RDBMS입니다
  • RDBMS로는 이 mysql밖에 쓰지 않아서 다른 RDBMS와 비교하거나 할 건 없지만 제가 사용하면서 겪은 경험이나 mysql의 특징, 또 넷상에서 다른 rdbms와의 차이점 등을 포스팅해 보겠습니다

SQL이란?

  • Structured Query Language의 줄임말로 RDBMS 상에서 데이터를 관리 및 처리하기 위해 설계된 언어
  • SQL을 데이터베이스라고 오인하기도 하지만 SQL은 물리적인 데이터베이스가 아닌 쿼리 언어이며 이를 활용한 관리 시스템이 RDBMS 입니다
  • SQL은 일종의 프로그래밍 언어, MySQL은 RDB를 관리하는 시스템인 RDBMS, 실재하는 데이터베이스가 바로 DB라고 할 수 있습니다. 따라서 이 세가지를 업무과정에서 DB라는 의미로 묶어서 틀리게 말할 수는 있지만 개념 자체는 구분해 인식하고 있어야 합니다.
  • SQL은 다음과 같이 4종류로 나뉩니다
    • DDL(Data Definition Language, 데이터 정의 언어)
      • 테이블과 같은 데이터 구조를 정의하는데 사용되는 명령어들로 데이터 구조와 관련된 명령어들을 말합니다
      • CREATE, ALTER, DROP, RENAME 등이 있습니다
    • DML(Data Manipulation Language, 데이터 조작어)
      • 데이터를 추가/수정/삭제하기 위한, 데이터 관리를 위한 언어입니다.
      • SELECT : 조회 혹은 검색을 위한 명령어
      • INSERT,UPDATE,DELETE 등 : 데이터에 변형을 가하는 종류의 명령어
    • DCL(Data Control Language, 데이터 제어어)
      • 데이터베이스에 접근하고 객체들을 사용하도록 권한을 주거나 회수하는 명령어를 말합니다
      • GRANT,REVOKE 등이 있습니다
    • TCL(Transaction Control Language, 트랜잭션 제어어)
      • 논리적인 작업단위를 묶어서 DML에 의해 조작된 결과를 트랜잭션(작업단위) 별로 제어하는 명령어를 말합니다
      • COMMIT,ROLLBACK,SAVEPOINT 등이 있습니다.

언급한 것들 이외에도 다양한 명령어가 있고, SQL의 특징을 세부적으로 다룰 수는 있지만 그것은 따로 포스팅하기로 하고 MySQL과 관계형 데이터베이스에 대해서 더 알아보겠습니다.

관계형 데이터베이스란?

RDB (관계형 데이터베이스)

  • RDBMS을 통해 데이터를 저장, 수정, 삭제 및 검색을 할 수 있습니다

  • 이 관계형 데이터베이스에는 두 가지 특징이 있습니다

    • 첫번째는 데이터가 정해진 데이터 스키마에 따라 테이블에 저장된다는 점입니다

      • 이 말은 스키마를 준수하지 않은 기록을 테이블에 추가할 수 없다는 뜻입니다
      • 정해진 구조에 맞는 레코드만 추가가 가능하다는 점이 관계형 데이터베이스의 특징 중 하나입니다
      		@Entity()
      		export class Feed {
      		  @PrimaryGeneratedColumn('increment')
      		  id: number;
      	  
      		  @Column('varchar')
      		  title: string;
      	
      		  @Column({ type: 'mediumtext' })
      		  content: string;
      	
      		  @CreateDateColumn()
      		  createdAt: Date;
      	
      		  @UpdateDateColumn()
      		  updatedAt: Date;
      	
      		  @DeleteDateColumn()
      		  deletedAt: Date;
      		}
      • 다음과 같이 typeorm을 이용해 entity를 미리 정의해주고 DDL SQL문을 통해 등록하면 위에서 정한 규격의 레코드만 추가가 가능하게 됩니다
    • 두번째로, SQL에서 데이터는 관계를 통해 여러 테이블에 분산됩니다

      • 데이터의 중복을 피하기 위해 관계를 사용합니다
      • 하나의 테이블에서 중복 없이 하나의 데이터만 관리하기 때문에 다른 테이블의 데이터와 섞일 위험이 없어집니다
        @ManyToOne(() => User, { onDelete: 'CASCADE', eager: true })
        	user: User;
      • 다음과 같이 관계설정을 해주면 다른 테이블의 데이터와 중복될 여지가 없으면서 JOIN하는 것이 가능합니다
  • 장점

    • 명확하게 정의된 스키마
    • 데이터 무결성 보장
    • 각 데이터를 중복없이 한번만 저장
  • 단점

    • 덜 유연하다. 데이터 스키마를 사전에 계획하고 알려야한다
    • 관계를 맺고 있어서 조인문이 많은 복잡한 쿼리가 만들어질 수 있다
    • 대체로 수직적 확장만 가능하고 수평적 확장은 불가능하다

그렇다면 관계형DB가 아닌 NoSQL은 어떤 특징이 있을까요?

NoSQL

  • 반대로 NoSQL에는 관계도 없고 스키마도 없습니다

  • 백엔드 단에서 스키마를 정해줄 수는 있지만, SQL에서는 스키마를 따르지 않으면 데이터 추가를 차단하는데 반해, NoSQL에서는 다른 구조의 데이터들을 같은 컬렉션에 추가할 수 있습니다

  • 조인이라는 개념이 존재하지 않기 때문에 조인할 필요없이 모든 것을 갖춘 문서를 작성해야하는 것이 NoSQL입니다

  • 따라서 조인을 잘 사용하지 않고 자주 변경되지 않는 데이터일 때 NoSQL을 사용하면 상당히 효율적이라고 할 수 있습니다

  • 컬렉션간의 조인을 하고 싶다면 데이터가 중복되어 서로 영향을 줄 위험이 있습니다

  • 장점

    • 스키마가 없어서 유연하다
    • 언제든지 저장된 데이터를 조정하고 새로운 필드를 추가할 수 있다
    • 데이터는 애플리케이션이 필요로 하는 형식으로 저장되며, 따라서 읽어오는 속도가 빠르다
    • 수직 및 수평 확장이 가능하다 애플리케이션이 발생시키는 모든 읽기/쓰기 요청이 처리가 가능하다
  • 단점

    • 유연성으로 인해 데이터 구조 결정을 미루게 될 수 있다
    • 데이터 중복을 계속 업데이트 해야한다
    • 데이터가 여러 컬렉션에 중복되어있기 때문에 수정 시 모든 컬렉션에서 수정해야 한다

그럼 어떨 때 SQL을 사용해야하고 어떨 때 NoSQL을 사용하는 것이 좋을까?

  • SQL 사용이 좋을 경우

    • 관계를 맺고 있는 데이터가 자주 변경되는 애플리케이션의 경우
    • 변경될 여지가 없고, 안정적이고 명확한 스키마가 사용자와 데이터에게 중요한 경우
  • NoSQL 사용이 좋을 경우

    • 정확한 데이터 구조를 알 수 없거나 변경/확장 될 수 있는 경우
    • 읽기를 자주 하지만 데이터 변경은 자주 없는 경우
    • 데이터베이스를 수평으로 확장해야 하는 경우 (막대한 양의 데이터를 다뤄야하는 경우)

관계형 데이터베이스를 사용한 이유

  • 스키마를 준수하지 않은 레코드를 추가할 수 없기 때문에 정해진 구조에 맞는 레코드만 추가가 가능해 명확한 데이터 구조와 데이터의 무결성을 보장합니다
  • 또 관계를 설정하기 때문에 한 테이블에서 중복 없이 하나의 데이터만 관리할 수 있고 다른 테이블의 데이터와의 중복을 피할 수 있습니다
  • 데이터에 접근하는 가장 보편적인 수단인 SQL 인터페이스를 사용하기 때문에 SQL을 통해서 다양한 데이터에 대한 수월한 접근이 가능합니다
  • 관계를 통해 외래 키를 이용한 테이블간의 join이 가능합니다
  • 사용한 경험(example)
    - 제가 한 프로젝트 중에서 RDB를 사용한 프로젝트는 온도의 프로젝트와 SNS 프로젝트 등이 있었는데, 이 프로젝트들은 테이블들이 가지고 있는 데이터가 중복될 수 있는 여지가 있었습니다.
    - 또한 join을 사용해야 하는 경우였는데 두 개이상의 테이블을 담아서 리턴해야 하는 경우 join을 사용해야하기 때문에, 게시글과 함께 유저정보를 리턴해야하거나 게시글이 가지고 있는 여러 이미지 URL들을 함께 리턴해줘야할때 join을 활용하기 위해 자연스럽게 RDB를 사용했던 것 같습니다
  • 다음과 같이 여러 관계가 필요한 애플리케이션에서는 관계형 데이터베이스를 사용해야 했습니다
  • NoSQL 중에서는 redis와 mongoDB를 잠깐 사용해본 경험이 있습니다
    • mongoDB에서도 다음과 같이 스키마를 설정해주고 mongoose를 통해 collection을 만들었었습니다
      import mongoose from 'mongoose';
      const userSchema = new mongoose.Schema(
        {
            name: String,
            email: String,
            phone: String,
            personal: String,
            prefer: String,
            pwd: String,
            og: Object,
        },
        { versionkey: false },
      );
      export const User = mongoose.model('User', userSchema); //collection 만들기
    • 다만 이렇게 스키마를 만든다고 해도 데이터를 추가할 수 있어서 데이터 무결성을 원한다면 RDB를 쓰는게 낫습니다
    • 두번째로 위와 같은 구조에서는 join의 개념이 없고 관계의 개념이 없어 그저 user라는 객체 정보가 저장될 뿐이며 데이터의 중복이 일어날 수 있다는 단점이 있습니다.
    • 따라서 mongoDB가 아닌 관계형 DB를 선택했고 mongoDB같은 NoSQL은 속도는 빠르기 때문에 채팅같은 서비스에서 사용하면 좋겠다는 생각을 했었습니다

RDBMS 중에서 MySQL을 선택한 이유

  • mysql은 일단 오픈 소스이기에 무료로 사용할 수 있고 가장 널리 알려진 표준 SQL 형식을 사용한다는 점에서 RDB를 공부하는 입장에서 도입하기 가장 적합하다고 판단했습니다

  • 세부적인 장점은

    • 구조가 간단하기 떄문에 빠릅니다
    • 유연하고 확장 가능한 구조를 가지고 있습니다 (다만 이점은 의문을 가지고 있는 사람들이 많습니다)
    • 다중 사용자와 다중 스레드를 지원합니다
    • 많은 유저들이 사용하기 때문에 관련 커뮤니티에 사용 경험에 관한 정보나 레퍼런스할 정보들이 많다는 점이 장점입니다
    • 트랜젝션에 있어서 좋은 평판을 받고 있습니다. 데이터 무결성을 필요로 하는 사용자에게 적합하다고 생각하여 사용했습니다.
    • 디폴트 고립수준이 repeatable-read로 좀 더 높은 고립수준을 가지고 있어 더 일관성 있는 데이터를 가져올 확률이 높습니다
  • 단점

    • 오라클이 30년째 개발되고 있는데 반해 역사가 깊지 않습니다
    • 새로 추가된 기능들은 충분히 안정화되지 않았습니다
    • 인증된 개발자/운영자나 공인 파트너사가 부족하고 오라클이나 MS에 비해 규모가 작긴 해서 신뢰도가 다소 떨어집니다
  • 추가

    • 마리아DB
      • 비교적 최근의 오픈소스라서 커뮤니티가 더 활발하고 MySQL이 오라클에 인수되면서 영리 목적이 된 탓에 마리아 DB를 권장하는 글을 본적이 있습니다
      • mysql과 비교했을때 큰 차이점이 없어 공부 목적으로 사용한다면 mariaDB를 사용하는 것도 다르지 않을 것이라는 생각이 있습니다
    • Postgresql
      • 다양한 index 방식을 사용하고 이를 위주로 업데이트하고 있습니다 따라서 더 전문적으로 활용 가능한 RDBMS라고 생각합니다
      • 동시성 제어에 있어서 성능 우위를 지닙니다. 동시 데이터 작업이 진행되더라도 모든 동작을 기록해두고 가장 마지막 작업 결과를 최종값으로 인식합니다.
      • locking에 의한 병목이 생기지 않기 때문에 속도에서 우위를 가집니다
      • 다만 update 시에 과거 행을 삭제하고 데이터를 추가하기 떄문에 이점은 성능이 좋지 않습니다
      • 디폴트 격리수준이 read-committed입니다 좀 더 낮은 격리수준을 가지고 있습니다

정리

SQL

  • RDBMS 상에서 데이터를 관리 및 처리하기 위해 설계된 언어

RDB

  • 정해진 스키마에 따라 데이터가 저장되고 이를 준수하지 않은 데이터는 저장되지 않는다 이를 통해 데이터를 보다 무결하게 관리할 수 있다
  • 데이터를 관계를 통해 분산시키는데 이 관계를 통해 테이블간의 데이터 중복을 방지하고 JOIN을 할 수 있게 해준다.

NoSQL

  • 관계도 없고 스키마도 없고
  • class를 설정해 스키마를 정해줄순 없지만 컬렉션에 문서가 추가되는걸 막아주진 않기때문에 무결하지 않다
  • 조인과 관계의 개념이 존재하지 않기에 모든것을 갖춘 문서를 작성해한다
  • 속도가 RDB보다 빠르다

RDB를 선택한 이유

  • 명확한 데이터 구조와 무결성
  • SQL 인터페이스를 통한 쉬운 데이터 접근
  • 관계
    • 외래 키를 이용한 테이블간의 join이 가능 (가장 큰 이유)
    • 데이터 중복을 방지

MySQL을 선택한 이유

  • 오픈 소스라 무료로 이용가능
  • 가장 널리 알려진 표준 SQL 형식을 사용
  • 구조가 간단해서 빠름
  • 다중 사용자와 다중 스레드를 지원
  • 적당한 용량
  • 트랜잭션에 있어서 좋은 평판
    • 디폴트 고립수준이 repeatable-read로 더 높은 고립수준을 가지고 있다
profile
개발 공부중

0개의 댓글