diff --git "a/\352\271\200\354\227\260\354\232\261/[lecture19] mvcc (1\353\266\200)/README.md" "b/\352\271\200\354\227\260\354\232\261/[lecture19] mvcc (1\353\266\200)/README.md" new file mode 100644 index 0000000..2e084f4 --- /dev/null +++ "b/\352\271\200\354\227\260\354\232\261/[lecture19] mvcc (1\353\266\200)/README.md" @@ -0,0 +1,29 @@ +> # [Lecture 19](https://www.youtube.com/watch?v=wiVvVanI3p4&list=PLcXyemr8ZeoREWGhhZi5FZs6cvymjIBVe&index=19) + +## 주요 내용 + +- MVCC (MultiVersion Concurrency Control) +- isolation level과 함께 MVCC case study (MySQL, postgreSQL) +- postgreSQL의 MVCC Lost Update + +## MVCC + +- MultiVersion Concurrency Control +- Lock + + + | | Read | Write | + | --- | --- | --- | + | Read | O | O | + | Write | O | X | +- MVCC는 데이터를 읽을 때 특정 시점 기준으로 가장 최근에 commit된 데이터만 읽음 (중요한 특징!) +- 데이터 변화(write) 이력을 관리함 (공간이 더 필요해서 단점이 될 수 있음) +- read와 write는 서로 block하지 않음!! +- MySQL에서는 특정 시점 기준을 Consistent read라고 함 + +## postgreSQL의 MVCC Lost Update + +- 변경된 값에 대해서 덮어 쓰게 되는 경우(lost update)가 발생할 수 있음 +- postgreSQL에서 repeatable read 레벨은 같은 데이터에 먼저 update한 tx이 commit되면 나중 tx는 rollback된다는 특징이 있음 (first-updater-win) +- 이 경우 한 트랜잭션의 레벨만 repeatable read로 두는 것이 아닌 연관된 트랜잭션을 모두 repeatable read로 둬야함!! (트랜잭션마다 서로 다른 isolation level을 줄 수 있음) +- 즉 postgreSQL의 MVCC는 lost update를 repeatable read 만으로 해결 가능 \ No newline at end of file diff --git "a/\352\271\200\354\227\260\354\232\261/[lecture20] mvcc (2\353\266\200)/README.md" "b/\352\271\200\354\227\260\354\232\261/[lecture20] mvcc (2\353\266\200)/README.md" new file mode 100644 index 0000000..3da33ed --- /dev/null +++ "b/\352\271\200\354\227\260\354\232\261/[lecture20] mvcc (2\353\266\200)/README.md" @@ -0,0 +1,57 @@ +> # [Lecture 20](https://www.youtube.com/watch?v=-kJ3fxqFmqA&list=PLcXyemr8ZeoREWGhhZi5FZs6cvymjIBVe&index=20) + +## 주요 내용 + +- MySQL의 MVCC Lost Update + +## MySQL에서의 Lost Update + +- 변경된 값에 대해서 덮어 쓰게 되는 경우(lost update)가 발생할 수 있음 +- MySQL에서의 for update 문을 추가해서 해결! +- MySQL에서 locking read는 가장 최근에 commit된 데이터를 읽음!! +- Locking Read : 트랜잭션이 데이터를 읽을 때 해당 데이터에 대한 잠금을 거는 방식 + + ```sql + select balance + from account + where id = 'x' + for update; + ``` + +- 대충 정리 시나리오 + 1. tx2가 read(x)를 for update를 하여 lock을 취득함 (이때 x는 50이라 가정) + 2. tx1이 read(x)를 for update로 하는데 이미 tx2에서 점유중이기 때문에 대기 + 3. tx2의 이후 로직 write(x = 80)을 실행 후 commit한 뒤 unlock + 4. tx2에서 lock을 반환하였으니 대기중이던 tx1에서 lock을 취득함 + 5. 이때 tx1은 가장 최근의 commit된 데이터를 읽음 (즉 80이 읽힘) + 6. 이후 tx1은 write(x = 40)을 수행후 read(y)를 하는데 이때도 locking read인 for update를 수행 + 7. 이후 write(y = 50)을 한 뒤 commit후 unlock을 함 +- for update : exclusive lock(write-lock) +- for share : shared lock(read-lock) + +## repeatable read 레벨에서의 write skew + +- 이는 MySQL과 postgreSQL 둘 다 발생함 +- 이를 해결하기 위해 MySQL은 locking read를 사용함 +- 이를 해결하기 위해 postgreSQL for update와 for share 쓰면 됨 (다만 작동 방식이 좀 다름!) + +## postgreSQL의 for update와 for share 작동 방식 + +- MySQL과 좀 다름 +- postgreSQL은 repeatable read 레벨에서는 같은 데이터가 다른 트랜잭션에서 update후 commit 됐다면 나중 트랜잭션은 다 rollback되기 때문에 + +## serializable 레벨 + +- 이 레벨을 통해 write skew를 해결할 수도 있음 +- MySQL serializable level + - repeatable read와 유사함 + - tx의 모든 평범한 select문은 암묵적으로 select … for share 처럼 동작 +- postgreSQL serializable level + - SSI(serializable snapshot isolation)로 구현 + - first-committer-wins + +## 마무리 + +- 많은 RDBMS가 MVCC로 동작함 +- 이 MVCC는 각 RDBMS마다 내부적으로 동작하는게 좀 다름 +- 그래서 사용하고자 하는 RDBMS의 MVCC동작을 찾아보고 잘 알고 있자! diff --git "a/\352\271\200\354\227\260\354\232\261/[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/\352\271\200\354\227\260\354\232\261/[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..f350738 --- /dev/null +++ "b/\352\271\200\354\227\260\354\232\261/[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,48 @@ +> # [Lecture 21](https://www.youtube.com/watch?v=JwfQ8ouhAzA&list=PLcXyemr8ZeoREWGhhZi5FZs6cvymjIBVe&index=21) + +## 주요 내용 + +- DB Schema 설계의 중요성 + +## Insertion Anomaly + +- 삽입 이상 현상 +- 문제점
+ + + - 중복된 데이터로 인한 저장 공간 낭비 (empl_id = 1, 2) + - 실수로 인한 데이터 불일치 가능성 존재 + - null 값은 적게 쓰는 것이 좋음 (empl_id = 3) +- 해결
+ + + +## Deletion Anomaly + +- 삭제 이상 현상 +- 문제점
+ + + - empl_id = 5를 삭제하면 QA부서에 대한 정보가 다 없어짐 + - empl_id = 5인 데이터의 부서 정보를 제외한 값을 null로 하여 관리하면 QA부서에 대한 정보는 존재하나 null이 많아짐, pk인 empl_id의 의미와도 맞지 않는 정보 +- 해결
+ + + +## Modification Anomaly + +- 갱신 이상 현상 +- 문제점
+ + + - DEV부서가 DEV1로 변경되었는데 JINHO의 부서명만 DEV1로 변경된 경우 (MESSI의 부서명과의 데이터 불일치 발생) +- 해결
+ + + +## 바른 DB Schema 설계 + +1. 의미적으로 관련있는 속성들끼리 테이블을 구성 +2. 중복 데이터를 최대한 허용하지 않도록 설계 +3. join 수행 시 가짜 데이터가 생기지 않도록 설계 (매우 중요) +4. 되도록이면 null 값을 줄일 수 있는 방향으로 설계 \ No newline at end of file diff --git "a/\352\271\200\354\227\260\354\232\261/[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/img/lecture-21-2.png" "b/\352\271\200\354\227\260\354\232\261/[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/img/lecture-21-2.png" new file mode 100644 index 0000000..f0265c2 Binary files /dev/null and "b/\352\271\200\354\227\260\354\232\261/[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/img/lecture-21-2.png" differ diff --git "a/\352\271\200\354\227\260\354\232\261/[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/img/lecture-21-3.png" "b/\352\271\200\354\227\260\354\232\261/[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/img/lecture-21-3.png" new file mode 100644 index 0000000..cb6fb95 Binary files /dev/null and "b/\352\271\200\354\227\260\354\232\261/[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/img/lecture-21-3.png" differ diff --git "a/\352\271\200\354\227\260\354\232\261/[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/img/lecture-21-4.png" "b/\352\271\200\354\227\260\354\232\261/[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/img/lecture-21-4.png" new file mode 100644 index 0000000..582126d Binary files /dev/null and "b/\352\271\200\354\227\260\354\232\261/[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/img/lecture-21-4.png" differ diff --git "a/\352\271\200\354\227\260\354\232\261/[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/img/lecture21-1.png" "b/\352\271\200\354\227\260\354\232\261/[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/img/lecture21-1.png" new file mode 100644 index 0000000..6272746 Binary files /dev/null and "b/\352\271\200\354\227\260\354\232\261/[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/img/lecture21-1.png" differ diff --git "a/\352\271\200\354\227\260\354\232\261/[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/img/lecture21-2.png" "b/\352\271\200\354\227\260\354\232\261/[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/img/lecture21-2.png" new file mode 100644 index 0000000..f0265c2 Binary files /dev/null and "b/\352\271\200\354\227\260\354\232\261/[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/img/lecture21-2.png" differ diff --git "a/\352\271\200\354\227\260\354\232\261/[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/img/lecture21-3.png" "b/\352\271\200\354\227\260\354\232\261/[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/img/lecture21-3.png" new file mode 100644 index 0000000..cb6fb95 Binary files /dev/null and "b/\352\271\200\354\227\260\354\232\261/[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/img/lecture21-3.png" differ diff --git "a/\352\271\200\354\227\260\354\232\261/[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/img/lecture21-4.png" "b/\352\271\200\354\227\260\354\232\261/[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/img/lecture21-4.png" new file mode 100644 index 0000000..582126d Binary files /dev/null and "b/\352\271\200\354\227\260\354\232\261/[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/img/lecture21-4.png" differ diff --git "a/\352\271\200\354\227\260\354\232\261/[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/\352\271\200\354\227\260\354\232\261/[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..de34094 --- /dev/null +++ "b/\352\271\200\354\227\260\354\232\261/[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,65 @@ +> # [Lecture 22](https://www.youtube.com/watch?v=fw8hvolebLw&list=PLcXyemr8ZeoREWGhhZi5FZs6cvymjIBVe&index=22) + +## 주요 내용 + +- DB 설계의 기본인 함수 종속(Functional Dependency) 학습 + +## Functional Dependency + +- 한 테이블에 있는 두 개의 attribute(s) 집합(set) 사이의 제약(a constraint) +- ‘tuple들의 X 값이 같다면 Y 값도 같다’는 의존 관계가 존재한다면 이를 FD라고 함 +- X → Y (기호 표시)
+ + +- 테이블의 행만 보고 FD를 판단 X +- 테이블의 스키마를 보고 의미적으로 FD를 파악해야 함 +- X → Y 라고 해서 Y → X 는 아님 ({empl_id} → {empl_name} O / 반대에서는 동명 이인 문제가 있을 수 있음) + +## {} → Y + +- Y는 언제나 하나의 값만을 가짐을 의미 +- 예시 + - 어디 사는지에 대한 정보를 저장하기 위해 만들어 놓은 컬럼이 존재한다 가정 + - 근데 사용하다 보니 인천인 사람만 정보가 모이기 인천에 대한 테이블로만 쓰이게 됨 + - 이 경우는 결국 {} → {city} +- 2NF에서도 나오니 기억하기 + +## trivial FD + +- X → Y 일 때, Y는 X의 부분 집합이면 X → Y는 trivial FD 라고 함 +- {a, b, c} → {c} : trivial FD +- {a, b, c} → {a, c} : trivial FD +- {a, b, c} → {a, b, c} : trivial FD + +## Non-trivial FD + +- X → Y 일 때, Y는 X의 부분 집합이 아니라면 X → Y 는 non-trivial FD 라고 함 +- {a, b, c} → {b, c, d} : non-trivial FD +- {a, b, c} → {d, e} : non-trivial FD & completely non-trivial FD + +## Partial FD + +- 부분 함수 종속 +- X → Y 일 때, X의 부분 집합(proper subset)으로 Y를 알 수 있으면 이 FD(X → Y)를 partial FD 라고 함 +- 즉, 자기 자신을 제외한 모든 부분 집합을 partial FD라고 함 (공집합도 부분 집합임을 잊지 말자) +- X = {a, b, c} + - {}, {a}, {b}, {c}, {a, b}, {a, c}, {b, c} : X의 proper subset + - {a, b, c} : X의 proper subset이 아님 +- {empl_id, empl_name} → {birth_date} + - {empl_id}는 유니크한 값으로 이 값만으로도 birth_date를 알 수 있기에 이 FD({empl_id, empl_name} → {birth_date})는 partial FD라고 할 수 있음 + +## Full FD + +- 완전 함수 종속 +- X → Y 일 때, X의 부분 집합(proper subset)으로 Y를 알 수 없으면 이 FD(X → Y)를 full FD 라고 함 + +## 이외 FD + +- Transitive FD + - 이행 함수 종속 +- Boyce-codd Normalization + - 결정자 함수 종속 +- Multi-Valued Dependency + - 다중값 종속 +- Adjoin Dependency + - 조인(결합) 종속 \ No newline at end of file diff --git "a/\352\271\200\354\227\260\354\232\261/[lecture22] db \354\240\225\352\267\234\355\231\224\354\235\230 \352\267\274\353\263\270 (functional dependency)/img/lecture-22-1.png" "b/\352\271\200\354\227\260\354\232\261/[lecture22] db \354\240\225\352\267\234\355\231\224\354\235\230 \352\267\274\353\263\270 (functional dependency)/img/lecture-22-1.png" new file mode 100644 index 0000000..d1fd44e Binary files /dev/null and "b/\352\271\200\354\227\260\354\232\261/[lecture22] db \354\240\225\352\267\234\355\231\224\354\235\230 \352\267\274\353\263\270 (functional dependency)/img/lecture-22-1.png" differ diff --git "a/\352\271\200\354\227\260\354\232\261/[lecture22] db \354\240\225\352\267\234\355\231\224\354\235\230 \352\267\274\353\263\270 (functional dependency)/img/lecture22-1.png" "b/\352\271\200\354\227\260\354\232\261/[lecture22] db \354\240\225\352\267\234\355\231\224\354\235\230 \352\267\274\353\263\270 (functional dependency)/img/lecture22-1.png" new file mode 100644 index 0000000..d1fd44e Binary files /dev/null and "b/\352\271\200\354\227\260\354\232\261/[lecture22] db \354\240\225\352\267\234\355\231\224\354\235\230 \352\267\274\353\263\270 (functional dependency)/img/lecture22-1.png" differ diff --git "a/\352\271\200\354\227\260\354\232\261/[lecture23] db \354\240\225\352\267\234\355\231\224 (1NF, 2NF)/README.md" "b/\352\271\200\354\227\260\354\232\261/[lecture23] db \354\240\225\352\267\234\355\231\224 (1NF, 2NF)/README.md" new file mode 100644 index 0000000..6b31eeb --- /dev/null +++ "b/\352\271\200\354\227\260\354\232\261/[lecture23] db \354\240\225\352\267\234\355\231\224 (1NF, 2NF)/README.md" @@ -0,0 +1,33 @@ +> # [Lecture 23](https://www.youtube.com/watch?v=EdkjkifH-m8&list=PLcXyemr8ZeoREWGhhZi5FZs6cvymjIBVe&index=23) + +## 주요 내용 + +- DB 정규화 +- 1NF +- 2NF + +## DB Normalization + +- DB 정규화 +- 데이터 중복과 insertion, deletion, modification anomaly를 최소화하기 위해 일련의 NF(Normal Forms)에 따라 Relation DB를 구성하는 과정 + +## Normal Forms + +- 정규화 되기 위해 준수해야 하는 몇 가지 규칙들이 있는데 이 각각의 규칙을 NF라고 부름 + +## DB 정규화 과정
+ + +- 1NF ~ BCNF + - FD와 Key만으로 정의되는 NF + - 3NF까지 도달하면 정규화 됐다고 말하기도 함 + - 보통 실무에서는 3NF 혹은 BCNF까지 진행 (많이 해도 4NF 정도까지만 진행) + +## 1NF + +- attribute의 value는 반드시 나눠질 수 없는 단일한 값이어야 한다 + +## 2NF + +- 모든 non-prime attribute는 모든 key에 fully functionally dependent 해야 한다 +- non-prime attribute : 어떠한 key에도 속하지 않는 attribute \ No newline at end of file diff --git "a/\352\271\200\354\227\260\354\232\261/[lecture23] db \354\240\225\352\267\234\355\231\224 (1NF, 2NF)/img/lecture-23-1.png" "b/\352\271\200\354\227\260\354\232\261/[lecture23] db \354\240\225\352\267\234\355\231\224 (1NF, 2NF)/img/lecture-23-1.png" new file mode 100644 index 0000000..29a8b79 Binary files /dev/null and "b/\352\271\200\354\227\260\354\232\261/[lecture23] db \354\240\225\352\267\234\355\231\224 (1NF, 2NF)/img/lecture-23-1.png" differ diff --git "a/\352\271\200\354\227\260\354\232\261/[lecture23] db \354\240\225\352\267\234\355\231\224 (1NF, 2NF)/img/lecture23-1.png" "b/\352\271\200\354\227\260\354\232\261/[lecture23] db \354\240\225\352\267\234\355\231\224 (1NF, 2NF)/img/lecture23-1.png" new file mode 100644 index 0000000..29a8b79 Binary files /dev/null and "b/\352\271\200\354\227\260\354\232\261/[lecture23] db \354\240\225\352\267\234\355\231\224 (1NF, 2NF)/img/lecture23-1.png" differ diff --git "a/\352\271\200\354\227\260\354\232\261/[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/\352\271\200\354\227\260\354\232\261/[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..d729fba --- /dev/null +++ "b/\352\271\200\354\227\260\354\232\261/[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,31 @@ +> # [Lecture 24](https://www.youtube.com/watch?v=5QhkZkrqFL4&list=PLcXyemr8ZeoREWGhhZi5FZs6cvymjIBVe&index=24) + +## 주요 내용 + +- DB 정규화 +- 3NF +- BCNF + +## 3NF + +- 모든 non-prime attribute는 어떤 key에도 transitively dependent 하면 안 된다 +- non-prime attribute와 non-prime attribute 사이에는 FD가 있으면 안 된다 + +## BCNF + +- 모든 유효한 non-trivial FD X → Y 는 X가 super key여야 한다 + +## 2NF 참고 사항 + +- 2NF는 key가 composite key(두 개 이상의 attribute로 이루어진 키)가 아니라면 2NF는 자동적으로 만족한다?? + - 2NF : 모든 non-prime attribute는 모든 key에 fully FD 해야 한다 + - 2NF : 모든 non-prime attribute는 어떤 key에도 partially FD 하면 안 된다 +- 항상 그런 것은 아님!! + +## Denormalization + +- 역 정규화 +- 테이블을 너무 쪼개게 되면 여러 테이블을 조인을 해야하는 성능 이슈가 발생 +- 테이블을 너무 쪼개게 되면 관리가 힘듬 +- 그래서 전략적으로 너무 쪼개지 않겠다 라는 의미 +- DB를 설계할 때 과도한 조인과 중복 데이터 최소화 사이에서 적정 수준을 잘 선택할 필요가 있음 \ No newline at end of file