Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 169 additions & 0 deletions song/28강~36강 정리.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
# 28강 인덱스 구조

인덱스(색인)는 WHERE로 조건이 지정된 SELECT 명령의 처리 속도 향상을 위해 사용한다.
하지만 인덱스 만으로는 의미가 없다. DB에서 테이블을 삭제하면 연결된 인덱스도 함께 삭제된다.

이진 탐색이나 해쉬를 사용한 검색 알고리즘들이 유명하다.
이진 탐색을 위해서는 데이터가 정렬 되어있어야 하는데 이 점을 보완하기 위해 이진 트리를 사용한다.
이진 트리는 중복한 값을 가지는 노드가 없기 때문에 이진 트리로 인덱스를 작성할 때는 기본키를 주로 사용한다.

# 29강 인덱스 작성과 삭제

```mysql
CREATE INDEX 인덱스 명 ON 테이블 명 (열명1, 열병2, ...)
DROP INDEX 인덱스 명 ON 테이블 명
```
ORACLE이나 DB2에서 인덱스는 스키마 객체가 된다.
하지만, SQL Server나 MySQL에서의 인덱스는 테이블 내 객체가 된다.

인덱스를 지정할 때는 어느 테이블의 어느 열에 관한 것인지 지정해 주어야 한다.

인덱스를 사용하면 WHERE 구를 사용한 SELECT 명령의 처리 속도가 향상한다.
하지만, 모든 SELECT 명령에 적용되는 인덱스는 존재할 수 없다.
또한 인덱스를 사용하게 되면 INSERT 구의 처리 속도가 조금 떨어진다.

### EXPLAIN 명령

EXPLAIN 명령을 사용하면 실제로 인덱스를 사용해 검사하는지를 확인할 수 있다.

```mysql
EXPLAIN SQL명령
```
SQL 명령을 실제로 실행하는 것은 아니지만 MySQL에서는 상황에 따라 실제로 실행하는 경우도 있다.
possible_key라는 곳에서 사용될 수 있는 인덱스가 표시되고, key는 사용된 인덱스가 표시된다.

# 30강 뷰 작성과 삭제

뷰는 테이블과 같은 부류의 데이터베이스 객체 중 하나다.
```mysql
CREATE VIEW 뷰명 AS SELECT 명령
DROP VIEW 뷰명
```

FROM 구에 기술된 서브쿼리에 이름을 붙이고 데이터베이스 객체화 해 쉽게 사용할 수 있게 한 것이 뷰이다.
SELECT 명령에 이름을 붙여 관리할 수 있도록 한 것

뷰는 실체가 존재하지 않는 가상 테이블이라고 불린다. 뷰는 테이블처럼 저장 공간을 가지지 않는다.
VIEW에서 열명을 지정하면 SELECT 문에서 가져온 열에 열명을 지정해 뷰를 만들 수 있다.

뷰는 저장공간을 소비하지 않지만 CPU 자원을 사용한다. -> 단점
뷰는 단순히 SELECT 명령을 저장해 두었다가 실행하는 역할만 한다.
데이터 양이 많거나 집계함수를 사용, 뷰를 중첩으로 사용할 때 처리속도가 많이 떨어진다.

머티리얼라이즈드 뷰(Materialized View)는 테이블처럼 저장장치에 저장해 사용한다.
-> 변경사항이 있을 때만 다시 긁어온다.
> 그럼 변경사항은 어떻게 알아오려나?
>
> 4가지 리프레시 로직에 따라 다르다.
> 1. ON COMMIT 리프레시: 이 경우, 머티리얼라이즈드 뷰는 트랜잭션이 커밋될 때마다 자동으로 새로 고쳐집니다. 이는 변경 내용을 실시간으로 반영할 때 사용됩니다.
> 2. ON DEMAND 리프레시: 이 경우, 머티리얼라이즈드 뷰는 수동으로 또는 일정한 스케줄에 따라 개발자 또는 관리자에 의해 명시적으로 새로 고쳐집니다.
> 3. ON COMMIT REFRESH WITH ROWID 옵션: 이 옵션은 ON COMMIT 리프레시와 유사하지만, ROWID를 기반으로 변경 내용을 추적하여 효율적으로 변경 사항을 감지합니다.
> 4. COMPLETE 리프레시: 이 경우, 전체 머티리얼라이즈드 뷰 데이터가 주기적으로 또는 수동으로 새로 고쳐집니다. 이는 데이터가 자주 변경되거나 트랜잭션 처리 성능에 큰 영향을 미치는 경우에 사용됩니다.
>
> 기본적으로 ON DEMAND 리프레시 방식을 따른다.


# 31강 집합 연산

집합 연산을 사용하면 복수의 테이블을 사용해 데이터를 사용할 수 있다.

### UNION - 합집합

```mysql
SELECT * FROM 테이블 명1
UNION
SELECT * FROM 테이블 명2;
```

두 테이블의 열 자료형이 같아야 쓸 수 있다.
테이블 명의 순서는 UNION 후 데이터 값에 영향을 주지 않는다.
하지만 ORDER BY를 사용하는 경우는 주의해야 한다.

### UNION ORDER BY

UNION 에서의 ORDER BY는 중간에 사용하면 안되고, 마지막에 붙여줘야 한다.
또한 두 테이블의 열 명이 일치하지 않으면 오류가 발생한다. 때문에 같은 별명으로 맞춰주어야 한다.
두 테이블에 동일한 행이 있다면 중복 제거된다. -> 중복 제거하기 싫으면 UNION ALL 사용


> 합치는 두 테이블의 칼럼 명이 다르다면 결과 칼럼 명은 어떻게 나올까?
>
> 첫번째 테이블의 칼럼 명을 따른다 -> gpt 왈

### 교집합과 차집합

교집합 : INTERSECT
차집합 : EXCEPT(Oracle은 MINUS)

# 32강 테이블 결합

join : 테이블끼리 열로 결합해 데이터를 가져오는 기술

교차결합(Cross Join)
```mysql
SELECT * FROM 테이블 명1, 테이블 명2
```

내부결합(Inner Join)
```mysql
SELECT * FROM 테이블 명1, 테이블 명2 WHERE 결합 조건
SELECT * FROM 테이블 명1 JOIN 테이블 명2 ON 결합 조건
```

자기 결합(Self Join)
```mysql
SELECT * FROM 테이블 명 S1 INNER JOIN 테이블 명 S2 ON S1.열명 = S2.열명;
```

외부 결합(Outer Join)
외부 결합은 한쪽에만 있는 데이터를 어떻게 처리할지를 고민한다.
```mysql
SELECT * FROM 테이블 명1 LEFT JOIN 테이블 명2 ON 결합 조건
-> 테이블 명1을 기준으로 데이터를 가져와 테이블 명2의 값이 NULL이어도 가져온다.
```

# 33강 관계형 모델

이 부분은 왜 설명이 되어있는거지? 그냥 명칭이 다르다?

# 34강 데이터베이스 설계

- 논리명과 물리명

물리명 : CREATE TABLE에 지정하는 이름\
논리명 : 테이블 설계상의 이름

데이터베이스 시스템을 사용할 때 데이터 정합성 체크는 DB에 맡기는 것이 좋다.
ex) 이 칼럼에는 1, 2, 3만 들어올 수 있어! or yes, no 둘중 하나만 받을거야

> 정합성 체크를 DB에 맡긴다고 해도 백엔드에서 확인하고 넘겨줘야 하는거 아닌가?
> 그냥 확실히 체크하라는 이야기겠지?

파일을 저장할 때 사용하는 자료형 : LOB(Large Object) -> 인덱스를 지정할 수 없다.

데이터베이스를 설계할 때 외부키 제약을 설정하면 데이터의 정합성이 엄격히 관리되어 번거로워진다는 이유로 사용하지 않는 시스템도 있다.

# 35강 정규화

테이블을 올바른 형태로 분리하는 작업

제1 정규형 : 테이블에는 하나의 셀에 하나의 값만 저장할 수 있다.-> 가로가 아닌 세로로 늘린다.
제2 정규형 : 데이터가 중복하는 부분을 찾아 테이블로 분리 -> 기본키에 중복이 있는지 조사
제3 정규형 : 중복하는 부분을 찾아 테이블로 분리 -> 기본키 이외의 부분의 중복을 조사

**정규화의 목적** : 하나의 데이터는 한 곳에 있어야 한다.

# 36강 트랜잭션

```mysql
START TRANSACTION
COMMIT
ROLLBACK
```