Computer A에서 Computer B로 100MB의 비디오를 전송하는 경우 Segment 과정이 없다면 사용자는 100MB의 비디오가 모두 로딩된 후 비디오를 볼 수 있다. Segment 과정이 있다면 Segment라는 작은 단위로 나뉘어 비디오 일부분을 미리 볼 수 있다.
연결이 중간에 끊기는 경우 Segmentation을 하지 않으면 큰 Data가 날아가 손실률이 크다.
<!-- 해당 Collection에 대한 전체 정보 -->
GET /cources
<!-- Document의 정보 조회 -->
GET /cources/front
4.2. Create(생성) - POST
<!-- backend coach 집합에 jjyoung라는 닉네임을 가진 코치 개체 생성 -->
POST /courses/back/coaches
<!-- body에 생성할 내용을 담음 -->
body {nickname: jjyoung}
4.3. Update(수정) - PUT
<!-- frontend coach 집합 중 첫 번째 코치 닉네임을 jjyoung로 수정 -->
PUT /courses/front/coaches
<!-- 수정할 내용을 body에 담음 -->
body {id: 1, nickname: jjyoung}
4.4. Delete(삭제) - DELETE
<!-- frontend crew 집합 중 jjyoung 삭제 -->
DELETE /courses/front/crews/jjyoung
5. REST Arichtecture의 제약 조건
5.1. Client - Server
: Client가 Server에게 Request를 보내고 Server가 Client에게 Response를 보내는 구조로 Server와 Client의 역할이 분리되어있다.
Server : API 제공과 제공된 API를 이용해 비즈니스 로직을 처리하거나 저장
Client : 사용자 인증이나 컨텍스트(세션, 로그인 정보) 등을 관리
5.2. Stateless(무상태성)
: Client와 Server의 통신에는 상태가 없어야하며 모든 요청은 필요한 정보를 담고 있어야 한다.
☞ Client가 두 가지 요청을 보냈을 때 두 번째 요청 시 Server는 Client의 첫 번째 요청의 내용을 모르므로 두 번째 요청시에도 필요한 모든 정보를 담고 있어야 한다.
5.3. Cache
: 일반적인 서비스에서 60 ~ 80% 가량의 Transaction이 Select와 같은 조회성 트랜잭션이며 GET은 얼마든지 호출해도 매번 같은 결과를 만들어내므로(Idempotent) 캐싱이 가능하다.
5.4. Uniform Interface
5.4.1. Identification of Resources : 자원은 유일하게 식별 가능해야하며 Resource가 하나 이상의 유일한 특정 주소인 URI로 식별되어야 한다. ☞ 아직 POST Method로만 Request를 보내기 때문에 URI나 Request Body로 어떤 동작을 할 지 알려줘야 한다.
5.4.2. Manipulation of Resources through Representation : HTTP Method로 표현(CRUD)을 담아야 한다. ☞ 안전한 Operation과 안전하지 않은 Operation 간의 강한 분리를 제공해야 한다.
5.4.4. Hypermedia As the Engine Of Application State(HATEOAS)
: Hyperlink를 통해 Application의 상태가 전이되어야 한다.
☞ HTTP Response에 다음 Action이나 관계되는 Resource에 대한 HTTP Link를 함께 Return한다.
☞ 장점 : 요청 URI가 변경되더라도 Client는 Server에서 동적으로 생성된 URI를 사용함으로써 Client는 URI 수정에 따른 코드를 변경하지 않아도 된다.
5.5. Layered System
: 계층으로 구성이 가능해야 한다.
☞ Server는 다중 계층으로 구성될 수 있으나 Client 입장에서는 계층에 상관 없이 Server만 호출하면 된다.
e.g., 순수 비즈니스 로직을 수행하는 Server, 사용자 인증, 암호화(SSL), 로드 밸런싱 등을 하는 계층을 추가하거나 PROXY, 게이트웨이 같은 중간 매체 사용 가능
5.6. Code-On-Demand(Option)
: Server가 Network를 통해 Client에 Program을 전달하면 그 Program이 Client에서 실행될 수 있어야 한다.
e.g., JavaScript를 사용해 Server에서 Program 전달하면 Client에서 동적으로 실행 가능하다.
6. Richardson Maturity Model
Glory of REST
Level 3 : Hypermedia Controls
Level 2 : HTTP Verbs
Level 1 : Resources
Level 0 : The Swamp of POX
6.1. Level 0 : The Swamp of POX
: POX(Plain Old XML)를 주고받는 단순한 RPC Style System
☞ HTTP를 RPC 기반의 원격 통신을 위한 터널링 Mechanism으로 사용된다.
충족된 제약 조건 : Server-Client, Stateless, Layered System, Manipulation of Resources through Representation
RPC(Remote Procedure Call, 원격 프로시저 호출) : 별도의 원격 제어를 위한 코딩 없이 다른 주소 공간에서 함수나 프로시저를 실행할 수 있게 하는 프로세스 간 통신 기술 (= Client가 Server에 있는 Program을 실행하기 위해 사용하는 통신 기술) ☞ RPC를 이용하면 개발자는 실행 Program이 로컬 위치에 있든 원격 위치에 있든 동일한 코드를 이용할 수 있다.
☞ Client가 Server에게 Message를 보내 Program을 실행시키고 Server에서는 그 Program의 결과를 Client에게 전송
상호 배제(Mutual Exclusion) : 여러 Process/Thread가 동시에 한 자원에 접근하지 못하도록 막는것
점유와 대기(Hold and Wait) : Process/Thread가 자원을 점유한 상태로 다른 자원을 점유하기 위해 대기하는 것
비선점(Nopreemption) : Process에서 자원을 할당 받으면 작업을 완료할 때까지 System에서 Process의 제어를 뺏을 수 없음
순환 대기(Circular Wait) : 점유와 대기를 하는 형태로 Cycle에 갇혀 빠져나갈 수 없는 상태
3. 교착 상태 해결법
: 교착 상태의 해결법으로는 교착 상태 예방, 교착 상태 회피, 교착 상태 탐지 및 복구, 교착 상태 무시가 있다.
3.1. 교착 상태 예방
: 교착 상태 필요 조건 중 하나를 거부하는 방식으로 예방하는 방법이다.
교착 상태는 발생하지 않으면 좋지만, 교착 상태가 발생하지 않는 환경을 만들어버린다면 자원을 효율적으로 사용할 수 없다.
e.g., 필요 조건 중 점유와 대기 조건을 거부해 한 Process가 자신이 필요한 자원을 모두 사용할 수 있을 때만 작업을 시작한다면 자원을 효율적으로 사용할 수 없다.
3.2. 교착 상태 회피
: 교착 상태를 인정하고 피해가는 방법으로 자원을 요청할 때마다 System의 상태를 판단하고 회피하는 전략을 사용한다.
☞ Overhead가 심하다.
e.g., 은행원 Algorithm
은행원 Algorithm : System을 안전 상태/불안전 상태(교착 상태가 발생할 가능성이 있는 경우)로 구분하고 불안전 상태일 때는 대기하고 안전 상태일 때만 자원을 빌려주는 Algorithm으로 할당한 자원 수 고정, Process 수 고정, 제한된 시간 안에 자원 반납 등의 많은 조건이 필요하다. ☞ 현실에서는 자원이 동적으로 왔다갔다해 현실적으로는 불가능한 Algorithm이다.
3.3. 교착 상태 탐지 및 복구
: 교착 상태가 발생한 것 같을 때 탐지하고 복구하는 방법으로 교착 상태가 자주 발생하는 System에서 일반적으로 사용하는 방법이다.
☞ 교착 상태 회피에 비해 Overhead가 적다.
교착 상태 탐지 : 교착 상태 존재 여부 및 교착 상태에 연관된 Process와 자원을 알아내는 전략을 사용하며 교착 상태의 4가지 필요 조건 중 순환 대기 존재 여부에 초점을 맞춰 교착 상태를 탐지한다. ☞ 탐지 Algorithm도 회피 Algorithm과 마찬가지로 Overhead가 있으므로 얼마나 자주(주기적으로, 자원 즉시 할당 여부에 따라, CPU 이용률에 따라 등) 탐지 Algorithm을 호출하는지가 관건이다. e.g., 자원 할당 그래프 소거
교착 상태 복구 : 순환 대기를 깨서 교착 상태로부터 회복하는 방식이다. e.g., 순환 대기가 깨질 때까지 Process 종료, 순환 대기에 포함된 Process 제어권 뺏고 Rollback ☞ 희생양이 될 Process는 남은 수행 시간, 자원 유형의 수 등 Systemp마다 다른 기준의 우선순위에 따라 결정된다. e.g., MySQL의 경우 Transaction Timeout시 교착상태이든 아니든 가장 작은 Transaction을 Rollback하며 Transaction의 크기는 삽입, 업데이트, 삭제된 행 수에 의해 결정된다.
Race Condition(경쟁 조건) : 여러 Process/Thread가 동시에 같은 Data를 조작할 때 타이밍이나 접근 순서에 따라 결과가 달라질 수 있는 상황
Synchronization(동기화) : 여러 Process/Thread를 동시에 실행해도 공유 Data의 일관성을 유지하는 것
Critical Section(임계 영역) : 공유 Data의 일관성을 보장하기 위해 한 번에 하나의 Precess/Thread만 진입해 실행가능한 영역
Mutual Exclusion(상호 배제) : 공유 Data의 일관성을 보장하기 위해 한 번에 하나의 Process/Thread만 진입해 실행할 수 있도록 하는 Algorithm
1. Mutual Exclusion을 보장할 수 있는 방법
: Lock을 사용한다.
// 실제 동작 Code가 아닌 개념 이해를 돕기위한 Code 입니다.
do{
acquire lock // 여러 Process/Thread가 Lock을 획득하기 위해 경합
critical section // Lock을 획득한 단 하나의 Process/Thread만이 Critical Section에 들어가 실행
release lock // Critical Section에서의 실행을 마치면 Critical Section을 빠져나오며 Lock 반환
reminder section
} while(TRUE)
Mutual Exclusion을 보장하는 상호 배제 기법으로는 Spin Lock, Mutex, Semaphore가 있다.
2. Spin Lock
: Lock을 획득할 수 있을 때까지 Lock 획득을 반복해서 시도하는 방식
☞ Lock을 획득하기 전까지 Lock이 다른 Process/Thread에 의해 선점되었는지 확인하는 것 자체가 CPU Cycle을 잡아먹는 일이기 때문에 CPU를 낭비한다.
Single Core에서는 Spin Lock으로 Lock이 반환되기를 계속 기다리더라도 Lock을 획득하기 위해서는 이미 누군가 획득한 상태인 Lock을 반환해야하는데 이는 결국 Context Switching이 필요하다. ☞ Single Core에서의 Spin Lock은 이점이 없다.
Multi Core에서는 Spin Lock으로 Lock이 반환되기를 기다리다가 Thread 1이 Lock을 반환하자마자 Thread 2가 Lock을 획득하므로 Context Switching이 일어나지 않는다.
2.1. 동작 예제
// 실제 동작 Code가 아닌 개념 이해를 돕기 위한 Code입니다.
volatile in lock = 0; // global -> 여러 Thread가 동시에 Lock에 접근 가능
// 여러 Thread가 호출할 함수
void critical(){
while(test_and_set(&lock) == 1); // 여러 Thread가 while loop를 통해 Lock을 획득하려 시도
... critical section // Lock 획득에 성공한 하나의 Thread가 Critical Section에 들어와 실행
lock = 0 // Critical Setcion에서 수행 완료 후 Lock 반환
}
// 실제 TestAndSet()의 동작 원리를 간단히 구현한 함수
// 공유되는 Lock에 대해 Lock의 원래 저장값을 반환하고 Lock 값은 1로 변경
int test_and_set(int* lockPtr){
int oldLock = *lockPtr; // 원래 가지고 있던 Lock 값 가져오기
*lockPtr = 1; // Lock 값을 1로 변경
return oldLock; // 원래 가지고 있던 Lock 값을 반환
}
2.2. 동작 과정
Thread 1이 먼저 수행된 후 Thread 2가 수행되는 경우
1. Thread 1의 test_and_set()의 반환값 = 0 (원래 Lock은 0으로 초기화 되어있었기 때문) 이므로 while loop 탈출해 Critical Section에서 작업을 수행한다.
☞ test_and_set()을 호출했으므로 Lock은 1로 변경된다.
2. Thread 2의 test_and_set()의 반환값 = 1 (1번 과정에서 Thread 1에 의해 Lock이 1로 변경되었기 때문) 이므로 while loop에 갇힌다.
☞ test_and_set()을 호출했으므로 Lock은 계속 1로 갱신된다.
3. Thread 1이 Critical Section에서 작업을 마치고 Lock을 반환한다.
☞ Lock이 0이 된다.
4. Thread 1이 Lock을 반환함과 동시에 Thread 2의 test_and_set() 반환값 = 0 (3번 과정에서 Thread 1에 의해 Lock이 0으로 변경되었기 때문) 이 되므로 while loop 탈출해 Critical Section에서 작업을 수행한다.
☞ test_and_set()을 실행했기 때문에 Lock은 1로 변경된다.
5. Thread 2가 Critical Section에서 작업을 마치고 Lock을 반환한다.
☞ Lock이 0이 된다.
∴ test_and_set()을 통해 Thread 1과 Thread 2가 Critical Section 안에서 동시에 작업을 수행할 수 없다. (= 상호 배제)
① 실행 중간에 간섭받거나 중단되지 않는다. ② 같은 Memory 영역에 대해 동시에 실행되지 않는다. ☞ 2개 이상의 Process/Thread에 의해 동시에 호출된다고 해도 CPU Level에서 알아서 먼저 하나 실행시킨 후 실행이 끝나면 이어서 다른 하나를 실행시키는 방식으로 동기화시켜 실행된다.
3. Mutex
: Lock이 다른 Process/Thread에 의해 획득된 상태라면 Lock이 반환될 때까지 Queue에서 대기하는 방식
☞ CPU Cycle을 불필요하게 낭비하는 것을 최소화한다.
3.1. 동작 예제
// 실제 동작 Code가 아닌 개념 이해를 돕기 위한 Code입니다.
Class Mutex{
int value = 1; // 이 값을 획득해야 Lock을 획득할 수 있다. (공유되는 Data)
// value를 변경할 때 Critical Section 안에서 변경하지 않으면 Race Condition이 발생할 수 있다.
int guard = 0; // Critical Section에 포함되어있는 value를 변경하기 위해 사용되는 변수
}
Mutex::lock(){
while(test_and_set(&guard)); // value 값 변경 전 guard를 획득하기 위해 여러 Process/Thread가 경합
// guard를 획득한 하나의 Process/Thread만 value 변경 Logic을 수행한다.
if (value == 0){ // 누군가 value를 이미 획득한 상태라면
현재 Thread를 Queue에 넣는다; // 작업을 잠시 멈추고 쉬고 있을테니 Lock이 풀리면 깨워달라며 Queue에 들어간다.
guard = 0; & go to sleep // Process/Thread를 Queue에 넣고 guard 변경(guard 반환)
}
else{ // value를 획득할 수 있으면
value = 0; // value 획득하고 value를 0으로 갱신(value 획득한 상태를 표시)한다.
guard = 0; // value 변경 후 guard 0으로 갱신(guard 반환)
}
Mute::unlock(){
while(test_and_set(&guard)); // value 변경 전 여러 Process/Thread가 guard를 획득하기 위해 경합
// guard를 획득한 하나의 Process/Thread만 value 변경 Logic을 수행한다.
if (Queue에 하나라도 대기 중이라면){
그 중 하나를 깨운다;
}
else{ // 대기중인 Process/Thread가 하나도 없으면
value = 1; // value를 1로 갱신(value 반환)
}
guard = 0; // value 변경 혹은 Queue에서 Process/Thread 꺼낸 후 guard 0으로 갱신(guard 반환)
}
mutex -> lock(); // 여러 Process/Thread가 Lock을 획득하기 위해 경합
... critical section // Lock을 획득한 하나의 Process/Thread가 Critical Section에 들어가 작업 수행
mutex -> unlock(); // Critical Section에서 작업을 마친 후 Lock 반환
Multi-Core 환경이고 Critical Section에서의 작업이 Context Switching보다 빨리 끝난다면 Spin Lock이 Mutex보다 더 이점이 있다.
Mutex와 Spin Lock의 Context-Switching
Mutex는 잠들고 깨는 과정(Queue에 넣고 빼는 과정)에서 Context Switching이 발생한다.
Spin Lock은 잠들고 깨는 과정(Queue에 넣고 빼는 과정)이 없기 때문에 Context Switching이 발생하지 않는다.
4. Semaphore
: Signal Mechanism을 가지는, 하나 이상의 Process/Thread가 Critical Section에 접근 가능하도록 하는 방법
4.1. 종류
Binary Semaphore(이진 세마포어) : 한 번에 1개의 Process/Thread만 Critical Section에 접근할 수 있다. ☞ Mutual Exclusion을 보장한다.
Counting Semaphore : 한 번에 value개의 Process/Thread만 Critical Section에 접근할 수 있다.
4.2. 동작 예제
// 실제 동작 Code가 아닌 개념 이해를 돕기 위한 Code입니다.
Class Semaphore{
// 한 번에 value개의 Process/Thread가 Critical Section에 접근할 수 있다.
int value = 1; // value를 획득해야 Lock을 획득할 수 있다. (공유되는 Data)
// value를 변경할 때 Critical Section 안에서 변경하지 않으면 Race Condition이 발생할 수 있다.
int guard = 0; // Critical Section에 포함되어있는 value를 변경하기 위해 사용되는 변수
}
Semaphore::wait(){
while(test_and_set(&guard)); // value 변경 전 guard를 획득하기 위해 여러 Process/Thread가 경합
// guard를 취득한 하나의 Process/Thread만 value 변경 Logic을 수행한다.
if (value == 0){ // 이미 누군가 value를 획득한 상태라면
현재 Process/Thread를 Queue에 넣는다; // Process/Thread가 일을 잠시 멈추고 쉬고 있을테니 Lock이 풀리면 깨워달라며 Queue에 들어간다.
guard = 0; & go to sleep; // Process/Thread를 Queue에 넣은 후 guard 변경(guard 반환)
}
else{ // value를 획득할 수 있다면
value -= 1; // value 획득한 후 value를 1 감소(value 획득한 상태를 표시)
guard = 0; // value 변경 후 guard 0으로 갱신(guard 반환)
}
}
Semaphore::signal(){
while(test_and_set(&guard)); // value 변경 전 guard 획득하기 위해 여러 Process/Thread가 경합
// guard를 획득한 하나의 Process/Thread만 value 변경 Logic을 수행
if (Queue 안에 하나라도 대기 중이라면){
그 중에 하나를 깨워 준비시킨다;
}
else{ // 대기중인 Process/Thread가 하나도 없으면
value += 1; // value 1 증가(value 반환)
}
guard = 0; // value 변경 혹은 Queue에서 Process/Thread 꺼낸 후 guard 0으로 갱신(guard 반환)
}
Semaphore -> wait(); // 여러 Process/Thread가 Lock을 획득하기 위해 경합
... critical section // Lock을 획득한 하나의 Process/Thread가 Critical Section에 들어가 작업 수행
semaphore -> signal(); // Critical Section에서 작업을 마친 후 Lock 반환
: Software 분야에서 Application을 개발에 빈번히 쓰여지는 범용 기능을 한꺼번에 제공해 Application의 토대로서 기능하는 Software이다. Application의 아웃라인으로 개발에 Framework를 이용하면 독자적으로 필요로하는 부분만 개발하면 되기 때문에 개발 효율의 향상을 기대할 수 있다.
e.g., Spring, Django, node.js 등
1.1. 특징
공통적인 개발 환경을 제공한다. (개발 편의성)
개발할 수 있는 범위가 정해져있다.
Application 제어의 역전이 발생한다.
2. Library
: 개발자가 사용할 수 있는 API들을 종류나 목적에 따라 나누어 정의한 API 묶음으로 재사용 가능한 Code의 집합이다. Library는 System에 기본적으로 설치되어있는 기본 Library와 제조사나 외부 메이커에 의해 만들어지는 확장 Library로 나뉜다.
e.g.,
import random # random Library를 사용하겠다.
random_num = random.randrange(1, 7) # random Library에 포함되어 있는 함수를 이용해 값 반환
2.1. 특징
개발에 필요한 것들을 모아둔 일종의 저장소이다.
필요할 때 호출해서 사용한다.
Application의 흐름을 제어한다 ☞ Framework와 반대
3. API(Application Programming Interface)
: 응용 프로그램에서 사용할 수 있도록 운영체제나 다른 프로그램이 제공하는 기능을 제어할 수 있게 만든 Interface이다.
3.1. 특징
응용 프로그램을 다른 운영체제나 Program과 연결해주는 다리 역할을 한다.
직접 구현하는 것이 아닌 제어를 담당한다.
API를 조합해 원하는 Program을 만들 수 있다.
4. 비유를 통한 Framework, Library, API의 이해
집을 지을 때 아래의 조건이 만족되어야 한다고 가정해보자.
1. 3개의 방, 1개의 화장실이 존재해야 한다. 2. 에어컨이 존재해야 한다. 3. 조명, 가전제품 등을 제어할 수 있는 리모컨이 존재해야 한다.
1번 조건 : 맨땅에 헤딩하기보다는 평면도를 이용해 여러 사람이 협업하면 효율성이 높아질 것이다. ☞ 평면도 = Framework
2번 조건 : 에어컨을 실제로 만들기보다는 기존에 만들어져 있는 에어컨을 구매해 가져다 놓으면 불필요한 시간과 노력을 줄일 수 있을 것이다. ☞ 기존 제품 = 외부 Library
3번 조건 : 리모컨을 이용해 제품을 제어한다면 리모컨 없이 제어할 때보다 더 쉽게 제어할 수 있을 것이다. ☞ 리모컨 = API
Data의 중복(Data Redundancy) : File System은 각 File 마다 필요한 Data를 각각 가지고 있어야 하므로 동일한 Data를 서로 다른 File에 유지해 관리한다.
Data의 비일관성(Data Inconsistency) : 데이터에 변경사항이 조금만 있어도 각 File에서 해당되는 Data를 모두 변경해야 하므로 수정에 문제가 있고, 한꺼번에 수정이 되지 않으면 Data가 서로 달라진다.
정보 접근의 어려움(Difficulty in Accessing Data) : 기존 File System은 File의 용도에만 맞춰 제작되어 다른 Program을 만들 때는 기존의 Program을 변경하거나 개조하는 데 시간이 오래걸리며 다시 DataBase 작업을 해야한다.
Data의 고립(Data Isolation) : 정보가 여러 File에 서로 다른 형식으로 흩어져서 존재해 흩어진 정보를 이용하기 위해서는 재구성 비용이 들어가며 오랜 시간이 소요된다.
무결성 문제(Integrity Problems) : Data를 변경하기 위해서는 여러 File에 존재하는 Data에 모두 접근해 여러 번 변경해야 한다.
원자성 문제(Atomicity Problems) : Program이 수행 중인 작업은 전부 완료되어 저장되어하며 완료되지 못하면 아예 저장되지 않아야 한다. 즉, 수행중인 작업이 컴퓨터 고장이나 기타 의도하지 않은 이유로 중단되는 경우 작업을 전부 완료하지 못했으므로 저장하지 않고 이전의 Data를 복원한다.
동시 Access 문제 : 많은 사용자가 동시에 같은 정보에 접속해 갱신한다면 동시에 갱신되도록 해야한다. (= 정보의 일관성을 보장하도록 해야한다.)
2. DataBase
: 여러 사람이 공유하고 사용할 목적으로 통합 관리되는 Data들의 모임
2.1. 등장 목적
DataBase가 존재하기 전에는 File System을 사용해 Data를 관리했다. Data를 각각의 File 단위(Record)로 저장하며 이러한 일을 처리하기 위한 독립적인 Application과 상호 연동이 되어야 하는데 File System에서는 File에 접근하는 방식이 응용 프로그램 내에 표현되므로 응용 프로그램과 Data 간의 의존관계가 존재하게 되어 Data의 구조, 접근 방법이 변경되면 기존의 프로그램과 Data를 함께 변경해야한다.
즉, Data 정의가 응용 프로그램에 내포되어 있고 Program에서 Data를 접근하고 조작하는 것 외의 별도의 제어가 없다.
따라서, File 단위로 저장할 때 데이터 종속성 문제와 중복성, 데이터 무결성 문제 등이 존재해 DataBase로 관리하기 시작했다.
3. DBMS(DataBase Management System, 데이터베이스 관리 시스템)
: 다수의 사용자들이 DataBase 내의 Data의 생성, 접근 방법, 관리 유지할 수 있도록 전반적으로 지원하는 System
3.1. 기능
정의 기능 : DataBase를 관리하기 위해서는 저장할 구조를 정의해야하며 정의된 구조에 따라 저장해야한다.
조작 기능 : 사용자가 DataBase를 검색, 갱신, 삽입, 삭제 등을 할 수 있도록 지원하는 기능이다.
제어 기능 : DataBase의 정확성과 안정성을 위해 일정한 형식을 필터링해 저장하거나 여러 명이 Data를 동시 공유할 수 있도록 한다.
3.2. 특징
DBMS는 File System의 문제를 해결하기 위해 만들어졌기 때문에 DBMS의 특징은 곧 File System의 단점을 의미한다.
Data의 독립성
물리적 독립성 : DataBase의 Size를 늘리거나 성능 향상을 위해 Data File을 늘리거나 새롭게 추가하더라도 관련된 응용 프로그램을 수정할 필요가 없다.
논리적 독립성 : DataBase는 논리적인 구조로 다양한 응용 프로그램의 논리적 요구를 만족시킬 수 있다.
Data의 무결성 : 여러 경로를 통해 잘못된 Data가 발생하는 경우의 수를 방지하는 기능으로 Data의 유효성 검사를 통해 Data이 무결성을 구현한다.
Data의 보안성 : 인가된 사용자들만 DataBase나 DataBase 내의 자원에 접근할 수 있도록 계정 관리 및 접근 권한을 설정함으로써 모든 Data에 보안을 구현할 수 있다.
Data의 일관성 : 연관된 정보를 논리적인 구조로 관리함으로써 어떤 하나의 Data만 변경하는 경우 발생할 수 있는 Data의 불일치성을 배제할 수 있다. 또 작업 중 일부 Data만 변경되어 나머지 Data와 일치하지 않는 경우의 수를 배제할 수 있다.
Data 중복 최소화 : DataBase는 Data를 통합해서 관리함으로써 File System의 단점 중 하나인 자료의 중복과 Data의 중복 문제를 해결할 수 있다.