-
Notifications
You must be signed in to change notification settings - Fork 2
lecture19~24 #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
simhani1
wants to merge
7
commits into
main
Choose a base branch
from
lecture19-24/sjh
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
lecture19~24 #6
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| # lecture19 - mvcc (1부) | ||
|
|
||
| ## MVCC (Multiversion concurrency control) | ||
|
|
||
| MVCC는 커밋된 데이터만 읽는다. | ||
|
|
||
| ### committed read | ||
|
|
||
| 이 isolation 레벨로 데이터를 읽으면 read하는 시간을 기준으로 그전에 커밋된 데이터를 읽는다. | ||
|
|
||
|  | ||
|
|
||
| 따라서 이 상태에서는 `tx2` 가 write한 50이 조회된다. | ||
|
|
||
| ### repeatable read | ||
|
|
||
| tx 시작 시간 기준으로 그전에 커밋된 데이터를 읽는다. | ||
|
|
||
|  | ||
|
|
||
| 따라서 이 상태에서는 10이 조회된다. | ||
|
|
||
| > [!NOTE] | ||
| > | ||
| > **어떤 isolation 레벨로 데이터를 읽는지는 DBMS마다 다르다.** | ||
|
|
||
| ### serializable | ||
|
|
||
| SSI 기법이 적용된 MVCC로 동작한다. | ||
|
|
||
| ### read uncommitted | ||
|
|
||
| MVCC는 커밋된 데이터를 읽기 때문에 이 레벨에서는 MVCC가 적용되지 않는다. | ||
|
|
||
| ## MVCC 특징 | ||
|
|
||
| - 데이터를 읽을 때 `특정 시점 기준` 으로 가장 최근에 `커밋` 된 데이터를 읽는다. | ||
| - _이때 특정 시점은 isolation 레벨에 따라 다르다._ | ||
| - 데이터 변화 이력을 관리한다. | ||
| - 따라서 추가적인 저장 공간을 사용하게 된다. | ||
| - read, write는 서로 block하지 않는다. | ||
| - 동시에 처리할 수 있는 트랜잭션이 늘어나 성능이 더 좋아질 수 있다. | ||
|
|
||
| > [!NOTE] | ||
| > | ||
| > 특정 시점을 기준으로 커밋된 데이터를 읽는 것을 MySQL에서 `consistent read` 라고 부른다. | ||
|
|
||
| ## MVCC에서 발생 가능한 문제 | ||
|
|
||
| ### read committed 레벨을 사용하는 경우 | ||
|
|
||
| > 현재 예제는 PostgreSQL을 기반으로 설명한다. | ||
|
|
||
|  | ||
|
|
||
| `tx1` 의 쓰기 작업의 결과가 사라지는 문제가 있다. | ||
|
|
||
| 왜냐하면 `tx1` 이 x값애 쓰기 작업을 할때 락을 획득한다. | ||
| 또한 `tx2` 는 커밋된 시점의 x값을 읽으므로 50을 읽는다. | ||
| 30을 입금하려 하지만 `tx1` 이 쓰기 락을 가지고 있으므로 대기하게 되고 결과적으로 `lost update` 문제가 발생한다. | ||
|
|
||
| ### 해결법 | ||
|
|
||
| tx2 의 isolation 레벨을 repeatable read 로 바꾸면 해결된다. | ||
|
|
||
| PostgreSQL 는 `repeatable read` 레벨을 사용하면 같은 데이터에 먼저 update한 tx가 커밋되었다면 이후 tx는 롤백하는 기능이 있다. | ||
|
|
||
|  | ||
|
|
||
| 이런 특성을 `fist-updater-win` 라고도 한다. | ||
|
|
||
| ### 더 고민해보자 | ||
|
|
||
| 일단 트랜잭션마다 서로 다른 isolation 레벨을 가져갈 수 있다. | ||
|
|
||
| 그렇다면 tx1 이 read committed 레벨을 사용해도 정말 괜찮은지 보자. | ||
|
|
||
|  | ||
|
|
||
| 이처럼 트랜잭션의 동작 순서가 바뀐다면 lost update 문제가 발생하게 된다. | ||
|
|
||
| **즉 서로 연관되는 트랜잭션의 isoloation 레벨을 동시에 고려해야 문제를 해결할 수 있다는 것이다.** | ||
|
|
||
|  | ||
|
|
||
| `tx1` 의 isolation 레벨을 바꾸더라도 `tx1` 은 롤백되는 상황이 발생할 수 있고 여전히 `lost update` 문제가 발생한다. | ||
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| # lecture20 - mvcc (2부) | ||
|
|
||
| ## MySQL에서 lost update 해결 | ||
|
|
||
| ### locking read | ||
|
|
||
|  | ||
|
|
||
| MySQL에서는 select for update 구문을 사용할 수 있다. | ||
| 단, `tx1` , `tx2` 모두 `locking read` 를 사용해야만 한다. | ||
| `tx1` 이 `locking read` 를 사용하지 db에 커밋되어 있는 값을 읽게 된다. | ||
|
|
||
|  | ||
|
|
||
| 또한 MySQL에서 locking read는 가장 최근에 커밋된 데이터를 읽는다. | ||
| 따라서 repeatable read 레벨이더라도 트랜잭션의 시작 시점의 값을 읽지 않고 가장 최근에 커밋된 데이터를 읽도록 동작한다. | ||
|
|
||
|  | ||
|
|
||
| ### wrtie skew 문제 | ||
|
|
||
| 정상적으로 동작하면 결과는 다음과 같다. | ||
|
|
||
|  | ||
|
|
||
| 그러나 아래처럼 locking read를 사용하지 않으면 문제가 생긴다. | ||
|
|
||
|  | ||
|
|
||
|  | ||
|
|
||
| #### MySQL에서의 해결 - select for update | ||
|
|
||
|  | ||
|
|
||
| MySQL에서 locking read를 사용하면 repeatable read 격리 수준이더라도 가장 최근에 커밋된 데이터를 읽게 되므로 문제가 해결된다. | ||
|
|
||
| #### PostgreSQL | ||
|
|
||
| 그러나 PostgreSQL에서 repeatable read 격리 수준에서는 동작하는 방식이 달라 먼저 update한 tx가 커밋되면 이후 tx는 롤백된다. | ||
|
|
||
|  | ||
|
|
||
| 이번엔 select for share 로 읽기 잠금을 획득하더라도 동일한 이유로 롤백된다. | ||
|
|
||
| ### 정리 | ||
|
|
||
| DBMS의 종류에 따라 동작 방식이 다르므로 상황에 알맞은 방법을 적용해야 한다. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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을 사용했을 때 주의 필요 | ||
| - 불필요한 저장공간 낭비 |
73 changes: 73 additions & 0 deletions
73
심종한/[lecture22] db 정규화의 근본 (functional dependency)/README.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -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 | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| - { 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의 값은 반드시 나눠질 수 없는 단일한 값이어야 한다.** | ||||||
|
|
||||||
|  | ||||||
|
|
||||||
| 그러나 중복 데이터가 있고 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` 를 분리해야 한다. | ||||||
|
|
||||||
|  | ||||||
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,33 @@ | ||||||
| # lecture24 - db 정규화 (3NF, BCNF, 역정규화) | ||||||
|
|
||||||
|  | ||||||
|
|
||||||
| `{ 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 하면 안된다. | ||||||
|
|
||||||
|  | ||||||
|
|
||||||
| **3NF까지 되면 `정규화 됐다` 라고 말할 수 있다.** | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| ## BCNF | ||||||
|
|
||||||
| 모든 유효한 non-trivial FD X -> Y는 X가 super key여야 한다. | ||||||
|
|
||||||
|  | ||||||
|
|
||||||
|  | ||||||
|
|
||||||
| 더이상 bank_name이 중복되어 저장되는 일이 없다. | ||||||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.