Relational Algebra

Relational Data Operation

What is Relational data Operation?

  • 원하는 데이터를 얻기 위해 Relation에 필요한 Query를 수행하는 것으로,
    DB system의 구성 요소 중 데이터 언어의 역할을 한다.
  • 관계 대수/관계 해석 으로 나눌 수 있다. (기능과 표현력 측면에서 능력은 동등하다)
    • 관계 대수(Relational Algebra) : 절차식 언어, 원하는 결과를 얻기 위해 데이터의 처리 과정을 순서대로 기술한다.
    • 관계 해석(Relational Calculus) : 비절차식 언어, 원하는 결과를 얻기 위해 처리를 원하는 데이터가 무엇인지만 기술한다.

https://www.lucidchart.com/publicSegments/view/ffd9cd6c-c856-4fef-96fa-f749e6b77080/image.png

Why do we use it?

  • 원하고자 하는 데이터를 쉽고, 빠르고, 정확하게 얻고자 사용한다.
  • 새로운 데이터 언어 제안 시, 해당 데이터 언어의 유용성을 검증하는 기준
    관계 대수나 해석으로, 기술할 수 있는 모든 query를 기술할 수 있으면
    데이터 언어를 관계적으로 완전(Relationally Complete)하다고 판단할 수 있다.

Relational Algebra

What is Relational Algebra?

  • Relation을 다루는 연산으로, 검색 질의를 기술하는데 사용한다.
  • 절차식 언어이다. (User가 원하는 결과를 위해 어떤 연산을 수행해야 할 지 system에 알려준다)
  • 간단하며 명시적(Powerful) 표현을 사용한다.
  • 폐쇄 특성(Closure Property)을 가진다.

->피연산자와 그 연산의 결과 역시 Relation이다.

  • 대표 연산자는 8개로, 일반 집합 연산자 4개와 순수 관계 연산자 4개로 분류할 수 있다.
  • 피연산자의 특성 두가지
    • Variables that stand for relations(relation을 나타내는(대표하는) 변수)
    • Constants which are finite relations(유한한 relation의 상수)

    연산 : By System     vs     언어 : By User


Normal Set Operator

일반 집합 연산자

  • Relation이 tuples의 set이라는 개념을 이용하며, 수학의 집합 연산자를 차용한다.
  • 조건 : 피연산자가 두 개이며, 합병가능(Union-compatible)이어야 한다.
  • 합병가능 (Union-compatible)이란?
    이들의 필드 수가 같고,(속성의 개수)
    왼쪽에서부터 오른쪽으로 차례대로, 대응하는 필드들이 동일한 도메인을 가지고 있다.
    (도메인이 같으면 이름은 달라도 됨)


일반 집합 연산자
연산자기호표현의미

Union

R∪S

릴레이션 R과 S의 합집합 반환,
R∪S={t│t∈R ∨ t∈S}

Intersection

R∩S

릴레이션 R과 S의 교집합 반환,
R∩S={t│t∈R ∧ t∈S}

Difference

R-S

릴레이션 R과 S의 차집합 반환,
R-S={t│t∈R ∧ ¬t∈S}

Cartesian Product

×R × S

릴레이션 R과 S의 각 tuple들을 모두 연결,
R × S={r·s│r∈R ∧ s∈S}






UNION



https://www.lucidchart.com/publicSegments/view/dc41b327-a211-4580-a79b-299ff18eca04/image.png

Cardinality차수특징
│R∪S│≤│R│+│S│R과S의 차수와 같다

교환/결합법칙 성립










INTERSECTION



https://www.lucidchart.com/publicSegments/view/99aab467-5ed6-4c4f-8853-182b684b9122/image.png

Cardinality차수특징
│R∩S│≤ MIN{│R│,│S│}R과S의 차수와 같다

교환/결합법칙 성립






DIFFERENCE



https://www.lucidchart.com/publicSegments/view/cdca4006-f940-4ce9-a668-9beb4cf5f959/image.png

Cardinality차수특징
│R-S│≤│R│R과S의 차수와 같다

교환/결합법칙 불가







CARTESIAN PRODUCT



https://www.lucidchart.com/publicSegments/view/a97abf44-ea93-4ea6-83da-8fc8c216c613/image.png

Cardinality차수특징
│R × S│=│R│×│S│R과S의 차수를 더한 값교환/결합법칙 성립



Cartesian Product는 두 Relation의 구조가 달라도 가능하다.






Pure Relational Operator

순수 관계 연산자

  • Relation의 구조와 특성을 이용하는 연산자이다.
순수 관계 연산자
연산자기호표현의미

Selection

σσ조건(R)

릴레이션 R에서 
조건(Predicate)을 만족하는 tuples 반환

Projection

ππ칼럼(R)

릴레이션 R에서 
주어진 column으로만 구성된 tuples 반환

Join

R⋈S

릴레이션 R, S의 특정column(들)을 비교하여,
조건에 알맞는 컴포넌트가 있다면
그 컴포넌트(들)의 tuples 반환.

Division

÷R÷S

릴레이션 S의 모든 tuple과 관련이 있는
릴레이션 R의 tuples 반환

Rename

ρρs(x1,x2,...)(R)

릴레이션 R을 S로 개명
각 attribute를 x1, x2,...로 개명










SELECTION



https://www.lucidchart.com/publicSegments/view/b9b1d15e-c897-4e4e-822d-e8a681b9f2b0/image.png

특징

- 하나의 Relation에서만 수행하는 연산
- 조건식(Predicate)에는 비교연산자(>, ≥, =, ≠, ≤, <)와 논리연산자(, ) 이용
- 수평적 부분집합 개념










PROJECTION



https://www.lucidchart.com/publicSegments/view/a6d22977-c20a-49d9-9b36-951e1d8e280e/image.png 

특징

- 하나의 Relation에서만 수행하는 연산
- 수직적 부분집합 개념










JOIN



https://www.lucidchart.com/publicSegments/view/e37dddbf-9208-4cf0-9c48-b77cdc5e0699/image.png

종류특징
Join

- 릴레이션 R 하나로는 원하는 Data를 얻지 못하여 
관련있는 여러 Relation들을 함께 사용해야 하는 경우 사용 
자연 조인(Natural Join)이라고도 함

Theta-Join

- 이러한 조인 연산에, θ(조건; Predicate)을 부여해
조건을 만족하는 tuples를 반환
- 조건(Predicate)은 비교연산자(>, ≥, =, ≠, ≤, <)을 의미한다.

Equi-Join

- θ연산자가 등호(=)일 때의 세타 조인을 말한다.











DIVISION



https://www.lucidchart.com/publicSegments/view/ea663266-3648-4ae5-9404-6eca3535e0dd/image.png

특징

- 릴레이션 R이 릴레이션 S의
  모든 column을 포함하고 있어야 연산 가능 (R⊃S)










RENAME



https://www.lucidchart.com/publicSegments/view/1d7bf5ec-9d8e-4842-a846-c513966056b8/image.png

특징
- 각 combining시 Name conflict(이름 충돌)이 그림과 같이 빈번히 일어날 수 있다.
- 이는 User, DBA 모두에게 모호할 수 있어, 명시적으로 이름을 바꾸는 데 사용한다.





Bag vs Set

     초기 DBMS는 Bag을 이용한 data modeling을 하였다.
     Bag은 한마디로, 중복을 허용하는 집합 개념이다.
     그렇기 때문에 implementation 관점에서, 
     Set을 이용한 것보다 효율이 좋다.(두 Relation을 합칠 경우
     복사해서 붙여넣기만 하면 된다.)
     현재는 Data의 종류에 따라 저장 방법이 매우 다르므로
     이 두가지를 적절히 사용한다! ( All과 Distinct 개념 )

Combining Issues

Ordering

아무 조건(Predicate)이 없는 연산들은, 그 순서대로(괄호가 있다면 괄호부터) 행하면 되지만,
위에서 살펴본 Selection, Theta Join 등의 다양한 조건들을 갖는 연산들은
어떤 순서로 조건을 만족시키는 지 정하는 것이 좋다.

  • 예를 들어, 두 릴레이션 R1, R2를 ∧(AND)가 포함된 Theta join을 한다고 가정하자. 이 때 AND 양옆의 조건들을
    먼저 행하고 합칠 것이냐, 아니면 Cartesian Product 등으로 먼저 합친 뒤 조건을 행할 것이냐
    하는 등의 issue를 말할 수 있겠다.

이러한 것들은 Optimizer가 다양한 비용, 공간, 시간 등을 고려해 '적절히' 정한다.

A Linear Notation for Algebraic Expressions

대수식의 선형 표현법

  • Assignment : 복잡한 표현들 대신, 빈 relation을 만들어 순차적 assignment에 따라 표현한다.
    1. Relation 이름, 괄호안에 column 리스트를 입력한다. 보통 마지막 결과 relation 이름은 Answer로 칭한다.
    2. Assignment 기호는 :=를 사용한다.
    3. 대수 표현을 우변에 작성한다.
  • 이와 같은 작업을 행하면, 마치 C++의 Pseudocode처럼, 우측 대수를 좌측 relation에 대입한다.

예)

     Movies relation에서, 

     상영시간이 90분을 넘고 Fox사 배급인 영화의 제목과 개봉 년도를 찾아라.

     R(t,y,l,i,s,p) := σlength>90(Movies)
     S(t,y,l,i,s,p) := σstudioName='Fox'(Movies)
     T(t,y,l,i,s,p) := R ∩ S
     Answer(title, year) := π t,i(T)

블로그 이미지

차트

소소한 일상 C코드 DB 항상 행복하게^-^★

,

BINARY SEARCH (이진탐색)

What is it?

  • Binary search(이진탐색). 많은 탐색기법 중 간단하고 속도가 빨라 자주 쓰이는 로직이다.
  • 배열을 계속 반으로 갈라 UP/DOWN을 하면서 (1/2)n개로 줄여가며 탐색한다.
  • 반드시 정렬된 배열에서만 사용할 수 있다.
  • Worst Case, 'O( logn )'
  • 너무 간단한 코드라 자세한 설명은 생략한다.



CODE

/************************************************ * BINARY SEARCH ****************************** * ********************************* binaryS.c **** * ***********************************************/ #include <stdio.h> /* Length of Array */ #define MAX_BUFF 5 /* Data which into Array */ typedef struct DATA { int mKey; // 키 int mValue; // 값 } DATA; /****************************** * * BINARY SEARCH by Recursive * * ***************************** */ int BinarySearch(struct DATA aSortedArray[], int aBegin, int aEnd, int aFind) { /* Arguments */ // aSortedArray[] : 정렬된 배열 // aBegin : 배열의 0번째 인덱스 // aEnd : 배열의 끝 인덱스 // aFind : 찾고자 하는 값 X /* Array's middle index */ int mMid = 0; /* Escape condition */ if ( aBegin > aEnd ) { return -1; } /* Declare mMid's value */ mMid = ( aBegin + aEnd ) / 2; /* If i find the value X, */ if ( aSortedArray[mMid].mValue == aFind ) { /* Return */ return mMid; } /* If arry[mid] > X */ else if ( aSortedArray[mMid].mValue > aFind ) { /* Recursive, aEnd is mMid-1 */ return BinarySearch( aSortedArray, aBegin, mMid-1, aFind ); } /* If arry[mid] < X */ else if ( aSortedArray[mMid].mValue < aFind ) { /* Recursive, aBegin is mMid+1 */ return BinarySearch( aSortedArray, mMid+1, aEnd, aFind ); } } /* MAIN FUNCTION */ int main() { /* declare an Array which has struct datas */ struct DATA arr[MAX_BUFF]; /* Variables */ int mFindValue = 0; // 입력받는 찾을 값 int mIndex = 0; // 찾은 값의 인덱스 int inputKey = 0; // 배열에 들어갈 입력받은 key값 int inputValue = 0; // 배열에 들어갈 입력받은 value값 printf("\nEnter the 5 KEYs and VALUEs which you want : \n"); printf("\n\n :::: WARNING : YOU MUST ENTER BY ORDER FOR VALUEs::::\n\n"); for(int i = 0; i < MAX_BUFF; i++) { /* Fill the Array with inputed values */ scanf("%d", &inputKey); scanf("%d", &inputValue); arr[i].mKey = inputKey; arr[i].mValue = inputValue; printf("KEY : %d VALUE : %d and\n", inputKey, inputValue); } printf("\n\nThen, current array's status is : \n\n"); printf("Keys : [ "); for(int i = 0; i < MAX_BUFF; i++) { printf("%d ", arr[i].mKey); } printf("]\n"); printf("VALUEs : [ "); for(int i = 0; i < MAX_BUFF; i++) { printf("%d ", arr[i].mValue); } printf("]\n\n\n"); while(mFindValue!=999) { printf("Enter the number which you wanna find (if you want to exit it, enter '999' : "); scanf("%d", &mFindValue); if(mFindValue==999) { printf("\n\nExit................\n\n"); break; } else { /* SEARCH */ mIndex = BinarySearch(arr, 0, MAX_BUFF-1, mFindValue); if(mIndex < 0) { printf("There is no %d in this array. \n\n", mFindValue); } else { printf("\n%d is in Array[ %d ] and %d's KEY is %d\n\n", mFindValue, mIndex, mFindValue, arr[mIndex].mKey); } } } return 0; }


블로그 이미지

차트

소소한 일상 C코드 DB 항상 행복하게^-^★

,

INSERTION SORT (삽입정렬)

What is it?

  • Insertion sort (삽입정렬), 많은 정렬 중 널리 쓰이는 정렬기법이다.
  • 정렬된 하위배열에 원소를 채워넣는 기법이다.
  • Worst Case, 'O( n2 )'
  • 간단한 코드지만, 부연 설명을 하자면
    • 값이 이미 채워져 있는 데이터 기반이 아닌, 값을 채울 때마다 바로바로 정렬되는 방식이다.
    • 리스트로 구현하는 원리와 비슷하다.


CODE

/************************************************* * INSERTION SORT ****************************** * **************************** insertionsort.c **** * ***********************************************/ #include <stdio.h> /* Length of Array */ #define MAX_BUFF 10 /* Declaring for functions */ void Initiation(int arr[]); // Initiation for Array void PrintArray(int arr[]); // Print Array void InsertionSort(int arr[], int InputValue); // Insertion Sort /* Global variable for counting */ int CountValues = 0; /* **************** * * MAIN FUNCTION * * **************** */ int main() { /* Variables */ int mInputValue = 0; // Input Value int mCountValue = 0; // Count int SortedArray[MAX_BUFF + 1]; // Array /* Initiation */ Initiation(SortedArray); printf("\n"); /* Enter the Input for the number of array's size */ while(mCountValue < MAX_BUFF) { printf("Enter the number which you wanna into an Arrary : "); scanf("%d", &mInputValue); CountValues++; mCountValue++; /* SORT */ InsertionSort(SortedArray, mInputValue); PrintArray(SortedArray); } printf("\n"); return 0; } /* Initiation function */ void Initiation(int arr[]) { int Index = 0; for ( Index = 0; Index < MAX_BUFF; Index++) { arr[Index] = '\0'; } } /* Print function */ void PrintArray(int arr[]) { int Index = 0; printf("\n[ "); for( Index = 0; Index < MAX_BUFF; Index++ ) { printf("%d ", arr[Index]); } printf("]\nThe number of Values : %d\n\n", CountValues); } /* ****************** * INSERTION SORT * * ***************** */ void InsertionSort(int arr[], int aInputValue) { /* Variables for FOR clauses */ int Seeing = 0; int Index = 0; for ( Seeing = 0; Seeing < CountValues; Seeing++ ) { /* If an Array is empty, */ if ( arr[Seeing] == '\0' ) { arr[Seeing] = aInputValue; } /* If Array[INDEX] > Input, */ if ( arr[Seeing] > aInputValue ) { /* Move 1 index on right all values which bigger than Input */ for ( Index = CountValues; Index > Seeing; Index-- ) { arr[Index] = arr[Index-1]; } arr[Seeing] = aInputValue; break; } // IF } // FOR }


블로그 이미지

차트

소소한 일상 C코드 DB 항상 행복하게^-^★

,

Array based QUEUE

What is it?

  • Array 기반의 Queue
  • 기본적으로 Enqueue (Insert)Dequeue (Delete) 연산이 가능한 FIFO (First-In, First-Out) 자료구조이다.
  • 너무 간단한 코드라 자세한 설명은 생략한다.
  • FIFO란? 먼저 들어온 자료가 먼저 나가는 것으로, 줄을 서다가 입장하는 것을 연상하면 된다.


CODE

/************************************************** * Array 기반의 Queue ***************************** * ************************************ q.c ******** * *************************************************/ #include <stdio.h> #define MAX_BUFF 10 /* Data for Queue */ typedef struct qData { int qkey; // 키 char qvalue; // 값 } qData; struct qData queue[MAX_BUFF]; /* Information for Queue */ int qTail; /* 삽입되는 부분에 대한 정보 */ int qNum; /* 입력받은 총 데이터 수 */ int countDe; /* 현재 데이터의 개수를 위한 디큐 횟수 */



/* * Dequeue시 Head의 데이터를 삭제하는 * 동시에 모든 데이터를 한칸씩 앞으로 * 옮긺으로써 Head를 따로 선언하지 않음. */

/* Queue Initiation */ void qInit() { qTail = 1; qNum = 0; countDe = 0; for(int i=0; i<MAX_BUFF; i++) { queue[i].qkey = '\0'; queue[i].qvalue = '\0'; } } /* Queue Print for Enqueue */ void qPrintEn() { int i; /* variable for 'for clause' */ printf("\n Current Queue's status is :\n\n"); printf(" KEY VALUE\n"); for( i = qTail-1 ; /*qTail-1*/ i >= 0; /*qHead-1*/ i--) { printf(" %d %s\n", queue[i].qkey, &queue[i].qvalue); } printf("\n"); printf("The number of data which you into : %d\n", qNum); printf("The number of data which current exist : %d\n\n", qNum-countDe); } /* Queue Print for Dequeue */ void qPrintDe() { int i; /* variable for 'for clause' */ printf("\n Current Queue's status is :\n\n"); printf(" KEY VALUE\n"); for( i = qTail-3 ; /* qTail-2 */ i>=0; /* qHead */ i--) { printf(" %d %s\n", queue[i].qkey, &queue[i].qvalue); } printf("\n"); printf("The number of data which you into : %d\n", qNum); printf("The number of data which current exist : %d\n\n", qNum-countDe); } /* Queue Insert the data 'val' */ void enQ(char val) { if ( qTail >= 11 ) { /* If the Queue is full */ printf("\nerror::queue overflow.\n"); } else { qNum++; queue[qTail-1].qkey = qNum; queue[qTail-1].qvalue = val; qPrintEn(); qTail++; } } /* Queue Delete the data from head */ void deQ() { if( qTail == 1 ) { /* If the Queue is empty */ printf("\nerror::queue is already empty.\n"); } else { countDe++; printf("Deleted data : %s\n", &queue[0].qvalue); queue[0].qkey = '\0'; queue[0].qvalue = '\0'; for(int i=1; i<qTail; i++) { queue[i-1].qkey = queue[i].qkey; queue[i-1].qvalue = queue[i].qvalue; } qPrintDe(); qTail--; } } /* MAIN FUNCTION */ int main() { qInit(); printf("\n\nIt's an array based Queue.\n\n"); int menu; char push; while(menu!=3) { printf("\nYou make a choice to menu.\n\n"); printf("Press '0' If you wanna Initiation.\n"); printf("Press '1' If you wanna Enqueue.\n"); printf("Press '2' Ifyou wanna Dequeue.\n"); printf("Press '3' If you wanna exit.\n\n"); printf(" PRESS : "); scanf("%d", &menu); switch(menu) { case 0: printf("You pressed '0' to Initiation.\n"); printf("So, the stack is cleared.\n"); qInit(); qPrintDe(); break; case 1: printf("You pressed '1' to Enqueue.\n"); printf("Press the character which you want to Enqueue. : "); scanf( "%s", &push ); enQ(push); break; case 2: printf("You pressed '2' to Dequeue.\n"); deQ(); break; case 3: printf("Exit......\n\n"); break; default: printf("It's wrong number. press again.\n\n"); break; } // switch } // while return 0; }


블로그 이미지

차트

소소한 일상 C코드 DB 항상 행복하게^-^★

,

The Relational Data Model

Data modeling

What is data modeling?

  • 컴퓨터에 저장할 데이터의 구조를 논리적으로 표현하기 위한 행위.
  • 주어진 개념으로부터 논리적인 데이터 모델을 구성하는 작업을 말하며,
    일반적으로 이를 물리적인 데이터베이스 모델로 환원하여 고객의 요구에 따라
    특정 정보 시스템의 데이터베이스에 반영하는 작업을 포함한다.
  • DB구조 기반으로 데이터, 데이터 관계, 데이터 의미, 데이터 제약 등을 기술하기 위한 개념적 표현 방법.
  • 시스템의 대상이 되는 업무를 분석하여 정보시스템으로 구성하는 과정에서 
    업무의 내용과 정보시스템의 모습을 적절한 표기법으로 표현하는 것.

즉, 추상적인 데이터베이스 구조를 가시적으로 구현화(형태화)시키는 것으로, 
데이터베이스 설계 시 어려움을 도와주는 등의 역할을 한다. 



Why do we use it?

  • Leverage(파급력) : 계속 변화되는 데이터들을 변경하는 데 용이하다. 즉, 유지보수의 이점이 있다.
  • Conciseness(간결한 표현) : 설계도면처럼, 가시적인 Diagram으로 표현하여
    복잡한 유저들의 요구를 쉽게, 직관적으로 이해할 수 있다.
  • Data Quality(품질) : 데이터들의 중복, 비유연성, 비일관성 등 기존 file system의
    단점들을 극복할 수 있다.

3 Steps to data modeling

3 Steps to data modeling
STEPS설명
1. 개념적 데이터 모델링업무중심적이며 포괄적인, 추상적 모델링
2. 논리적 데이터 모델링구축하고자 하는 업무에 대해 Key, Attribute, Relation 등을 정확하게 표현. (재사용성 높음)
3. 물리적 데이터 모델링실제로 DB에 이식할 수 있도록 성능, 저장 등 물리적인 성격까지 고려하여 설계


아래로 내려올수록 구체적이며 위에 있을수록 추상적이다.



Relational Data Model

About Relation

  • Data를 담은 2차원 TableROW(행)과 COLUMN(열)로 이루어진다.
  • Relation의 특징
    1. 튜플의 유일성, 무순서
      • 유일성 : 각각의 튜플을 식별할 수 있어야 한다. 즉, 릴레이션에서 애트리뷰트들의 값의 조합이 유니크 해야한다. 
        ( 물론 1개로도 각각의 튜플을 식별할 수 있어도 상관없다. )
      • 무순서 : 순서를 부여하면 오히려 품질을 떨어트릴 수 있다. 튜플의 순서는 가치판단의 기준이 되는 것이 아니기 때문이다. 
    2. 애트리뷰트들의 무순서, 원자값 
      • 무순서 : 마찬가지로, 필요한 속성을 사용자로 하여금 취사 선택하도록 설계되었다. 
        오히려 순서에 의미를 부여하면 변화에 취약하게 되어 유지보수 비용이 증가될 염려가 있다.
      • 원자값 : 속성의 값의 범위가 하나여야만 한다는 의미이다. 그렇지 않으면 역시 비용이 증가될 염려가 농후하다.

Then, What is RDM?

Relation을 이용한 Data model

데이터를 표현하는 방법 중 하나인 '데이터 모델'의 여러 갈래 중 하나이며
설계의 의미보단 '데이터를 어떻게 표현할까'하는 개념적 의미이다.

Issues about RDM

  • 단순하며 유용하다. (실제로 DB implementation의 대부분이 RM 기반)
  • SQL(Structured Query Language)이라는 high-level language를 이용하여 Relation의 Data를 원하는 대로, 쉽게 조작할 수 있다.

Design

  • Design 측면에서는, E/R(Entity Relationship) 표기법을 기반으로,
    Entity(개체), Relationship(관계), Attribute(속성)들을 적절하게 
    RM 표기법으로 변형하여 Design 할 수 있다.
  • 이러한 설계 방식으로 각 Relation 간의 제약(Constraint)함수 종속(Functional Dependency)
    Key 등을 명확하게 이해하고, 보다 정확한 Relation을 설계할 수 있다.

Structure of RDM

RDM은 그림과 같이 구성되어 있다.

https://www.lucidchart.com/publicSegments/view/96e3db21-af81-4dd8-950c-b9ace13c96cb/image.png


Relation
구성요소설명
Attributestable의 맨 위에 표시되며 각 column의 이름을 명세 
(E/R Model의 entity set과 동일)
Tuplestable 맨 윗줄을 제외한 나머지 행들을 각각 일컬음 
각 attribute에 대해 하나의 구성 요소를 가짐 
괄호와 쉼표를 사용하여 표기한다. 
예 : (Star Wars, 1977, 124, color)
Instancerelation의 주어진 모든 tuple들의 집합을 칭함
Componenttable의 한 '칸'을 의미


Schemas

Data Model에 대해 이야기할 때 항상 'Schema(스키마)'를 언급한다.
Schema란, DB를 구성하는 레코드의 크기키(key)레코드들의 관계(relationship)
검색 방법 등 '자료를 저장하는 구조와 표현법을 정의한 것'이라고 칭할 수 있다.
relation 이름 뒤에 괄호로 묶어 표기하며 (예 : Movies(title, year, length, filmType))
Relational database schema (혹은 그냥 Database schema)라고 한다.

주의 : 여기서 attributes들은 list등의 레코드가 아니라 set이다 !


Words
이름설명
필드(Field)어떤 의미를 지니는 정보의 한 조각으로, 
DB 시스템에서 처리의 최소 단위를 뜻함
레코드(Record)정보를 처리하는 기본적인 단위로, 
필드(혹은 다른 items)의 모임을 뜻함
도메인(Domain)필드 값에 주어지는 값의 유효한 범위 
(어떠한 조건을 만족하는 범위)를 정해줌 
수학에서는 정의역


각 component 값들은 structure, set, list 등의 record 타입이 아닌, atomic해야 한다. 
또한 같은 column에 존재하는 component 값들 모두 같은 타입(이거나 정해진 값 중 하나)이어야 한다.


Relation은 tuple들의 set이기 때문에 제시된 tuple들의 '순서'는 중요하지 않다.
즉, tuple들의 순서가 바뀌어도 동일한 Relation으로 본다.
더 나아가 attribute들의 순서 역시 재배치할 수 있다.
하지만 데이터가 섞이거나 변경되는 일 없이 재배치해야 한다. 
결과적으로 각각의 tuple은 attribute 순서대로 정렬된다.
그러므로 그림과 같은 두 개의 Relation은 완전히 '같다' 라고 할 수 있다.

https://www.lucidchart.com/publicSegments/view/df26b00a-3b9d-46f2-a63c-94518332672a/image.png 



Schema vs Instance

스키마와 인스턴스의 구별은 확실히 해두자.
스키마는 Relation의 attribute와 name이며 대개 '변하지 않는다.'
반면, 인스턴스는 tuple의 집합으로 값이 바로바로 변한다.
디자인 시 인스턴스는 고려하지 않는다.
다만, 어떤 구조로 설계할 지만 고려하자.

Functional Dependencies

Constraint

E/R design을 Relational schema로 컨버팅 시 Application의 요구에만
Relational schema를 제공하면 큰 위험이 따를 수 있다. ( 바꾸기 쉽지 않음에도 불구하고 )
또한 별개로 빈번히 특정 제약(Constraint)에 얽매일 수밖에 없다. 이 때 생기는 제약들 중
가장 중요한 것은 'Functional dependency'(이하 FD)라고 불리는 unique-value 제약이다.
이 제약은, 중복을 제거하는 Database redesign에 있어 아주 위험할 수 있다.
이 밖에도, 도메인 제약조건(Domain constraint), 참조 무결성(Referential integrity) 등이 있다.

Constraints
종류설명
도메인 제약조건
(Domain constraint)
각 component들이 Data type/size 등 도메인에 위배되는지에 대한 제약조건
엔티티 무결성 제약조건
(Entity integrity constraint)
Entity의 기본 키(Primary key)를 구성하는 어떤 열도
NULL 값을 포함할 수 없다는 것에 대한 제약조건
참조 무결성 제약조건
(Referential integrity constraint)
외래 키(Foreign key)의 값은 참조된 relation의
기본 키 값들 중 하나와 같다는 제약조건





NULL value

널 값(null value)은 공백, 0, 길이가 0인 문자열들과는 다른, 말 그대로의
아직 입력되지 않은 데이터를 의미한다. RM에서 NULL 허용을 하면,
한 개의 Relation으로 모든 데이터를 표현할 수 있다는, 이론상으로 좋아보이지만
쿼리 및 갱신이 복잡해지며 제약 조건을 위배할 수 있다는 문제점도 따른다.
따라서, 일반적으로 NULL 값은 허용하지 않는 것이 좋다.



Definition of Functional Dependency

Relation R의 두 튜플 T1, T2에 대해 n개의 attribute(A1, A2, ... An)값이 같다면
T1, T2의 m개의 attribute(B1, B2, ... Bn)도 반드시 같은 값이다.
즉, An이 결정되면 그 값에 따른 Bn도 단 하나의 값으로 결정된다.

  • 표기 : A1A2...An -> B1B2...Bn

https://www.lucidchart.com/publicSegments/view/8ec0cfdc-df30-410a-b7e1-b8b10655a29f/image.png 



Functional dependency의 'Functional'이란?

마치 정의역의 한 값을 대입하면 그에 해당하는 치역이 단 한 개만 나온다는
수학의 'function'과 같기 때문 ! 

Keys of Relations

Key란, 

  1. Relation 내 다른 모든 attributes를 unique하게 결정하는(hold, identify) attribute(s)이다.
    즉, 두 개의 distinct한 tuple의 모든 attribute값들은 각각 다 다른값이다.
  2. Key 외엔 다른 attribute를 unique하게 결정하는 다른 부분집합이 없어야 한다.
    즉, Key는 minimal해야 한다. (key가 하나의 attribute A를 포함하면, A를 key라고 한다.) 

Key is minimal, not minimum'''

  • Primary key : 여러 key 중 user가 지정한 key를 일컫는다.
    (Implementation issue가 될 수 있기 때문에 underline으로 명확하게 표시함)
  • Superkeys(Superset of key) : Key의 제약이 걸려있는 attribute(들).
    Key는 모두 Superkey이지만, Superkey이면 Key는 아니다. (minimal의 조건)
  • Foreign key : 다른 Relation의 Primary key attribute를 참조하는 key로,
    참조 무결성 제약조건과 더불어 두 Relation들의 일관성을 유지하는 데 사용한다.
    또한 외래 키는 일종의 'key'개념이라고 보기엔 다소 무리가 있다.

혹자는 Key개념을 다르게 설명한다. 

Superkey 중 최소의 Key(s)를 
후보 키(Candidate Key)라고 따로 정의하기도 한다.













마침.


블로그 이미지

차트

소소한 일상 C코드 DB 항상 행복하게^-^★

,

Array based STACK

What is it?

  • Array 기반의 Stack
  • 기본적으로 Push (Insert)Pop (Delete)연산이 가능한 FILO (First-In Last-Out) 자료구조이다.
  • 너무 간단한 코드라 자세한 설명은 생략한다.
  • FILO란? 먼저 들어온 자료가 마지막에 나가는 것으로, 쌓아논 책을 위에서부터 습득하는 것을 연상하면 된다.



CODE

/**************************************************** * Array 기반의 STACK ******************************* * *********************************** st.c ********** * **************************************************/ #include<stdio.h> /* 배열의 크기를 상수로 지정 */ #define MAX_BUFF 10 /* 배열에 들어가는 데이터 */ typedef struct sData { int skey; //키 char svalue; //값 } sData; /* 크기가 MAX_BUFF인 스택 선언 */ struct sData stack[MAX_BUFF]; /* Information for Top of Stack */ int sTop; /* Information for number of datas */ int sNum; // 데이터가 들어온 총 횟수 int countPop; // 삭제연산의 수 /* Stack Initiation */ void sInit() { /* Top을 1로, 나머지는 모두 초기화한다 */ sTop = 1; sNum = 0; countPop = 0; for(int i=0; i<MAX_BUFF; i++) { stack[i].skey = '\0'; stack[i].svalue = '\0'; } } /**************************************************************** * Push 후 출력과 Pop 후 출력을 구별하는 게 좀 더 깔끔해서 구별함 * * ***************************************************************/ /* Stack Print for Push */ void sPrintPush() { printf("\n Current stack's status is :\n\n"); printf(" KEY VALUE\n"); for(int i=sTop-1; i>=0; i--) { printf(" %d %s\n", stack[i].skey, &stack[i].svalue); } printf("\n"); printf("The number of data which you into : %d\n", sNum); printf("The number of data which current exist : %d\n\n", sNum-countPop); } /* Stack Print for Pop */ void sPrintPop() { printf("\n Current stack's status is :\n\n"); printf(" KEY VALUE\n"); for(int i=sTop-2; i>=0; i--) { printf(" %d %s\n", stack[i].skey, &stack[i].svalue); } printf("\n"); printf("The number of data which you into : %d\n", sNum); printf("The number of data which current exist : %d\n\n", sNum-countPop); } /* Stack Insert the data 'val' */ void sPush(char val) { if(sTop-1>=MAX_BUFF) { /* If the STACK is full */ printf("\nerror::stack overflow.\n"); } else { sNum++; stack[sTop-1].skey = sNum; stack[sTop-1].svalue = val; sPrintPush(); sTop++; } } /* Stack Delete the data of top */ void sPop() { if(sTop-1==0) { /* If the STACK is empty */ printf("\nerror::stack is already empty.\n"); } else { sTop--; printf("Poped data : %s\n", &stack[sTop].svalue); stack[sTop-1].skey = '\0'; stack[sTop-1].svalue = '\0'; countPop++; sPrintPop(); } } /* MAIN FUNCTION */ int main() { sInit(); printf("\n\nIt's an array based STACK.\n\n"); int menu; char push; while(menu!=3) { printf("\nYou make a choice to menu.\n\n"); printf("Press '0' If you wanna Initiation.\n"); printf("Press '1' If you wanna push.\n"); printf("Press '2' Ifyou wanna pop.\n"); printf("Press '3' If you wanna exit.\n\n"); printf(" PRESS : "); scanf("%d", &menu); switch(menu) { case 0: printf("You pressed '0' to Initiation.\n"); printf("So, the stack is cleared.\n"); sInit(); sPrintPop(); break; case 1: printf("You pressed '1' to Push.\n"); printf("Press the character which you want to push. : "); scanf("%s", &push); sPush(push); break; case 2: printf("You pressed '2' to Pop.\n"); sPop(); break; case 3: printf("Exit......\n\n"); break; default: printf("It's wrong number. press again.\n\n"); break; } // switch } // while return 0; }


블로그 이미지

차트

소소한 일상 C코드 DB 항상 행복하게^-^★

,

Overview of Database Management System

What is DB?

DATA vs INFORMATION 

  • DATA : 단순한 관찰이나 측정 등의 수단을 통해 현실 세계로부터 수집된 사실이나 값.
  • INFORMATION : 데이터 중에서도 조직화되고 체계화 된 데이터로서 의사 결정권자에게 의미를 제공하는 것. 

DATABASE 

  • 체계화된 데이터들의 모임으로, 여러 응용 시스템들의 통합된 정보들을 저장하여 운영할 수 있는 공용 데이터들의 묶음. 

What is DBMS?

  • 이러한 데이터베이스의 모든 액세스를 관리하는 응용 소프트 웨어.
  • 데이터들을 정의조작제어 하는 기능을 가지고 있다.
    1. 정의 기능 : DB 생성 시 DB를 정의한다.
    2. 조작 기능 : 다수의 이용자들이 공동으로 이용(검색, 삽입, 삭제, 갱신)할 수 있다.
    3. 제어 기능 : 정확도와 보안성을 높인다.

DBMS의 기능에 따른 언어

  • DDL (Data Definition Language)' : DB의 구조(Schema, Domain, Table, View, Index)를 정의하는 언어로, 
    DBA(Database Administrator)는 해당 attribute, domain, authority 등을 명확히 이해하고 결정해야 한다.
DDL
명령어기능
CREATESchema, Domain, Table, View, Index를 정의함
ALTERTable에 대한 정의를 변경하는 데 사용함
DROPSchema, Damian, Table, View, Index를 삭제함



  • DML (Data Manipulation Language) : DB사용자, 어플리케이션 등 다수의 user들이 DB에 대해
    검색(select), 삽입(insert), 삭제(delete), 갱신(update)등을 하게 하기 위한 언어.
    1. 절차식(Procedural) DML : "어떤" 데이터를 "어떻게" 구할 지 명세.
    2. 비절차식(Non-procedural) DML : 방법은 따로 명시하지 않음.
DML
명령어기능
SELECT테이블에서 조건에 맞는 튜플을 검색함
INSERT테이블에 새로운 튜플을 삽입함
DELETE테이블에서 조건에 맞는 튜플을 삭제함
UPDATE테이블의 조건에 맞는 튜플의 내용을 변경함



  • DCL (Data Control Language) : DB에 접근하고 객체들을 사용하도록 권한을 주고 회수하는 언어.
DCL
명령어기능
COMMIT데이터베이스 조작 작업이 정상적으로 완료되었음을 관리자에게 알려줌
ROLLBACK데이터베이스 조작 작업이 비정상적으로 종료되었을 때 원래의 상태로 복구함
GRANT데이터베이스 사용자에게 사용권한을 부여함
REVOKE데이터베이스 사용자의 사용권한을 취소함




정보의 검색을 담당하는 부분을 Query라 한다.



Transaction

* What is transaction?

  • DBMS에서 데이터들의 상호작용이 일어나는데, 이러한 상호작용의 한 단위(unit of work)를 말한다.
  • 성공과 실패가 분명해야하고, 상호 독립적이어야 하며 일관되고 믿을 수 있어야 한다.
  • Logical Units of Work (LUW) 라고도 한다.
  • 트랜잭션이 안전하게 수행된다는 것을 보장하기 위한 성질인 ACID가 있다. 
    (하지만 성능을 위해 이런 특성들이 종종 완화되곤 한다.)
    • Atomicity (원자성) : all-or-nothing 개념으로, 한 번 트랜잭션 수행이 시작되었다면 중간에 중단되지 않아야 한다.
    • Consistency (일관성) : valid state(고립 상태 : 동시에 수행되는 트랜잭션이 없는 걸 보장하는 상태)에서의 
      트랜잭션 수행이 데이터베이스의 일관성을 보존하여야 한다.
    • Isolation (고립성) : 여러 트랜잭션들이 동시에 수행되더라도 어느 하나가 마친 뒤에 
      다른 트랜잭션이 시작하는 것과 같이 되도록 보장해야 한다.
    • Durability (지속성) : 트랜잭션이 성공적으로 수행 완료되고 나면 
      트랜잭션에 의해 데이터베이스에 변경된 내용은 지속되어야 한다. (이것이 만약 시스템에 오류를 발생시키더라도) 

예)

ATM기에서의 계좌 이체를 한 트랜잭션으로 생각해보자. 

A계좌로부터 B계좌로 x원을 계좌이체하는 트랜잭션에서

  1. A계좌에서 x원 만큼 차감
  2. B계좌에서 x원 만큼 증가 (중략)

    이러한 단계들로 되어 있는데(차감한 순간 B 계좌로 넣어지는 것은 아니므로) 단계 1만 진행한 상태로 오류가 나
    트랜잭션이 중단되면 A계좌의 잔고는 차감된 상태이며 B계좌에는 잔고가 변화가 없는, 있어서는 안 될 사태가 생긴다.
    이 때 ACID의 원자성 보장의 필요성을 알 수 있다. 또한 무결성 제약조건 및 잔고의 합이 같아야 한다는 일관적인
    조건들로 보아 일관성 보장도 따른다. 

Query processor

  • 파일 혹은 데이터베이스 접근을 위해 사용자의 조회 요구를 직접 사용될 수 있는 명령어로 변환시키는 프로그램 혹은 프로그래머.
  • Query compiler, Execution engine 두 가지로 표현할 수 있다.
    • Query compiler : 사용자의 query를 query plan, 즉 Low-level language로 번역해 주며 3가지 주 요소를 포함한다. 
      또한 작업들을 가장 빠르게 수행하기 위해 메타데이터/통계 등을 이용한다.
    • Execution engine : 데이터를 관리/제어/조작 하기위해 버퍼에 넣어 사용한다. 
      액세스 충돌 및 lock을 피하기 위해 Scheduler, 데이터의 변화를 확실히 하기위해 Log manager가 필요하다.

Query compiler
UNIT설명
Query parser텍스트 형태의 query를 트리 구조로 빌드함
Query preprocessorquery에 대한 의미론적 검사(모든 relation과 그 관계를 언급 했는지 등)와 
parse 트리를 대수 연산자 트리로 변환시키는 등을 수행
Query optimizer초기의 query plan을 가장 적합한 형태로 결정


블로그 이미지

차트

소소한 일상 C코드 DB 항상 행복하게^-^★

,