[빅데이터 및 지식관리시스템] DBMS와 level of abstraction에 대해 알아보기
DBMS(Database Management System)란?
데이터베이스는 매우 크고 통합된 데이터 모음으로 이를 관리하고 저장하는 소프트웨어 패키지이다.
real world의 개체 Entity와 그들 간의 관계 Relationship을 모델링하는 것이다.
파일시스템과 다른 점은 다음과 같다.
- Data Independence
- Concurrency Control: 다수의 사용자가 동시에 데이터를 조작할 때, 데이터의 정합성을 유지하게 한다.
- Crash Recovery: 전원 장애, 디스크 오류등으로 인한 데이터 손실이 발생하는 경우, 복구를 할 수 있도록 한다.
- Security and access control: 데이터의 기밀성과 무결성을 보장하기 위해 다양한 보안 기능을 제공한다.(인증, 권한관리, 암호화 등)
- 데이터 검색과 같은 특정 작업의 효율성을 높이기 위해 다른 code를 이용한다.
이런 특징 때문에 여러 회사에서는 자신의 데이터를 잘 저장 및 처리하기 위해 많은 비용을 내고 oracle 같은 회사의 서비스를 이용한다.
Computation에서 information으로 패러다임이 바뀐 오늘날 DBMS의 중요성은 더 커지고 있다.
Data Models
데이터를 어떻게 표현할 것인가에 대한 개념으로 즉 entity와 relationship을 어떤 구조를 이용하여 표현할 것인가?
우리가 주로 사용하는 것은 relational model of data이다.
relational model에서 데이터를 표현하기 위한 유일한 방법 2차원 표(table)이다.
여기서 Schema라는 개념이 나오는데, 쉽게 말해 특정 데이터를 모아놓은, 정의하는 구조를 말한다.
뒤에서 더 자세하게 설명하겠지만
scott파일을 통해 보면 emp, dept, salgrade가 스키마이다.
dept 스키마를 살펴보면 deptno, dname, loc의 column을 이뤄져있고 각 data type이 저장돼 있다.
스키마 내부의 record(or tuple, rows)를 Relation instance라 한다.
다음을 보면 파란색 칸이 column이고 빨간색 칸이 Relation instance인 것이다.
- attribute=field=column
- records=tuples=rows
또한 data model에는 intergrity가 있는데 이것은 나중에 따로 더 자세하게 알아보겠다.
Levels of Abstraction
데이터를 효율적으로 관리하고 사용자와 애플리케이션이 데이터에 접근할 수 있도록 3가지 추상화 단계를 제공한다.
이렇게 나눠서 접근하면 data independence를 확보할 수 있고 이 내용은 뒤에서 더 자세히 살펴보겠다.
External Schema
특정 사용자나 응용 프로그램이 데이터를 어떻게 보는지 정의하는 데이터의 사용자 뷰(View)이다.
같은 데이터라도 각각 유저들마다 다른 정보를 보는 것이다.
이를 통해 데이터 보안 및 접근 제어를 구현할 수 있다.
예를 들어 student라는 table이 있을 때, 여기에는 전체학생 정보를 포함하고 있다고 하자.
교수(user1)는 이름, 학과, 학번만 조회할 수 있고, 학사팀(user2)은 이름, 학번, 학과, 성적을 볼 수 있는 것이다.
create or replace view myview as select ename, sal from emp where deptno = 10;
select /*+ gather_plan_statistics */ * from myview;
Conceptual Schema
데이터베이스의 전체적인 구조 즉 Entity, Relationship, Attribute 등을 정의한다.
데이터 독립성을 유지하면서 전체 데이터베이스의 구조를 유지한다.
예를 들어 University Database가 있을 때, Students, Courses, Enrolled 테이블을 포함하는 것이다.
Conceptual(logical) Schema의 data independence을 설명해 보면
create or replace view dept_sal as select deptno, avg(sal) avg_sal from emp group by deptno;
select * from dept_sal;
emp table에 대해 dept_sal이라는 view를 만들고
alter table emp rename to emp2;
emp table을 emp2 table로 변경한다.(logical/conceptual schema에서의 변경)
select * from dept_sal;
이 query를 다시 보내면 오류가 발생한다.
create or replace view dept_sal as select deptno, avg(sal) avg_sal from emp2 group by deptno;
view를 재정의 해줌으로써 query를 실행할 수 있게 된다.
즉, table(logical schema)이 변경되더라도 view(external schema)를 재정의 해줌으로써 같은 방식으로 동작할 수 있다.
이러한 특성이 logical schema의 data independence이다.
Physical Schema
데이터를 실제로 어디에, 어떻게 저장할지 결정하는 스키마이다.
indexing, partitioning을 통해 성능을 최적화하고 저장 공간을 효율적으로 활용하는 것에 중점을 둔다.
예를 들어 University Database에서 Students 테이블은 인덱스를 생성하여 검색 속도를 향상한다던가, Courses 테이블은 두 개의 partition으로 나눠 저장하는 것이다.
physical schema independence에 대해 설명해 보면
create index emp_deptno on emp(deptno);
select * from emp where deptno = 30;
여기서 index와 상관없이 나의 query는 돌아간다. (이것을 physical data independence라 함)
단지 얼마나 효율적이게 돌아가냐의 차이인 것이다.
Queries in a DBMS
query는 what user wants? 에 해당하는 것이다.
DBMS에 query를 날리면 DBMS가 어떻게 할지 정하는 것이다.
즉, DBMS는 how에 해당하는 부분에 관여하며, 이런 것을 query optimizer이라 한다.
Transactions
life is full of transactions..
transactions의 특성에 대해 정리하면
- Atomicity: Transactions 내의 모든 연산이 성공해야 하며, 하나라도 실패하면 전체가 취소된다.
update ACCOUNT set balance = balance - 10 where id = 1;
update ACCOUNT set balance = balance + 10 where id = 2;
commit;
여기서 id=1일 때까지 update를 하고 전원이 나갔다고 했을 때
다시 들어와서 ACCOUNT table을 확인하면, commit 하기 전이므로 반영이 안 되어있다.
- Consistency: Database가 일관된 상태를 유지해야 된다. 예를 들어 은행에서 돈을 송금할 때, 돈을 보낸 사람의 계좌에서 빠진 돈과 받는 사람의 계좌에 들어간 돈이 정확히 일치해야 한다.
- Isolation: 동시에 여러 transaction이 실행될 때, 각 transaction은 다른 transaction에 영향을 주면 안 된다.
여기서 눈여겨봐야 할 내용은 concurrency control이다.
-- LOCKIN G for concurrency control
select sal from emp where ename = 'SMITH';
update emp set sal = sal + 100 where ename = 'SMITH';
select sal from emp where ename = 'SMITH';
-- Open another SQLPlus session S2
select sal from emp where ename = 'SMITH';
-- sal?
update emp set sal = sal * 1.1 where ename = 'SMITH';
-- What happens? why?
-- execute commit in session S1
commit;
-- Then, what happens in S2?
S1에서 emp table에 대해 작업을 하고 있을 때( sal에 100을 더한 상황), S2가 동시에 접속하면 어떻게 될까?
sal*1.1로 update 하려 하는데 가능할까?
S1에서 아직 commit을 안 했으므로 불가능하다.
만약 S2에서 update emp set.. 을 enter을 쳤다면, Locking이 걸렸을 것이다.
Locking이란 transaction 간 충돌을 방지하기 위해 데이터를 잠그는 것이다.
이후 S1에서 commit을 했다면, S2에서 비로소 작업을 할 수 있다.
이 경우 원래 sal이 1000이었다면, S1 이 후 1100이 되고 S2가 작업을 하면 1210이된다.
이것은 DBMS별로 다르다고 한다.
내가 작업한 곳은 oracle이기 때문에 결과가 저렇게 나왔고 언뜻 보면 atomicity을 안가지는 것 처럼 보이지만
DBMS면 가져야한다.
아마 그럼 S2가 종료되고 1100이 되는게 맞을 것이다.
- Durability: transaction이 성공적으로 commit 되면, database에 영구적으로 저장되야 한다.