인덱스의 탐색 키는 여러 필드를 포함할 수 있다.이렇게 여러 필드로 구성된 탐색 키를 '복합 키' 라고 한다. 위 그림과 같은 테이블을 생각해보자.만약 age 라는 하나의 search key 를 둔 경우에는 11, 12, 12, 13 순으로 인덱스가 정렬되어 가리킬 것이고, 라는 복합키를 둔 경우에는 (10, 12) (20, 12) (75, 13) (80, 11) 순으로 가리킨다. 라는 복합키를 둔 경우에는 (11, 80) (12, 10) (12, 20) (13, 75) 순으로 가리킨다. 이제 이렇게 인덱스가 주어진 상태에서 다음의 쿼리를 실행해보자. 만약 위와 같은 쿼리를 실행한다면 라는 복합키와 라는 복합키가 주어졌을 때, 어떤 것이 더 효율적일까?정답은 이라는 복합키이다.왜냐하면 일단 ..
DBMS에서 디스크로부터 읽어온 데이터를 저장하는 방식은 다양하다.이번 글에서는 다양한 저장 방식의 종류와 특징에 대해 정리한다. 힙 파일DBMS에서 데이터를 저장하는 제일 간단한 파일 구조이다. (자료구조 힙과는 관련이 없다.)데이터베이스에서 읽어오는 페이지는 1KB ~ 8KB 까지 다양한 크기가 존재할 수 있다. 힙 파일에는 이런 페이지가 여러개 모여 저장된다.그리고 각 페이지를 저장할 때는 그냥 들어온 순서에 맞춰 차곡차곡 저장하므로,특정 기준에 의해 정렬되어있다거나 하지는 않는다. 이제 이렇게 데이터를 저장한 상태에서 DBMS의 기능인 데이터 조회, 수정, 삭제 연산을 생각해보자. 만약 힙 파일로 DBMS에 데이터를 저장해둔 상태에서 특정 레코드를 조회, 수정하는 경우,그 레코드가 위치한 페이지를..
하드 디스크의 구조 하드 디스크는 여러개의 원판이 겹겹이 쌓인 구조를 하고 있다.각 원판 중앙에는 spindle rod 라는 중심축이 있고, 각 원반은 중심축을 기준으로 회전한다.이 원반을 platter 라고 부르고, 플래터에 들어있는 0과 1로 이루어진 데이터를 r/w arm 이 읽어들인다.이때 데이터를 읽기 위해서는 각 arm이 물리적으로 이동을 해야 하는데, 디스크 플레이트는 여러개의 트랙으로 구분되고, 그림에서 보는 것처럼 원반을 부채꼴 모양으로 자른 섹터로 나눌 수도 있다. 데이터를 읽고 쓸 때는 하나의 플레이트에서 색터와 트랙이 만드는 영역에 저장되는 '블록' 단위로 데이터를 읽고 쓴다.따라서 데이터를 찾는 데 걸리는 시간은 트랙을 이동하는 시간과 회전하여 섹터를 찾는 시간의 합으로 나타낼 수..
Constant Hash지금 공부하고 있는 데이터베이스는 하나의 컴퓨터에 모든 데이터를 저장하는 것을 가정하고 있다.하지만 규모가 큰 서비스를 운영하다보면 매우 많은 데이터를 다루므로 하나의 컴퓨터에 저장할 수 없다.따라서 규모가 큰 데이터는 결국 여러 컴퓨터에 쪼개서 저장할 수 밖에 없다. 데이터를 나누어서 저장한다면 우선 그림과 같이 같은 스키마를 갖는 테이블을 여러 개 만들어야 한다.이때 어떤 데이터가 어떤 테이블에 저장될 지 결정하기 위해 각각의 테이블에 0번부터 i 번까지 인덱스를 매긴다.그리고 데이터를 저장할 테이블을 결정할 때는 데이터의 PK를 해싱한 값으로 결정한다.이때 해시 값은 0부터 i 사이의 값이 나올 것이다.해시함수는 단순하게 고려한다면, PK 값이 숫자일 때 이 수를 (i+1..
Nullnull 은 알지 못하는 값, 존재하지 않는 값을 명시적으로 나타내는 값이다. 만약 어떤 직원이 퇴사하면서 데이터가 삭제되면 그 직원의 피부양자가 모두 삭제되도록 구현하는 테이블이 있다고 해보자.이때 실제로 데이터를 지우는 Hard Delete 방식 외에도, 그냥 피부양자에 대한 내용을 null 로 바꿈으로서 지우는 Soft Delete 방식을 적용할 수도 있다. 다만 Null 값을 사용할 때는 PK 에 null 이 들어갈 수 없다는 것만 기억하자.따라서 테이블을 설계할 때, PK에는 별도의 제약조건을 명시히지 않아도, 기본적으로 NOT NULL 제약조건이 걸린다. General Constraint무결정 제약조건을 걸 때, 키 제약조건, 널 제약조건, 참조 제약조건 등 다양한 제약 조건을 걸 수..
관계 대수에서는 없었지만, SQL에는 테이블에 있는 데이터들에 대해 다음의 5가지 집계 함수를 제공한다. 1. count()2. sum()3. avg()4. max()5. min() 이때 각 함수에는 하나의 컬럼이 들어가며, 1, 2, 3 은 그 컬럼에 대해 Distinct 를 취할 수도 있다.(4, 5번에도 사용은 가능하나 DISTINCT 를 취해도 같은 결과가 나온다.) 1. 모든 선원의 평균 나이SELECT avg(S.age)FROM sailors S; 2. 등급이 10인 선원의 평균 나이SELECT avg(S.age)FROM sailors SWHERE S.rating = 10; 3. 가장 나이가 많은 선원의 이름과 나이SELECT S.sname, S.ageFROM sailors SWHERE ..
SQL의 쿼리는 FROM, WHERE, HAVING 절 안에서도 중첩되어 등장할 수 있다.103번 보트를 예약한 선원의 이름을 출력할 때 다음과 같이 중첩된 쿼리를 통해서도 문제를 해결할 수 있다. 이는 마치 중첩된 반복문을 작성하는 것과 비슷하다.선원 테이블에서 모든 선원을 가져오고, 각 선원에 대해서 돌면서 (for each) 예약테이블을 돌면서 선원 정보를 찾는 것과 비슷하다.이때 IN 연산자는 집합 연산자로서 해당 서브쿼리의 결과 집합에 S.sid 가 존재하는 sid 만을 조회한다. 서브쿼리와 관련된 간단한 연습문제를 몇 가지 풀어보자. 1. 빨간색 배를 예약한 적이 있는 / 없는 선원 이름 조회SELECT S.snameFROM sailors SWHERE S.sid IN ( SELECT ..
SQL을 다루기에 앞서 다음과 같은 테이블을 사용한다. sailors 테이블 reserves 테이블 Boats 테이블 기본 문법 SQL 기본 문법의 형태는 위와 같다.이때 실행 순서는 FROM - WHERE - SELECT 순서이다.From 절로 릴레이션 리스트를 가져오고, 가져온 릴레이션에서 WHERE 절로 조건에 맞는 행을 고른 뒤, 그 안에서 보고 싶은 컬럼을 select 하면 된다.만약 DISTINCT 키워드가 있다면 select 결과에 대해 중복값을 제거한다. FROM 절에 들어가는 relation-list 에 여러개의 릴레이션을 넣으면 각 릴레이션에 대해 cross product 한 결과를 만들어낸다.WHERE 절은 관계 대수에서 selection 에 해당하는 부분이며, qualificati..
다음과 같이 Sailors, Boats, Reserves 테이블이 정의되어 있다. Sailors (sid, sname, rating, age)Boats (bid, bname, color)Reserves (sid, bid, day) 구체적인 데이터 표기는 생략하였다.이제 이 테이블에 대해 관계대수 문제를 풀어보자. 1. bid = 103 인 보트를 예약한 선원들의 이름 구하기 예약 테이블에서 bid = 103 인 예약만 가져온 뒤, 선원 테이블과 자연조인하였다.그러면 두 테이블의 모든 공통필드를 기준으로 동등 조인을 걸고, sid 가 동일한 경우만 추려낸다.그러면 103번 보트를 예약한 선원들만 남게 되므로, 여기에서 sname 을 프로젝션하여 조회하면 된다. 강의록에서는 이렇게 복잡하게 푼 경우도 제..
질의언어 (Query Language) 는 데이터베이스로부터 데이터를 가져오고 조작하는 언어이다.질의언어는 모든 알고리즘을 표현할 수 없는, Turing Complete 하지 않은 언어이다. 쿼리는 relation instance 에 적용되며, 쿼리의 적용결과 역시 relation instance 이다.또한 관계 대수를 정의할 때 각 릴레이션(테이블)의 필드는 위치 기반 또는 이름 기반으로 표현할 수 있는데, SQL에서는 두 방법 모두 사용가능하며, 상황에 맞게 적절하게 사용하면 된다. 관계 대수를 정리하기 위해 위 그림과 같은 테이블을 준비하였다.S1, S2 는 같은 스키마를 가진 Sailors 테이블이고, R1 테이블은 Reserves 테이블이다.선원과 선원이 예약한 보트에 대한 정보를 볼 수 있..