본 글은 이것이 MySQL입니다(한빛미디어, 우재남 지음) 을 읽고 정리한 내용입니다.
프로젝트란 현실세계의 업무를 컴퓨터 시스템으로 옮겨놓는 일련의 과정 혹은 대규모의 프로그램을 작성하기 위한 전체 과정이라고 볼 수 있다.
이것은 비유하자면 집을 짓는 것과 같다. 아무 준비도 하지 않은채 무작정 벽돌부터 쌓는다면 나중에는 무너뜨리고 처음부터 다시 시작해야 할 수도 있다. 이러한 문제점을 해결하기 위해 소프트웨어 개발 방법론이 여러개 나왔다. 그 중에 가장 오래되고 전통적으로 사용되던 모델이 폭포수 모델이다.
폭포수 모델의 장점은 각 단계가 명확히 구분되어서 진행단계가 명확하다는점이 있지만 가장 큰 단점은 내려가기는 쉬워도 다시 거슬러 올라가기 어렵다는 점이 있다. 뭐 어쨌든 여기서 가장 핵심적인 단계는 업무 분석과 시스템 설계라는 것이다. 이 두단계를 합쳐서 전체 공정의 최소 50%를 차지한다고 볼 수 있다. 단순히 생각하면 구현이 가장 중요한거 아니냐 라고 볼 수 있지만 분석과 설계에 비하면 그다지 중요한 작업은 아닌것이다.
✅ 데이터베이스 모델링 : 현 세계에서 사용되는 작업이나 사물들을 DBMS의 데이터베이스 개체로 옮기기 위한 과정. 더 쉽게 말하자면 현실에서 쓰이는 것을 테이블로 변경하기 위한 작업이라고 생각해도 좋다.
위 그림을 보자. 고객은 회원테이블, 직원은 직원테이블, 진열된 물건은 물품테이블... 근데 주의해서 볼 점은 '물건을 산다'라는 행위도 테이블로 변환된다는 점이다.
그렇다면 이러한 데이터베이스 모델링은 정답이 있는가? 꼭 저 데이터베이스처럼만 설계를 해야하는가? 🤔 그렇지는 않다. 데이터베이스 모델링 하는 사람에 따라서 각기 다른 결과가 나오는 경우가 훨씬 많다. 다만 정답은 없지만 좋은 모델링과 나쁜 모델링은 존재한다.
데이터베이스 모델링은 상당히 어려운 작업이다. 정확한 정답이 없고 업무에 대한 폭넓고 정확한 지식이 필요하고 데이터베이스 시스템에 대한 깊은 지식과 경험도 요구되기 때문이다. 만약, 모델링이 잘못 된다면 나중에 열심히 만든 프로그램이 결국 쓸모 없는 결과를 낳을 수도 있다.
데이터베이스 모델링은 크게 3단계를 거쳐서 완성되는게 일반적이다.
✅ 개념적 모델링 -> 논리적 모델링 -> 물리적 모델링
여기서는 데이터베이스 모델링에 대해서 약간의 개념만 익히는 것을 목표로 하기 때문에 간단한 데이터베이스 모델링 실습을 해볼 것이다. 원칙적으로는 정규화, 비정규화 등의 정확히 구분된 작업을 해야하지만 그러한 것들을 분류하지 않고 그냥 진행할 것이다.
우리는 지금 새로운 쇼핑몰을 오픈했다고 가정하자. 지금부터 우리 매장을 찾는 고객의 명단을 기록하고 또 물건을 구매할 때 구매한 내역도 기록하겠다. 다음과 같은 고객 방문 기록이 있다고 해보자.
고객은 이처럼 여러번 방문할 수도 있고 방문을 하더라도 하나도 물건을 사지 않을수도 있다. 혹은 물건을 여러개 살 수도 있을 것이다. 기록된 내용에서 물건을 구매한 적이 없는 고객을 위쪽으로 정렬해보겠다.
이렇게 보니 전체 테이블 모양이 L자 모양이 되었다. L자형 테이블의 문제는 공간이 낭비된다는 것이다. L자형 테이블을 빈칸이 있는 곳과 없는 곳으로 분리해보자. 즉, 고객테이블과 구매 테이블로 나눠보자.
이제 빈 부분이 없어졌다. 그런데 여전히 문제가 있다. 우선 고객 테이블에서 똑같은 정보가 중복된다는 점이다. 고객 테이블의 중복을 없애보자. 그런데 우리는 각각의 고객을 구분해야 한다. 그래서 고객 이름은 기본키로 설정하겠다. (실제로는 이름대신 회원ID를 부여해야 기본키로 설정해야한다)
그 다음에 구매테이블만 보니 누가 구매한 것지 알 수가 없다. 그래서 구매 테이블 앞에 누가 구매한 것인지 구분할 수 있도록 고객테이블의 기본키로 설정된 고객이름을 앞에 넣어주자.
다만 구매 테이블은 고객이름이 중복되었다고 중복을 없애면 안된다. 각각의 행은 별도의 구매한 내역이기 때문이다. 이제 고객 테이블과 구매 테이블 구분이 잘 되었다. 그런데 이 두개의 테이블은 서로 밀접한 관련이 있으니 관계(Relation)을 맺어줘야 한다. 고객 테이블과 구매 테이블은 1:1, 1:N, N:M 중에 어떤 관계일까? 고객은 구매를 여러번 할 수 있다. 구매는 특정고객이 하는 것이다. 따라서 1:N관계이다. (만약 고객, 제품테이블로 나눴다면 N:M이므로 구매테이블이 필요했을듯)
따라서 위에처럼 1:N관계를 갖고 관계를 맺어주는 역할은 기본키와 외래키를 설정하므로 이뤄진다. 이렇게 관계를 맺어진 후에는 제약 조건이 자동으로 설정된다. 예를 들어 구매 테이블에 '존밴이'라는 사람이 모니터를 한개 구매했다고 추가하려고 한다. 하지만 고객 테이블에 '존밴이'가 없기 때문에 추가될 수 없다. 이를 참조 무결성이라고 부른다. 이것은 우리가 물건을 구매하기전 회원가입을 해야 구매할 수 있는 것과 같은 이치이다.
또한 이번에는 김범수 회원이 탈퇴한다고 해보자. 이는 고객 테이블에서 김범수 행을 삭제하는 것이 된다. 그런데 구매 테이블에서의 김범수 데이터는 어떻게 될까? 이 경우에는 설정에 따라 연속 삭제되거나 삭제되지 않거나 NULL을 넣거나 할 수 있다.
모델링은 손으로 하다가 어느정도 되었다 싶으면 모델링 툴을 사용해 다이어그램으로 보는 편이 좋다. 그래야 개발자간에 공유하기도 쉽고 알아보기도 쉽고 보관하기도 좋다.
여기서는 Workbench를 이용해보도록 하겠다. File > New Model을 선택한다. 기본적으로 데이터베이스 이름은 mydb로 되는데 modelDB로 수정해주겠다. (마우스 오른쪽 버튼 누르면 나온다)
ADD Diagram을 더블 클릭한다. 그럼 EER 다이어그램 탭이 추가될 것이다.
Table 모양 아이콘을 선택해 테이블을 생성하자. 고객 테이블(userTBL)을 만들었다.
마찬가지로 구매테이블(buyTBL)도 만들어주자.
이제 1:N 관계를 맺어줄 차례이다. 가장 아래 아이콘을 클릭후 buyTBL의 userName과 userTBL의 userName 열을 차례로 클릭하면 1:N관계가 생성된다.
작업이 끝났으면 File > Save Model을 클릭해서 지금까지의 내용을 저장하자. 파일명은 적절히 modelDB.mwb 정도로 입력한다. 그리고 나서 탭을 닫는다.
모델링 파일을 실제 데이터베이스에 적용시켜보자. File > Open Model을 선택해서 저장한 파일을 불러오자. 그런다음 Database > Forward Engineer를 선택한다.
options는 그대로 두고 next선택. Export MySQL Table Objects가 기본적으로 선택되어있다. show Filter를 보면 우리가 만들었던 userTBL과 buyTBL 테이블이 보인다.
Review SQL Script를 통해 자동으로 SQL문이 생성된 것을 볼 수 있다.
끝이 나면 성공적으로 데이터베이스에 적용되는 것을 확인할 수 있을것이다.
기존에 만들었던 ShopDB의 테이블, 인덱스, 스토어드 프로시저, 트리거를 다이어그램으로 변경해보겠다. Database > Reverse Engineer 를 선택한다.
데이터베이스들 중에서 shopdb를 선택하자. 변환이 완료되면 다음과 같이 보인다.
4개의 테이블이 있고 1개의 뷰를 확인할 수 있다.
지금 사용한 MySQL Workbench에 포함된 모델링 기능은 고가의 데이터베이스 모델링 툴보다는 조금 부족할 수도 있겠지만 나름대로 좋은 기능을 활용할 수 있다.
유명한 툴로는 CA사의 ERwin제품이 있지만 고가이며, 최근에는 무료 또는 저가 모델링 툴인 Microsoft Visio, exERD 등도 많이 사용되고 있다.
나는 ERDCloud 사이트도 나쁘지 않다고 본다. 자주 애용하는 편임.