신승근 멘토님, DataBase Structure 특강

Aug 30, 2019


  • Data Driven Programming
  • 6개월 8억 -> 2개월 2억
  • 남의 것을 인정하지 않는 문화
  • 기본이 충실한 프로그래밍
    • 부동소수점
    • Data = Const + Variable / Data 의 저장공간은?
  • 스타트업 비즈니스에 대한 이해
  • ‘로그인’ - ‘회원’ 테이블은 다르다
  • 클러스터 인덱스
    • 대체키
    • VARCHAR vs CHAR
    • 인덱스
    • B-Tree
  • 용어 정리
    • 2 페이스 커밋 (two-phase commit)
    • I/O 페이스
    • 정규형
    • Relation = Table 간의 관계
    • Strong Entity / Weak Entity
    • DB lock 이 걸리는 경우, ‘insert & update’
  • 책 추천
    • ‘관계형 데이터베이스 실전 입문’


Data Driven Programming

  • ‘Algorithm + Data Structure = Programming’ - 니클라우스 에밀 비르트

    • 멘토님이 감명 깊게 읽은 책
  • 데이터 중심 프로그래밍

    • 데이터를 생각하면서 프로그래밍을 한다.

    • 예를들어, ‘한 학년의 수학 과목 점수를 계산하라’ 라는 프로그램을 짠다고 하면,

      ...
      for(int i = 0; i < NUM; i++) {
      	sum += 수학[i];
      }
      ...
      
      • 만약, 영어 점수의 합계도 구하라고 한다면?
      ...
      for(int i = 0; i < NUM; i++) {
      	sum += 수학[i];
      }
          
      for(int i = 0; i < NUM; i++) {
      	sum += 영어[i];
      }
          
      // 이렇게 할 것인가?
      ...
      
      • 데이터를 생각하고 자료구조를 사용하면 더 효율적인 프로그래밍이 가능하다!
      ...
      int[] sumArr = new int[2];
          
      for(int i = 0; i < NUM; i++) {
      	sumArr[0] += 수학[i];
      	sumArr[1] += 영어[i];
      }
      ...
      
  • Data = ?

    • Const + Variable
    • 상수와 변수로 이루어져 있다.
    • 상수는 코드상에 저장이 되고, 변수는 stack / heap 에 저장된다.
    • 상수를 굳이 코드상에 녹여야 하나? (DB에 저장해서 사용하면 안될까?)


6개월 8억 -> 2개월 2억

‘너무 너무 느린 프로그램에 관한 의뢰가 들어왔다. 문제를 찾다보니, 프로그램이 메모리보다 큰 문제가 있었다. RAM을 추가하는 방법으로 문제를 해결했다.’

  • 프로그램이 잘 돌아가는 상태에서 굳이 코드를 손봐야 하는가?
  • 문제가 뭔지 정확히 알고, 해결할 수 있으면 된다.


남의 것을 인정하지 않는 문화

‘아침에 다른 개발자와 했던 이야기를 저녁에 나에게 와서 마치 자신의 아이디어 인 마냥 말하더라’

  • 본인이 연구한 결과일 수 있지만, 분명 어떤 책이든, 세미나 든, 블로그 든 정보를 얻은 경로가 있을 것이다. 100% 본인의 산출물이 존재하기는 어렵다.
  • 서로 존중하고, 상대방의 아이디어나 생각을 인정하며 배려하는 문화가 중요하다.
  • 실리콘 벨리에서는 실패한 기업의 아이디어를 연구한다. 그 아이디어를 7단계만 거쳐서 바꾸면 논문이 하나 나오고, 독창적인 아이디어가 된다.
  • 그 아이디어를 생각한 이유가 있을 것이고, 그 생각에 대한 존중이 있기 때문에, 실패했다고 한들 연구하는 것.


기본이 충실한 프로그래밍

‘그래프를 그리는 프로그램을 검수한 적이 있다. 중간 중간에 선이 미세하게 끊어진 곳이 있어 원인을 찾아보니, 그래프를 그리는 변수를 ‘float’ 형으로 구현을 해놓은 것을 확인했다.’

  • float 형은 부동소수점
  • 4bit 짜리 메모리가 있다고 할 때, 정수 표현은 ‘0~15’ 까지 가능하다. 실수는 어떨까? ‘1/2’, ‘1/4’, ‘1/8’ … 사이 사이 끊어져서 표현 할 수 밖에 없다.


프로그래밍에서 실수의 표현 방식

컴퓨터에서 실수를 표현하는 방법은 정수에 비해 훨씬 복잡하다.

왜냐하면, 컴퓨터에서는 실수정수와 마찬가지로 2진수로만 표현해야 하기 때문이다.

(2진수로 표현하게 되면 모든 소수를 표현하기 어렵다.)

연구 끝에 현재는 2가지 방식으로 실수 표현을 사용하고 있다.

  • 고정 소수점 (fixed point)
  • 부동 소수점 (floating point)



고정 소수점 방식

실수는 보통 정수부와 소수부로 나눌 수 있다. (ex, ‘171.79’ … )

따라서 실수를 표현하는 가장 간단한 방식은 소수부의 자릿수를 미리 정하여, 고정된 자릿수의 소수를 표현하는 것.

  • 32 bit 방식일 때
    • 부호 : 1bit
    • 정수부 : 15bit
    • 소수부 : 16bit

하지만 이 방식은 정수부와 소수주의 자릿수가 크지 않으므로, 표현할 수 있는 범위가 매우 적다는 단점이 있다.


부동 소수점 방식

실수는 보통 ‘정수부와 소수부’ 로 나누지만, ‘가수부와 지수부’ 로 나누어 표현 할 수도 있다.

앞서 살펴본 고정 소수점 방식은 제한된 자릿수로 인해 표현할 수 있는 범위가 매우 작지만, 부동 소수점 방식은 매우 큰 실수 까지도 표현 할 수 있다.

현재 사용되고 있는 부동 소수점 방식은 대부분 IEEE 754 표준을 따르고 있다.

  • 32 비트 float 형 실수 표현 방식
    • 부호 : 1비트
    • 지수부 : 8비트
    • 가수부 : 23비트
  • 64 비트 double 형 실수 표현 방식
    • 부호 : 1비트
    • 지수부 : 11비트
    • 가수부 : 52비트


부동 소수점 방식의 오차

부동 소수점을 이용하면 고정 소수점 보다 훨씬 많은 범위를 표현할 수 있지만, 이 방식의 실수 표현은 항상 오차가 존재한다는 단점을 가지고 있다.

부동 소수점 방식에서의 오차는 실수를 표현하는 방식에서 발생한다.

스크린샷 2019-08-30 오후 9 43 06

위 공식은 지수를 표현하는 방식이고, 표현 할 수 있는 범위는 늘어나지만 10진수를 정확하게 표현할 수 없다는 단점이 있다.

따라서, 컴퓨터에서 실수를 표현하는 방법은 정확한 표현이 아닌 언제나 근사치를 표현할 뿐임을 항상 명심

  • 부동 소수점 방식으로 실수를 표현할 때 발생할 수 있는 오차를 보여주는 예제

    int i;
    float sum = 0;
      
    for(i = 0; i < 1000; i++) {
    	sum += 0.1;
    }
    
    • ‘0.1’ 을 1000번 더한 합은 ‘100’으로 예상되지만, float 는 근사치를 표현하기 때문에 결과는 ‘99.999’ 가 출력 된다.

*참고-TCP school.com



  • Data = Const + Variable / Data 의 저장공간은?
    • 상수는 코드, 변수는 스택과 힙

메모리의 구조

프로그램이 실행되기 위해서는 먼저 프로그램이 메모리에 로드(load) 되어야 한다.

또한, 프로그램에서 사용되는 변수들을 저장할 메모리 도 필요하다.

따라서, 컴퓨터의 운영체제는 프로그램의 실행을 위해 다양한 메모리 공간을 제공하고 있다.

프로그램이 운영체제로부터 할당받는 대표적인 메모리 공간은 다음과 같다.

  • 코드 영역
  • 데이터 영역
  • 스택 영역
  • 힙 영역

스크린샷 2019-08-30 오후 9 55 42

  1. 코드 영역

    • 실행할 프로그램의 코드가 저장되는 영역으로 ‘텍스트 영역’ 이라고도 불림.
    • CPU는 코드 영역에 저장된 명령어를 하나씩 가져가서 처리하게 된다.
  2. 데이터 영역

    • 프로그램의 전역 변수정적 변수 가 저장.
    • 프로그램의 시작과 함께 할당 되며, 프로그램이 종료되면 소멸 한다.
  3. 스택 영역

    • 함수의 호출 과 관계되는 지역 변수매개 변수 가 저장되는 영역.
    • 함수의 호출과 함께 할당되며, 호출이 완료되면 소멸한다.
    • 스택 영역에 저장되는 함수의 호출 정보를 스택 프레임 이라고 한다. (스택 프레임-TCP school.com)
    • 스택 영역은 ‘push’ 동작으로 데이터를 저장하고, ‘pop’ 동작으로 데이터를 인출한다.
    • 가장 늦게 저장된 데이터가 가장 먼저 인출.
    • 메모리의 높은 주소에서 낮은 주소의 방향으로 할당된다(?).
  4. 힙 영역

    • 사용자가 직접 관리할 수 있는 ‘그리고 해야만 하는’ 메모리 영역.
    • 사용자에 의해 메모리 공간이 동적으로 할당되고 해제된다.
    • 메모리의 낮은 주소에서 높은 주소의 방향으로 할당. (동적 할당 - TCP school.com)


스타트업 비즈니스에 대한 이해

‘데이터 모델링을 제대로 하지 않으면, 사업의 확장이나 기능의 추가, 변경이 아주 어렵거나 불가능해진다.’

  • 스타트업이 실패하는 이유 중에 쌓아놓은 데이터를 활용할 수 없는 경우인 경우가 많다.
  • 데이터 모델링에 실패했기 때문에, 칼럼을 추가하거나 데이터를 다른 곳에 활용하기 어려워 진 것.
  • 데이터에 칼럼 하나를 꽂아 넣으려면 이미 잘 돌고 있는 코드를 엄청나게 바꿔줘야 한다.


‘로그인’ - ‘회원’ 테이블은 다르다

  • 정규화를 한다. ‘null’ 을 없애기 위한 단계.
  • 테이블에 종속된 관계가 있으면 빼내야 한다.
  • 모든 회원이 로그인을 갖는가? (관리자는?)
  • 데이터 베이스를 설계할 때, 천만 사용자를 생각하고 모델링 한다.
  • 각 테이블에서 종속되는 부분을 때어내서 만든다.
  • 테이블을 나누는 두가지 이유 : 종속을 최소화 / null 제거


클러스터 인덱스

  • 대체키

    • 임의로 테이블을 특정하는 키를 만든다.
    • INT 는 21억 가량을 저장할 수 있다.
    • BIGINT 는 더 큰 값을 저장할 수 있다.
    • 대치키는 기본으로 정렬이 되어있기 때문에, 필요한 정보를 찾으려면 처음부터 검색이 들어간다. 따라서 인덱스를 걸어줘야 한다.
  • VARCHAR vs CHAR

    • ‘VARCHAR’ 는 가변길이를 갖기 때문에, 인덱싱이 어렵다.
    • ‘CHAR’ 는 고정길이를 갖기 때문에, 추후에 연산할 필요가 없기 때문에 검색속도 및 읽히는 속도가 다른 타입보다 월등히 빠르다.
    • 사이즈가 고정되어있는 경우 ‘CHAR’ / 가변적인 경우 ‘VARCHAR’
    • 시간복잡도와 공간복잡도를 고려하여 타입을 선정해야 한다.
  • 인덱스

  • B-Tree


용어 정리