데이터베이스란, 여러 사람들이 공유하고 사용할 목적으로 통합 관리되는 데이터들의 모임으로, 파일로 데이터를 저장하는 파일시스템의 단점을 보완하기 위해 생겨난 개념이다. 쉽게 말하자면 데이터의 저장소인 것이다.
데이터베이스는 계층형(Hierarchical), 망형(Network), 관계형(Relational), 객체지향형 (Object-Oriented), 객체관계형(Object-Relational) 등으로 분류된다. 그 중에서 계층형, 망형, 관계형에 대해서 알아보자.
① 계층형 DB
② 망형 DB
③ 관계형 DB
DBMS(DataBase Mangement System)는 데이터베이스를 관리하여 응용 프로그램들이 데이터베이스를 공유하고 사용할 수 있도록 만들어주는 소프트웨어이다. 특징은 다음과 같다.
그 외에도 데이터베이스 구축에 필요한 틀, 장애복구 기능, DB접근을 위한 인터페이스, 데이터 검색 및 저장 기능 등을 제공한다.
현재 우리가 사용하는 대부분의 DBMS는 RDBMS(Relational DataBase Management System)라 하는 관계형 DBMS형태로 사용되고 있다. 대표적인 RDBMS의 예로는 오라클(Oracle), MySQL, MSSQL, MariaDB 등이 있고, 이들은 아래와 같은 특징이 있다. 참고만 하자.
추가로 DBMS에서 사용하는 언어를 SQL(Structured Query Language)이라고 하는데, 주로 관계형 데이터베이스에서 데이터베이스를 조작하는 언어로 사용된다. SQL이 사용되는 DBMS를 만드는 회사가 여럿이기 때문에 각 회사의 제품은 공통적인 표준 SQL과 각 회사마다의 개별적 특성이 혼재한다. 대표적으로 오라클, SQL 서버, MySQL은 각자 PL/SQL, T-SQL, SQL을 자신만의 기능으로 가지고 있으면서, 표준 SQL을 공유한다.
① 테이블
② 열
③ 행
④ 기본키(Primary Key)
⑤ 외래키(Foreign Key)
⑥ 그 외의 키
⑦ 인덱스
⑧ 뷰
정규화(Normalization)의 기본 목표는 테이블 간의 중복된 데이터를 허용하지 않는다는 것이다. 중복을 불허함으로써 무결성을 유지할 수 있으며 DB의 저장 용량 역시 줄일 수 있다. 테이블을 어떻게 분해하는지 따라 정규화 단계가 달라진다.
제1 정규화는 테이블의 column이 원자값을 갖도록 테이블을 분해하는 것이다. 여기서 원자값이란, 속성값이 더 이상 논리적으로 분해될 수 없는 경우를 의미한다. 아래의 예시를 보자.
여러 취미를 가진 좌측의 테이블을 제1 정규화로 분해하면 우측의 테이블과 같은 모습이 된다.
제2 정규화는 제1 정규화를 진행한 테이블에 대해 완전 함수 종속을 만족하도록 테이블을 분해하는 것이다. 여기서 완전 함수 종속이란, 기본키의 부분집합이 결정자(한 속성의 값을 고유하게 결정하는 속성)가 되어선 안됨을 의미한다. 아래의 예시를 보자.
위 테이블에서 기본키는 {학생번호, 강좌이름}으로 복합키이다. 그리고 {학생번호, 강좌이름}인 기본키는 성적을 결정하고 있으며, 강의실 column은 기본키의 부분집합인 강좌 이름에 의해 결정될 수 있다. 즉, 기본키의 부분집합인 강좌 이름이 결정자이기 때문에 강의실을 분리하여 별도의 테이블에서 관리함으로써 아래의 제2 정규형을 만들 수 있다.
제3 정규화는 제2 정규화를 진행한 테이블에 대해 이행적 종속을 없애도록 테이블을 분해하는 것이다. 여기서 이행적 종속이란 A → B, B → C가 성립할 때 A → C가 성립되는 것을 의미한다. 아래와 같은 예시가 이에 해당한다.
위 테이블은 학생번호 → 강좌이름 테이블과 강좌이름 → 수강료 테이블로 나눌 수 있다. 이는 학생의 강좌가 변경될 경우 수강료까지 변경해야 하는 수고를 덜어줄 수 있다.
ACID(Atomicity, Consistency, Isolation, Durability)는 트랜잭션을 정의하는 4가지 중대한 속성을 가리키는 약어이다.
※ 트랜잭션
쪼갤 수 없는 업무처리의 최소 단위로, 데이터베이스의 상태를 변화시키기 위해 수행되는 작업의 단위를 의미한다. 넓은 의미로 데이터베이스와 데이터 스토리지 시스템에서 한 단위의 작업으로 취급되는 모든 작업을 의미하기도 한다. ACID를 번역하면 원자성, 일관성, 신뢰성, 고립성(격리) 그리고 영속성이다. ACID는 데이터베이스 내에서 일어나는 하나의 트랜잭션의 안전성을 보장하기 위해 필요한 성질이다.
데이터베이스 작업에 ACID 속성이 있으면, 이를 ACID 트랜잭션이라 부르고 이 작업을 적용하는 데이터 스토리지 시스템을 트랜잭션 시스템이라 한다. ACID 트랜잭션은 한 테이블의 읽기, 쓰기, 또는 수정 작업이 각각 다음과 같음을 보장해준다.
트랜잭션에 속한 각각의 읽기, 쓰기, 업데이트, 삭제문을 하나의 단위로 취급한다. 즉, 위 명령의 실행이 성공하거나 실패하거나 둘 중 하나일 뿐 그 중간 어딘가의 상태는 존재하지 않는다는 것이다. 쉽게 말해, 특정 쿼리를 실행했는데 부분적인 실패가 있다면 전부 실패하도록 구현한다는 것이다.
예를 들어 A계좌에서 돈을 출금하여 B계좌에 입금한다고 하자. A계좌에서의 출금은 정상적으로 진행되었는데, B계좌에 입금되지 않았다면 상황이 복잡해질 것이다. 만약 이러한 사례에 원자성을 적용한다면, 출금에 성공하더라도 입금에 실패하였으므로 출금작업을 포함한 모든 작업이 다 실패로 처리된다.
일관성이란 말그대로 데이터베이스의 상태가 일관되어야 하는 성질이다. 트랜잭션의 이전과 이후, 데이터베이스의 상태는 여전히 유효해야 한다. 즉, 데이터베이스의 제약이나 규칙을 그대로 유지하고 있어야 한다.
예를 들어 모든 고객은 반드시 이름을 가지고 있어야 한다는 데이터베이스 제약사항이 있다고 가정하자. 따라서 이름 없는 새로운 고객을 추가하는 쿼리 또는 기존 고객의 이름을 삭제하는 쿼리는 일관성을 위반하는 트랜잭션이다.
고립성은 모든 트랜잭션이 다른 트랜잭션으로부터 독립되어야 한다는 뜻이다. 실제로 여러 개의 트랜잭션들이 동시에 수행될 때, 각 트랜잭션은 격리되어 있으므로, 마치 연속적으로 실행되는 것 같은 결과를 보인다(동시에 실행된 결과는 연속적으로 실행된 결과와 같아야 한다).
예를 들어 계좌에 만원이 있다고 하자. 이 계좌에서 계좌 A로 6천원을, 계좌 B로 6천원을 동시에 이체하는 경우와 계좌 A에 먼저 이체한 후 연속적으로 B에 이체한 것의 결과가 동일해야 한다. 동시에 트랜잭션을 실행한다고 해서 각 6천원씩 보내게 되면, 마이너스 통장이 되어버릴 것이다.
영속성은 하나의 트랜잭션이 성공적으로 수행되었다면, 해당 트랜잭션에 대한 로그가 남아야 하는 성질을 의미한다. 런타임 오류나 시스템 오류가 발생하더라도 해당 기록은 영구적이어야 한다.
예를 들어 계좌이체를 성공적으로 실행한 후에 해당 은행 데이터베이스에 문제가 발생해 강제 종료되었다고 하자. 그렇다 하더라도 계좌이체 내역은 기록으로 남아있어야 할 것이다. 반대로 계좌이체를 실행하는 도중에 데이터베이스에 오류가 생긴다면, 해당 이체를 실패시키고 출금계좌와 입금계좌는 이전 상태를 유지하거나 이전 상태로 돌아가야 한다.
SQL(Structured Query Language)은 관계형 데이터베이스에 정보를 저장하고 처리하기 위한 프로그래밍 언어이다. 관계형 데이터베이스는 정보를 표 형식으로 저장하는데, SQL문을 사용하여 데이터베이스에서 정보를 저장, 업데이트, 제거, 검색할 수 있다.
또한 데이터베이스 성능을 유지 및 관리하고 최적화하는 데에도 SQL이 사용된다. SQL명령은 아래와 같이 분류된다.
MySQL은 Oracle에서 제공하는 오픈소스 관계형 데이터베이스 관리 시스템이다. 개발자는 라이선스 비용 지불 없이 MySQL을 다운로드하여 사용 가능하다.
MySQL은 가장 널리 사용되고 있는 관계형 데이터베이스 관리 시스템으로, 다중 사용자와 다중 스레드를 지원한다. C언어, C++, Java, PHP 등 여러 프로그래밍 언어를 위한 다양한 API 또한 제공하고 있다. MySQL은 다양한 운영체제에서 사용할 수 있으며, 특히 PHP와 함께 웹 개발에 자주 사용된다.
참고로 SQL과 MySQL의 관계에 대해 알아보면 MySQL은 SQL 쿼리를 사용하는 DBMS로, SQL 명령은 국제 표준에 의해 정의된 반면, MySQL은 소프트웨어의 지속적인 업그레이드 및 개선을 거치고 있다.