diff --git a/database/A-07.md b/database/A-07.md new file mode 100644 index 0000000..98ed501 --- /dev/null +++ b/database/A-07.md @@ -0,0 +1,42 @@ + +## 1. 정규화가 무엇인가요? + +관계형 데이터베이스 설계에서 중복을 최소화하여 무결성을 유지하도록 하는 것입니다. + +### 정규화를 하지 않을 경우, 발생할 수 있는 이상현상에 대해 설명해 주세요. + +- 삽입 이상(Insertion Anomaly) : 새로운 데이터를 삽입하기 위해 불필요한 데이터도 함께 삽입해야 하는 상황입니다. +- 삭제 이상(Deletion Anomaly) : 하나의 데이터를 삭제할 때 관련된 데이터도 함께 삭제되어 정보 손실이 발생하는 상황입니다. +- 수정 이상(Update Anomaly) : 데이터의 중복으로 인해 한 데이터를 여러 곳에서 수정해야 하며, 일부만 수정될 경우 데이터의 불일치(일관성 문제)가 발생할 수 있는 상황입니다. + +### 각 정규화에 대해, 그 정규화가 진행되기 전/후의 테이블의 변화에 대해 설명해 주세요. + +- 1정규형 전/후 + - 전: 테이블에는 중복된 레코드가 존재할 수 있고, 하나의 필드 내에 여러 값이 저장될 수 있습니다(비원자적 값). 예를 들어, 하나의 레코드에서 '취미' 필드에 ["독서", "영화감상"] 같이 여러 취미를 배열이나 문자열로 저장할 수 있습니다. + - 후: 각 필드의 값은 원자적이 되어야 합니다. 즉, 하나의 필드에는 하나의 값만을 가집니다. '취미' 정보를 저장하기 위해서는 취미마다 별도의 레코드를 추가해야 하며, 이는 테이블의 구조를 변경하여 각 취미가 별도의 레코드로 분리됩니다. + +- 2정규형 전/후 + - 전: non-key 속성들이 PK 와 연관되어 있다. + - 후 : 각 non-key 속성은 PK 전체에 의존해야 한다. + +- 3정규형 전/후 + - 전 : non-key 속성이 다른 non-key 속성에 의존한다. + - 후 : 모든 non-key 속성은 오로지 key에만 의존한다. + + +### 정규화가 무조건 좋은가요? 그렇지 않다면, 어떤 상황에서 역정규화를 하는게 좋은지 설명해 주세요. + +DB 정규화는 테이블을 많이 나누게 하고, 테이블이 많아지면 Join 연산이 많아집니다. Join 은 성능에 큰 악영향을 미칩니다. + +또한 정규화는 쓰기에 최적화되어 있습니다. 하지만 읽기가 훨씬 많은 비중을 차지합니다. + +따라서 아래와 같은 상황에서 역정규화를 하는 것이 좋습니다. +- **조회 성능 향상** : 데이터베이스에서 조회(쿼리) 작업이 매우 빈번하고, 데이터의 추가, 삭제, 수정(갱신) 작업은 상대적으로 드문 경우입니다. 자주 함께 조회되는 데이터를 하나의 테이블로 합치거나, 계산된 값을 저장하는 추가 필드(예: 집계 정보)를 도입하여 쿼리의 복잡성을 줄이고 조회 성능을 향상시킬 수 있습니다. + +- **갱신 작업 최소화** : 데이터 갱신 작업이 비교적 적고, 특히 시스템의 성능이 중요한 역할을 하는 애플리케이션에서, 정규화된 구조에서는 하나의 데이터를 업데이트하기 위해 여러 테이블을 수정해야 할 수 있습니다. 이때 역정규화를 적용하여 중복 데이터를 저장함으로써 갱신 작업을 줄이고, 이로 인한 시스템의 성능을 향상시킬 수 있습니다. + + +## 참고 +- [정규화(Normalization) 쉽게 이해하기](https://mangkyu.tistory.com/110) +- [[데이터베이스] 정규화의 의미 - 1NF, 2NF, 3NF, 4NF, 5NF](https://ddoddii.github.io/post/cs/database/normalization/) +- [DB 정규화를 하지 않는 이유](https://coolspeed.wordpress.com/2017/04/15/why_not_db_normalization/) \ No newline at end of file diff --git a/database/A-08.md b/database/A-08.md new file mode 100644 index 0000000..b9683e4 --- /dev/null +++ b/database/A-08.md @@ -0,0 +1,11 @@ +## 8. View가 무엇이고, 언제 사용할 수 있나요? + +View 는 사용자에게 접근이 허용된 자료만을 제한적으로 보여주기 위해 하나 이상의 기본 테이블에서 유도된, 이름을 가지는 **가상 테이블**입니다. 뷰는 저장장치 내에 물리적으로 존재하지는 않습니다. 뷰를 통해서만 데이터에 접근하게 하면 뷰에 나타나지 않는 데이터를 보호할 수 있습니다. 뷰를 사용하면 기본 테이블 구조가 변경되어도 응용 프로그램은 계속 동일한 뷰를 사용할 수 있어서, 데이터 독립성을 제공합니다. + +### 그렇다면, View의 값을 수정해도 실제 테이블에는 반영되지 않나요? + +View 의 종류에 따라 다릅니다. Updatable View 에서는 데이터를 수정,삽입,삭제하면 기본 테이블에도 반영됩니다. Read-Only View 에서는 데이터를 수정할 수 없습니다. + + +## 참고 +- [[DB기초] 뷰(View)란 무엇인가? + 간단한 예제](https://coding-factory.tistory.com/224) diff --git a/database/A-09.md b/database/A-09.md new file mode 100644 index 0000000..a665059 --- /dev/null +++ b/database/A-09.md @@ -0,0 +1,115 @@ +## 9. DB Join이 무엇인지 설명하고, 각각의 종류에 대해 설명해 주세요. + +DB Join 은 두 개 이상의 테이블에서 관련된 데이터를 결합하여 의미 있는 정보를 얻기 위해 사용되는 연산입니다. 조인은 테이블 간의 공통 열(일반적으로 기본 키와 외래 키)을 기반으로 수행됩니다. + +Join 의 종류는 다음과 같습니다. +- Inner Join + - 두 테이블에서 조인 조건을 만족하는 행만 반환합니다. +- LEFT OUTER JOIN + - 왼쪽 테이블의 모든 행을 반환하고, 오른쪽 테이블에서 조인 조건을 만족하는 행을 함께 반환합니다. +- RIGHT OUTER JOIN + - 오른쪽 테이블의 모든 행을 반환하고, 왼쪽 테이블에서 조인 조건을 만족하는 행을 함께 반환합니다. +- FULL OUTER JOIN + - 왼쪽 및 오른쪽 테이블의 모든 행을 반환합니다. +- CROSS JOIN + - 테이블의 모든 행을 결합하여 가능한 모든 조합을 반환합니다. +- SELF JOIN + - 하나의 테이블 내에서 자기 자신과 조인하는 것을 의미합니다. + +### 사실, JOIN은 상당한 시간이 걸릴 수 있기에 내부적으로 다양한 구현 방식을 사용하고 있습니다. 그 예시에 대해 설명해 주세요. + +주요한 네 가지 조인 알고리즘으로는 **Nested Loop Join, Hash Join, 그리고 Sort Merge Join, Index Join**이 있습니다. + +1. Nested Loop Join: + +- Nested Loop Join은 가장 간단한 조인 알고리즘 중 하나로, 바깥쪽 루프(Outer Loop)와 안쪽 루프(Inner Loop)로 두 테이블을 순차적으로 순회하면서 조인합니다. +- 바깥쪽 루프는 기준 테이블을 선택하고, 안쪽 루프는 조인 조건에 해당하는 테이블을 선택합니다. +- 조인 조건에 해당하는 데이터를 찾으면, 바깥쪽 루프의 다음 행으로 넘어가며, 안쪽 루프는 처음부터 다시 시작합니다 +- 데이터 양이 적을 때는 성능이 좋지만, 데이터 양이 많을 경우 비효율적일 수 있습니다. + + +2. Hash Join: + +- 해시 함수를 사용하여 조인 키를 기반으로 테이블을 해시 버킷에 분할합니다. +- 두 테이블의 해시 버킷을 비교하여 조인 조건을 만족하는 행을 찾습니다. +- 대용량 데이터 세트에 적합하며, 일반적으로 Nested Loop Join보다 빠릅니다. + + +3. Sort Merge Join: + +- 조인 키를 기준으로 두 테이블을 정렬합니다. +- 정렬된 테이블을 병합하면서 조인 조건을 만족하는 행을 찾습니다. +- 데이터가 이미 정렬되어 있거나, 조인 결과를 정렬해야 하는 경우에 효율적입니다. + +4. Index Join (인덱스 조인): + +- 조인 키에 대한 인덱스를 사용하여 조인을 수행합니다. +- 한 테이블에서 인덱스를 사용하여 조인 키를 빠르게 찾고, 다른 테이블에서 해당 키와 일치하는 행을 검색합니다. +- 인덱스가 있는 열을 조인할 때 효율적입니다. + +### 그렇다면 입력한 쿼리에서 어떤 구현 방식을 사용하는지는 어떻게 알 수 있나요? + +EXPLAIN (또는 EXPLAIN PLAN) 명령을 사용할 수 있습니다. 대부분의 DBMS는 EXPLAIN 명령을 제공하여 쿼리 실행 계획을 확인할 수 있습니다. 쿼리 앞에 EXPLAIN을 붙여 실행하면, 쿼리 옵티마이저가 선택한 실행 계획을 볼 수 있습니다. 실행 계획에는 사용된 조인 알고리즘, 조인 순서, 인덱스 사용 여부 등의 정보가 포함됩니다. + +### 앞 질문들을 통해 인덱스의 중요성을 알 수 있었는데, 그렇다면 JOIN의 성능도 인덱스의 유무의 영향을 받나요? + +네, 조인의 성능은 인덱스의 유무에 큰 영향을 받습니다. 적절한 인덱스를 사용하면 조인 연산의 속도를 크게 향상시킬 수 있습니다. 인덱스가 조인 성능에 미치는 영향은 다음과 같습니다: + +1. 인덱스를 사용한 조인 (Index Join): +- 조인 조건에 사용되는 열에 인덱스가 있는 경우, DBMS는 인덱스를 사용하여 빠르게 일치하는 행을 찾을 수 있습니다. +- 인덱스를 사용하면 테이블 전체를 스캔하지 않고도 필요한 데이터에 접근할 수 있어 조인 성능이 향상됩니다. + +2. 인덱스 없이 수행되는 조인 (Non-Index Join): +- 조인 조건에 사용되는 열에 인덱스가 없는 경우, DBMS는 테이블 전체를 스캔해야 합니다. +- 이는 조인 연산의 속도를 크게 저하시키며, 특히 대용량 테이블에서는 성능 문제가 두드러집니다. + +3. 인덱스 선택성 (Index Selectivity): +- 인덱스의 선택성이 높을수록 조인 성능이 향상됩니다. +- 선택성이 높은 인덱스는 중복 값이 적고 고유한 값이 많은 인덱스를 의미합니다. +- 선택성이 높은 인덱스를 사용하면 조인 조건을 만족하는 행을 빠르게 찾을 수 있습니다. + +4. 다중 열 인덱스 (Multi-Column Index): +- 조인 조건에 여러 열이 사용되는 경우, 다중 열 인덱스를 생성하면 조인 성능을 향상시킬 수 있습니다. +- 다중 열 인덱스는 조인 조건에 사용되는 열의 순서와 일치하도록 생성되어야 합니다. + +5. 클러스터형 인덱스 (Clustered Index): +- 클러스터형 인덱스는 테이블 데이터를 물리적으로 정렬하여 저장합니다. +- 조인 조건에 클러스터형 인덱스를 사용하면, 인덱스 스캔과 데이터 검색이 함께 이루어지므로 성능이 향상됩니다. + +따라서, 조인 성능을 최적화하려면 적절한 인덱스를 생성하고 사용해야 합니다. 조인 조건에 사용되는 열에 선택성이 높은 인덱스를 생성하고, 필요한 경우 다중 열 인덱스를 사용하는 것이 좋습니다. 인덱스를 효과적으로 활용하면 조인 연산의 속도를 크게 향상시킬 수 있습니다. + + +### 3중 조인 부터는 동작 방식이 약간 바뀝니다. 어떻게 동작하는지, 그리고 그 방식이 성능에 어떠한 영향을 주는지 설명해 주세요. + +3개 이상의 테이블을 조인할 때, 조인 순서와 실행 계획이 성능에 큰 영향을 미칩니다. DBMS의 쿼리 옵티마이저는 통계 정보와 규칙 기반 휴리스틱을 사용하여 최적의 조인 순서를 결정합니다. 다중 테이블 조인의 동작 방식과 성능에 미치는 영향은 다음과 같습니다: + +1. 조인 순서 (Join Order): +- 쿼리 옵티마이저는 다양한 조인 순서를 평가하여 가장 효율적인 실행 계획을 선택합니다. +- 조인 순서는 테이블의 크기, 조인 조건의 선택성, 인덱스 사용 가능성 등을 고려하여 결정됩니다. +- 최적의 조인 순서를 선택하면 불필요한 중간 결과를 최소화하고 조인 성능을 향상시킬 수 있습니다. + +2. 중첩 루프 조인 (Nested Loop Join): +- 다중 테이블 조인에서 중첩 루프 조인이 사용되는 경우, 조인 순서에 따라 성능이 크게 달라질 수 있습니다. +- 작은 테이블을 먼저 조인하고, 큰 테이블을 나중에 조인하는 것이 일반적으로 더 효율적입니다. +- 중첩 루프 조인은 작은 테이블에 인덱스가 있을 때 효과적입니다. + +3. 해시 조인 (Hash Join): +- 다중 테이블 조인에서 해시 조인이 사용되는 경우, 큰 테이블을 먼저 해시 테이블로 빌드하고 작은 테이블을 프로브하는 것이 일반적입니다. +- 해시 조인은 큰 테이블과 작은 테이블 간의 조인에 효과적이며, 인덱스가 없는 경우에도 높은 성능을 제공합니다. + +4. 조인 필터 조건 (Join Filter Condition): +- 다중 테이블 조인에서 추가적인 필터 조건을 사용하면 중간 결과 집합의 크기를 줄일 수 있습니다. +- 필터 조건을 가능한 한 빨리 적용하여 불필요한 데이터 처리를 최소화할 수 있습니다. + +5. 조인 방향 (Join Direction): +- 조인 방향은 어떤 테이블을 먼저 액세스하고 어떤 테이블을 나중에 액세스할지 결정합니다. +- 일반적으로 작은 테이블에서 큰 테이블 방향으로 조인하는 것이 효율적입니다. +- 조인 방향은 인덱스 사용 가능성과 조인 조건의 선택성에 따라 결정됩니다. + + +## 참고 +- [DB Join 정리(INNER/LEFT/RIGHT/OUTER)](https://pearlluck.tistory.com/46) +- [관계형 데이터베이스(RDBMS) 조인 알고리즘 종류: Nested Loop Join, Hash Join, Sort Merge Join](https://bestwizard.tistory.com/583) +- [[SQL] 성능 관점에서 보는 결합(Join)](https://schatz37.tistory.com/2) +- [[MYSQL] 📚 테이블 조인(JOIN) - 그림으로 알기 쉽게 정리](https://inpa.tistory.com/entry/MYSQL-%F0%9F%93%9A-JOIN-%EC%A1%B0%EC%9D%B8-%EA%B7%B8%EB%A6%BC%EC%9C%BC%EB%A1%9C-%EC%95%8C%EA%B8%B0%EC%89%BD%EA%B2%8C-%EC%A0%95%EB%A6%AC) +- [[DB] 데이터베이스 NESTED LOOPS JOIN (중첩 루프 조인)에 대하여](https://coding-factory.tistory.com/756) \ No newline at end of file