diff --git "a/\354\213\254\354\242\205\355\225\234/[lecture19] mvcc (1\353\266\200)/README.md" "b/\354\213\254\354\242\205\355\225\234/[lecture19] mvcc (1\353\266\200)/README.md" new file mode 100644 index 0000000..e87b43d --- /dev/null +++ "b/\354\213\254\354\242\205\355\225\234/[lecture19] mvcc (1\353\266\200)/README.md" @@ -0,0 +1,86 @@ +# lecture19 - mvcc (1부) + +## MVCC (Multiversion concurrency control) + +MVCC는 커밋된 데이터만 읽는다. + +### committed read + +이 isolation 레벨로 데이터를 읽으면 read하는 시간을 기준으로 그전에 커밋된 데이터를 읽는다. + +![alt text]() + +따라서 이 상태에서는 `tx2` 가 write한 50이 조회된다. + +### repeatable read + +tx 시작 시간 기준으로 그전에 커밋된 데이터를 읽는다. + +![alt text]() + +따라서 이 상태에서는 10이 조회된다. + +> [!NOTE] +> +> **어떤 isolation 레벨로 데이터를 읽는지는 DBMS마다 다르다.** + +### serializable + +SSI 기법이 적용된 MVCC로 동작한다. + +### read uncommitted + +MVCC는 커밋된 데이터를 읽기 때문에 이 레벨에서는 MVCC가 적용되지 않는다. + +## MVCC 특징 + +- 데이터를 읽을 때 `특정 시점 기준` 으로 가장 최근에 `커밋` 된 데이터를 읽는다. + - _이때 특정 시점은 isolation 레벨에 따라 다르다._ +- 데이터 변화 이력을 관리한다. + - 따라서 추가적인 저장 공간을 사용하게 된다. +- read, write는 서로 block하지 않는다. + - 동시에 처리할 수 있는 트랜잭션이 늘어나 성능이 더 좋아질 수 있다. + +> [!NOTE] +> +> 특정 시점을 기준으로 커밋된 데이터를 읽는 것을 MySQL에서 `consistent read` 라고 부른다. + +## MVCC에서 발생 가능한 문제 + +### read committed 레벨을 사용하는 경우 + +> 현재 예제는 PostgreSQL을 기반으로 설명한다. + +![alt text]() + +`tx1` 의 쓰기 작업의 결과가 사라지는 문제가 있다. + +왜냐하면 `tx1` 이 x값애 쓰기 작업을 할때 락을 획득한다. +또한 `tx2` 는 커밋된 시점의 x값을 읽으므로 50을 읽는다. +30을 입금하려 하지만 `tx1` 이 쓰기 락을 가지고 있으므로 대기하게 되고 결과적으로 `lost update` 문제가 발생한다. + +### 해결법 + +tx2 의 isolation 레벨을 repeatable read 로 바꾸면 해결된다. + +PostgreSQL 는 `repeatable read` 레벨을 사용하면 같은 데이터에 먼저 update한 tx가 커밋되었다면 이후 tx는 롤백하는 기능이 있다. + +![alt text]() + +이런 특성을 `fist-updater-win` 라고도 한다. + +### 더 고민해보자 + +일단 트랜잭션마다 서로 다른 isolation 레벨을 가져갈 수 있다. + +그렇다면 tx1 이 read committed 레벨을 사용해도 정말 괜찮은지 보자. + +![alt text]() + +이처럼 트랜잭션의 동작 순서가 바뀐다면 lost update 문제가 발생하게 된다. + +**즉 서로 연관되는 트랜잭션의 isoloation 레벨을 동시에 고려해야 문제를 해결할 수 있다는 것이다.** + +![alt text]() + +`tx1` 의 isolation 레벨을 바꾸더라도 `tx1` 은 롤백되는 상황이 발생할 수 있고 여전히 `lost update` 문제가 발생한다. diff --git "a/\354\213\254\354\242\205\355\225\234/[lecture19] mvcc (1\353\266\200)/read committed \353\254\270\354\240\234.png" "b/\354\213\254\354\242\205\355\225\234/[lecture19] mvcc (1\353\266\200)/read committed \353\254\270\354\240\234.png" new file mode 100644 index 0000000..108f385 Binary files /dev/null and "b/\354\213\254\354\242\205\355\225\234/[lecture19] mvcc (1\353\266\200)/read committed \353\254\270\354\240\234.png" differ diff --git "a/\354\213\254\354\242\205\355\225\234/[lecture19] mvcc (1\353\266\200)/read committed \353\254\270\354\240\234\354\240\220.png" "b/\354\213\254\354\242\205\355\225\234/[lecture19] mvcc (1\353\266\200)/read committed \353\254\270\354\240\234\354\240\220.png" new file mode 100644 index 0000000..a098285 Binary files /dev/null and "b/\354\213\254\354\242\205\355\225\234/[lecture19] mvcc (1\353\266\200)/read committed \353\254\270\354\240\234\354\240\220.png" differ diff --git "a/\354\213\254\354\242\205\355\225\234/[lecture19] mvcc (1\353\266\200)/read committed.png" "b/\354\213\254\354\242\205\355\225\234/[lecture19] mvcc (1\353\266\200)/read committed.png" new file mode 100644 index 0000000..eba93da Binary files /dev/null and "b/\354\213\254\354\242\205\355\225\234/[lecture19] mvcc (1\353\266\200)/read committed.png" differ diff --git "a/\354\213\254\354\242\205\355\225\234/[lecture19] mvcc (1\353\266\200)/repeatable read \355\225\264\352\262\260\353\262\225.png" "b/\354\213\254\354\242\205\355\225\234/[lecture19] mvcc (1\353\266\200)/repeatable read \355\225\264\352\262\260\353\262\225.png" new file mode 100644 index 0000000..50014e7 Binary files /dev/null and "b/\354\213\254\354\242\205\355\225\234/[lecture19] mvcc (1\353\266\200)/repeatable read \355\225\264\352\262\260\353\262\225.png" differ diff --git "a/\354\213\254\354\242\205\355\225\234/[lecture19] mvcc (1\353\266\200)/repeatable read.png" "b/\354\213\254\354\242\205\355\225\234/[lecture19] mvcc (1\353\266\200)/repeatable read.png" new file mode 100644 index 0000000..ca629f2 Binary files /dev/null and "b/\354\213\254\354\242\205\355\225\234/[lecture19] mvcc (1\353\266\200)/repeatable read.png" differ diff --git "a/\354\213\254\354\242\205\355\225\234/[lecture19] mvcc (1\353\266\200)/repeatable read\353\241\234 \353\260\224\352\277\224\353\217\204 \353\254\270\354\240\234.png" "b/\354\213\254\354\242\205\355\225\234/[lecture19] mvcc (1\353\266\200)/repeatable read\353\241\234 \353\260\224\352\277\224\353\217\204 \353\254\270\354\240\234.png" new file mode 100644 index 0000000..c582a51 Binary files /dev/null and "b/\354\213\254\354\242\205\355\225\234/[lecture19] mvcc (1\353\266\200)/repeatable read\353\241\234 \353\260\224\352\277\224\353\217\204 \353\254\270\354\240\234.png" differ diff --git "a/\354\213\254\354\242\205\355\225\234/[lecture20] mvcc (2\353\266\200)/README.md" "b/\354\213\254\354\242\205\355\225\234/[lecture20] mvcc (2\353\266\200)/README.md" new file mode 100644 index 0000000..f949c5f --- /dev/null +++ "b/\354\213\254\354\242\205\355\225\234/[lecture20] mvcc (2\353\266\200)/README.md" @@ -0,0 +1,48 @@ +# lecture20 - mvcc (2부) + +## MySQL에서 lost update 해결 + +### locking read + +![alt text]() + +MySQL에서는 select for update 구문을 사용할 수 있다. +단, `tx1` , `tx2` 모두 `locking read` 를 사용해야만 한다. +`tx1` 이 `locking read` 를 사용하지 db에 커밋되어 있는 값을 읽게 된다. + +![alt text]() + +또한 MySQL에서 locking read는 가장 최근에 커밋된 데이터를 읽는다. +따라서 repeatable read 레벨이더라도 트랜잭션의 시작 시점의 값을 읽지 않고 가장 최근에 커밋된 데이터를 읽도록 동작한다. + +![alt text]() + +### wrtie skew 문제 + +정상적으로 동작하면 결과는 다음과 같다. + +![alt text]() + +그러나 아래처럼 locking read를 사용하지 않으면 문제가 생긴다. + +![alt text]() + +![alt text]() + +#### MySQL에서의 해결 - select for update + +![alt text]() + +MySQL에서 locking read를 사용하면 repeatable read 격리 수준이더라도 가장 최근에 커밋된 데이터를 읽게 되므로 문제가 해결된다. + +#### PostgreSQL + +그러나 PostgreSQL에서 repeatable read 격리 수준에서는 동작하는 방식이 달라 먼저 update한 tx가 커밋되면 이후 tx는 롤백된다. + +![alt text]() + +이번엔 select for share 로 읽기 잠금을 획득하더라도 동일한 이유로 롤백된다. + +### 정리 + +DBMS의 종류에 따라 동작 방식이 다르므로 상황에 알맞은 방법을 적용해야 한다. diff --git "a/\354\213\254\354\242\205\355\225\234/[lecture20] mvcc (2\353\266\200)/locking read \354\202\254\354\232\251\355\225\230\354\247\200 \354\225\212\354\235\214.png" "b/\354\213\254\354\242\205\355\225\234/[lecture20] mvcc (2\353\266\200)/locking read \354\202\254\354\232\251\355\225\230\354\247\200 \354\225\212\354\235\214.png" new file mode 100644 index 0000000..9851313 Binary files /dev/null and "b/\354\213\254\354\242\205\355\225\234/[lecture20] mvcc (2\353\266\200)/locking read \354\202\254\354\232\251\355\225\230\354\247\200 \354\225\212\354\235\214.png" differ diff --git "a/\354\213\254\354\242\205\355\225\234/[lecture20] mvcc (2\353\266\200)/locking read1.png" "b/\354\213\254\354\242\205\355\225\234/[lecture20] mvcc (2\353\266\200)/locking read1.png" new file mode 100644 index 0000000..37cb2d3 Binary files /dev/null and "b/\354\213\254\354\242\205\355\225\234/[lecture20] mvcc (2\353\266\200)/locking read1.png" differ diff --git "a/\354\213\254\354\242\205\355\225\234/[lecture20] mvcc (2\353\266\200)/locking read2.png" "b/\354\213\254\354\242\205\355\225\234/[lecture20] mvcc (2\353\266\200)/locking read2.png" new file mode 100644 index 0000000..c08b5d2 Binary files /dev/null and "b/\354\213\254\354\242\205\355\225\234/[lecture20] mvcc (2\353\266\200)/locking read2.png" differ diff --git "a/\354\213\254\354\242\205\355\225\234/[lecture20] mvcc (2\353\266\200)/locking read3.png" "b/\354\213\254\354\242\205\355\225\234/[lecture20] mvcc (2\353\266\200)/locking read3.png" new file mode 100644 index 0000000..d7c0600 Binary files /dev/null and "b/\354\213\254\354\242\205\355\225\234/[lecture20] mvcc (2\353\266\200)/locking read3.png" differ diff --git "a/\354\213\254\354\242\205\355\225\234/[lecture20] mvcc (2\353\266\200)/mysql solution.png" "b/\354\213\254\354\242\205\355\225\234/[lecture20] mvcc (2\353\266\200)/mysql solution.png" new file mode 100644 index 0000000..d503ba4 Binary files /dev/null and "b/\354\213\254\354\242\205\355\225\234/[lecture20] mvcc (2\353\266\200)/mysql solution.png" differ diff --git "a/\354\213\254\354\242\205\355\225\234/[lecture20] mvcc (2\353\266\200)/postgresql rollback1.png" "b/\354\213\254\354\242\205\355\225\234/[lecture20] mvcc (2\353\266\200)/postgresql rollback1.png" new file mode 100644 index 0000000..f6e7278 Binary files /dev/null and "b/\354\213\254\354\242\205\355\225\234/[lecture20] mvcc (2\353\266\200)/postgresql rollback1.png" differ diff --git "a/\354\213\254\354\242\205\355\225\234/[lecture20] mvcc (2\353\266\200)/repeatable read \354\240\225\354\203\201.png" "b/\354\213\254\354\242\205\355\225\234/[lecture20] mvcc (2\353\266\200)/repeatable read \354\240\225\354\203\201.png" new file mode 100644 index 0000000..2e95180 Binary files /dev/null and "b/\354\213\254\354\242\205\355\225\234/[lecture20] mvcc (2\353\266\200)/repeatable read \354\240\225\354\203\201.png" differ diff --git "a/\354\213\254\354\242\205\355\225\234/[lecture20] mvcc (2\353\266\200)/wrtie skew.png" "b/\354\213\254\354\242\205\355\225\234/[lecture20] mvcc (2\353\266\200)/wrtie skew.png" new file mode 100644 index 0000000..10dc210 Binary files /dev/null and "b/\354\213\254\354\242\205\355\225\234/[lecture20] mvcc (2\353\266\200)/wrtie skew.png" differ diff --git "a/\354\213\254\354\242\205\355\225\234/[lecture21] db \355\205\214\354\235\264\353\270\224 \354\204\244\352\263\204 \354\236\230\353\252\273\355\225\230\353\251\264 \353\260\234\354\203\235\355\225\230\353\212\224 \353\254\270\354\240\234/README.md" "b/\354\213\254\354\242\205\355\225\234/[lecture21] db \355\205\214\354\235\264\353\270\224 \354\204\244\352\263\204 \354\236\230\353\252\273\355\225\230\353\251\264 \353\260\234\354\203\235\355\225\230\353\212\224 \353\254\270\354\240\234/README.md" new file mode 100644 index 0000000..1db4b82 --- /dev/null +++ "b/\354\213\254\354\242\205\355\225\234/[lecture21] db \355\205\214\354\235\264\353\270\224 \354\204\244\352\263\204 \354\236\230\353\252\273\355\225\230\353\251\264 \353\260\234\354\203\235\355\225\230\353\212\224 \353\254\270\354\240\234/README.md" @@ -0,0 +1,34 @@ +# lecture 21 - db 테이블 설계 잘못하면 발생하는 문제 + +## 부서와 사원을 관리하는 테이블 + +| empl_id | empl_name | birth_date | position | salary | dept_id | dept_name | dept_leader_id | +| ------- | --------- | ---------- | -------- | ------ | ------- | --------- | -------------- | +| 1 | MESSI | ... | ... | ... | 1001 | DEV | 1 | +| 2 | JINHO | ... | ... | ... | 1001 | DEV | 1 | +| 3 | JENNY | ... | ... | ... | null | null | null | +| ? | ? | ? | ? | ? | 1002 | QA | null | + +### 문제점 + +부서가 지정되지 않은 직원을 추가할 때, 직원이 없는 부서를 추가할 때 등의 상황에서 불편한 점이 많다. + +데이터가 지정되지 않은 경우 null값을 사용해야 한다. +또한 어떤 부서에 직원이 추가될 때마다 기존 부서 저장용 행을 지우고 삽입해야 한다. + +이상 현상이 발생할 수 있는 설계다. + +- **수정 이상** + - 부서 이름을 수정하는 경우 모든 행을 수정하지 않는 경우 부서명이 달라지는 현상이 발생할 수 있다. +- **삽입 이상** + - 부서에 첫 직원 정보를 저장해야 할 때 기존 부서 정보를 저장하는 행을 제거한 후 직원 정보를 저장해야 한다. +- **삭제 이상** + +## 테이블을 잘 설계하지 않는 경우 + +- 중복 데이터 문제 +- spurious tupples +- null 값이 많아짐으로 인한 문제점 + - null값이 있는 칼럼으로 조인하는 경우 예상 밖의 결과가 나올 수 있음 + - null값이 있는 칼럼에 aggregate function을 사용했을 때 주의 필요 + - 불필요한 저장공간 낭비 diff --git "a/\354\213\254\354\242\205\355\225\234/[lecture22] db \354\240\225\352\267\234\355\231\224\354\235\230 \352\267\274\353\263\270 (functional dependency)/README.md" "b/\354\213\254\354\242\205\355\225\234/[lecture22] db \354\240\225\352\267\234\355\231\224\354\235\230 \352\267\274\353\263\270 (functional dependency)/README.md" new file mode 100644 index 0000000..44067a6 --- /dev/null +++ "b/\354\213\254\354\242\205\355\225\234/[lecture22] db \354\240\225\352\267\234\355\231\224\354\235\230 \352\267\274\353\263\270 (functional dependency)/README.md" @@ -0,0 +1,73 @@ +# lecture22 - db 정규화의 근본 (functional dependency) + +## functional dependency + +`한 테이블에 있는 두 개의 속성 집합 사이의 제약` 을 의미한다. + +### EMPLOYEE + +| empl_id | empl_name | birth_date | position | salary | dept_id | +| ------- | --------- | ---------- | -------- | ------ | ------- | + +#### 집합 X + +- empl_id + +#### 집합 Y + +- empl_name +- birth_date +- position +- salary +- dept_id + +X 값에 따라 Y 값이 유일하게 (uniquely) 결정될 때 `X가 Y를 함수적으로 결정한다 (functionally determine)`, `Y가 X에 함수적으로 의존한다 (functionally dependent)` 라고 말할 수 있고, 두 집합 사이의 이러한 제약 관계를 functional dependency (FD)라고 부른다. + +> [!IMPORTANT] +> +> 테이블의 스키마를 보고 의미적으로 FD가 존재하는지 파악해야 한다. + +## 함수적 종속 종류 + +### Trivial functional dependency + +X -> Y 일 때, Y가 X의 부분집한인 경우 + +``` +{ a, b, c } -> { c } +{ a, b, c } -> { a, c } +{ a, b, c } -> { a, b, c } +``` + +### Non-trivial functional dependency + +X -> Y 일 때, Y가 X의 부분집합이 아닌 경우 + +``` +{ a, b, c } -> { b, c, d} +{ a, b, c } -> { d, e } // 완벽히 겹치는 것이 없으므로 completely non-trivial FD이기도 함 +``` + +### Partial functional dependency + +X -> Y 일때, X의 진부분집합도 Y를 함수적으로 결정할 수 있는 경우 + +``` +{ empl_id, empl_name } -> { birth_date } 이 가능하다면 +{ empl_id } -> { birth_date } 도 가능하다. +``` + +### Full functional dependency + +X -> Y 일때, 모든 X의 진부분집합으로 Y를 함수적으로 결정할 수 없는 경우 + +``` +{ stu_id, class_id } -> { grade } 이 가능하다면 +{ stu_id }, { class_id }, {} 만으로 { grade }를 결정할 수 없다. +``` + +## FD와 관련된 추가적인 개념 + +- Armstrong's axioms +- Closure +- minimal cover diff --git "a/\354\213\254\354\242\205\355\225\234/[lecture23] db \354\240\225\352\267\234\355\231\224 (1NF, 2NF)/1NF.png" "b/\354\213\254\354\242\205\355\225\234/[lecture23] db \354\240\225\352\267\234\355\231\224 (1NF, 2NF)/1NF.png" new file mode 100644 index 0000000..f6fa1b3 Binary files /dev/null and "b/\354\213\254\354\242\205\355\225\234/[lecture23] db \354\240\225\352\267\234\355\231\224 (1NF, 2NF)/1NF.png" differ diff --git "a/\354\213\254\354\242\205\355\225\234/[lecture23] db \354\240\225\352\267\234\355\231\224 (1NF, 2NF)/2NF.png" "b/\354\213\254\354\242\205\355\225\234/[lecture23] db \354\240\225\352\267\234\355\231\224 (1NF, 2NF)/2NF.png" new file mode 100644 index 0000000..afb54b7 Binary files /dev/null and "b/\354\213\254\354\242\205\355\225\234/[lecture23] db \354\240\225\352\267\234\355\231\224 (1NF, 2NF)/2NF.png" differ diff --git "a/\354\213\254\354\242\205\355\225\234/[lecture23] db \354\240\225\352\267\234\355\231\224 (1NF, 2NF)/README.md" "b/\354\213\254\354\242\205\355\225\234/[lecture23] db \354\240\225\352\267\234\355\231\224 (1NF, 2NF)/README.md" new file mode 100644 index 0000000..698ead7 --- /dev/null +++ "b/\354\213\254\354\242\205\355\225\234/[lecture23] db \354\240\225\352\267\234\355\231\224 (1NF, 2NF)/README.md" @@ -0,0 +1,55 @@ +# lecture23 - db 정규화 (1NF, 2NF) + +## DB 정규화 + +데이터 중복과 삽입, 갱신, 삭제 이상을 최소화하기 위해 일련의 normal formms에 따라 관계형 DB를 수정하는 과정이다. + +## 예시 + +- bank_name +- account_num +- account_id +- class +- ratio +- empl_id +- empl_name +- card_id + +- super key: table에서 tuple들을 unique하게 식별할 수 있는 attributes set +- (candidate) key: 어느 한 attribute라도 제거하면 unique하게 tuples를 식별할 수 없는 super key + - { account_id }, { bank_name, account_num } +- primary key: table에서 tuple들을 unique하게 식별하려고 선택된 candidate) key + - { account_id } +- prime attribute: 임의의 key에 속하는 attribute + - account_id, bank_name, account_num +- non-prime attribute: 어떠한 key에도 속하지 않는 attribute + - class, ratio, empl_id, empl_name, card_id + +## 1NF + +**attribute의 값은 반드시 나눠질 수 없는 단일한 값이어야 한다.** + +![alt text](1NF.png) + +그러나 중복 데이터가 있고 PK도 변경해야 한다. + +(candidate) key: { account_id, card_id }, { bank_name, account_num, card_id } +non-prime attribute: class, ratio, empl_id, empl_name + +현재 상황에서 `{ account_id, card_id } -> { class, ratio, empl_id, empl_name }` FD가 있다. + +그런데 `{ account_id } -> { class, ratio, empl_id, empl_name }` FD도 가능하다. + +즉 모든 `non-prime attribute` 들이 `{ account_id, card_id }` 에 `partially dependent` 하다. + +또한 `{ bank_name, account_num, card_id }` 에도 `partially dependent` 하다. + +## 2NF + +**모든 non-prime attribute는 모든 key에 fully functionally dependent 해야 한다.** + +**다르게 말하면 key가 composite key가 아니라면 2NF는 자동적으로 만족한다고도 말할 수 있다. (일반적으로)** + +이제 `card_id` 를 분리해야 한다. + +![alt text](2NF.png) diff --git "a/\354\213\254\354\242\205\355\225\234/[lecture24] db \354\240\225\352\267\234\355\231\224 (3NF, BCNF, \354\227\255\354\240\225\352\267\234\355\231\224)/3NF \354\235\264\355\233\204.png" "b/\354\213\254\354\242\205\355\225\234/[lecture24] db \354\240\225\352\267\234\355\231\224 (3NF, BCNF, \354\227\255\354\240\225\352\267\234\355\231\224)/3NF \354\235\264\355\233\204.png" new file mode 100644 index 0000000..fa3d115 Binary files /dev/null and "b/\354\213\254\354\242\205\355\225\234/[lecture24] db \354\240\225\352\267\234\355\231\224 (3NF, BCNF, \354\227\255\354\240\225\352\267\234\355\231\224)/3NF \354\235\264\355\233\204.png" differ diff --git "a/\354\213\254\354\242\205\355\225\234/[lecture24] db \354\240\225\352\267\234\355\231\224 (3NF, BCNF, \354\227\255\354\240\225\352\267\234\355\231\224)/3NF.png" "b/\354\213\254\354\242\205\355\225\234/[lecture24] db \354\240\225\352\267\234\355\231\224 (3NF, BCNF, \354\227\255\354\240\225\352\267\234\355\231\224)/3NF.png" new file mode 100644 index 0000000..0a3bd07 Binary files /dev/null and "b/\354\213\254\354\242\205\355\225\234/[lecture24] db \354\240\225\352\267\234\355\231\224 (3NF, BCNF, \354\227\255\354\240\225\352\267\234\355\231\224)/3NF.png" differ diff --git "a/\354\213\254\354\242\205\355\225\234/[lecture24] db \354\240\225\352\267\234\355\231\224 (3NF, BCNF, \354\227\255\354\240\225\352\267\234\355\231\224)/BCNF \354\235\264\355\233\204.png" "b/\354\213\254\354\242\205\355\225\234/[lecture24] db \354\240\225\352\267\234\355\231\224 (3NF, BCNF, \354\227\255\354\240\225\352\267\234\355\231\224)/BCNF \354\235\264\355\233\204.png" new file mode 100644 index 0000000..bf51cee Binary files /dev/null and "b/\354\213\254\354\242\205\355\225\234/[lecture24] db \354\240\225\352\267\234\355\231\224 (3NF, BCNF, \354\227\255\354\240\225\352\267\234\355\231\224)/BCNF \354\235\264\355\233\204.png" differ diff --git "a/\354\213\254\354\242\205\355\225\234/[lecture24] db \354\240\225\352\267\234\355\231\224 (3NF, BCNF, \354\227\255\354\240\225\352\267\234\355\231\224)/BCNF.png" "b/\354\213\254\354\242\205\355\225\234/[lecture24] db \354\240\225\352\267\234\355\231\224 (3NF, BCNF, \354\227\255\354\240\225\352\267\234\355\231\224)/BCNF.png" new file mode 100644 index 0000000..4c66929 Binary files /dev/null and "b/\354\213\254\354\242\205\355\225\234/[lecture24] db \354\240\225\352\267\234\355\231\224 (3NF, BCNF, \354\227\255\354\240\225\352\267\234\355\231\224)/BCNF.png" differ diff --git "a/\354\213\254\354\242\205\355\225\234/[lecture24] db \354\240\225\352\267\234\355\231\224 (3NF, BCNF, \354\227\255\354\240\225\352\267\234\355\231\224)/README.md" "b/\354\213\254\354\242\205\355\225\234/[lecture24] db \354\240\225\352\267\234\355\231\224 (3NF, BCNF, \354\227\255\354\240\225\352\267\234\355\231\224)/README.md" new file mode 100644 index 0000000..e38c0f3 --- /dev/null +++ "b/\354\213\254\354\242\205\355\225\234/[lecture24] db \354\240\225\352\267\234\355\231\224 (3NF, BCNF, \354\227\255\354\240\225\352\267\234\355\231\224)/README.md" @@ -0,0 +1,33 @@ +# lecture24 - db 정규화 (3NF, BCNF, 역정규화) + +![alt text](3NF.png) + +`{ account_id } -> { empl_id }` + +`{ empl_id } -> { empl_name }` + +따라서 `{ account_id } -> { empl_name }` 함수적 종속이 존재한다. + +`{ bank_name, account_num } -> { empl_id }` 이므로 `{ bank_name, account_num } -> { empl_name }` 함수적 종속이 존재한다. + +## transitive functional dependency + +`X -> Y & Y -> Z` 라면 `X -> Z` 도 함수적 종속이다. 단 Y, Z 모두 어떤 키에 대해서 부분집합이 아니여야 한다. + +## 3NF + +모든 non-prime attribute는 어떤 key에도 transitively dependent 하면 안된다. + +![alt text](<3NF 이후.png>) + +**3NF까지 되면 `정규화 됐다` 라고 말할 수 있다.** + +## BCNF + +모든 유효한 non-trivial FD X -> Y는 X가 super key여야 한다. + +![alt text](BCNF.png) + +![alt text]() + +더이상 bank_name이 중복되어 저장되는 일이 없다.