diff --git "a/song/28\352\260\225~36\352\260\225 \354\240\225\353\246\254.md" "b/song/28\352\260\225~36\352\260\225 \354\240\225\353\246\254.md" new file mode 100644 index 0000000..c61b846 --- /dev/null +++ "b/song/28\352\260\225~36\352\260\225 \354\240\225\353\246\254.md" @@ -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 +``` + + + + + + +