2022년 04월 15일 TIL
✅ 한 것
공부
- 백준 알고리즘 문제 1개
- 1일 1커밋 & 푸쉬
- TIL 작성
운동
- X
❓ 오늘의 질문, 배운 것
SQL 스크립트란?
- 여러 쿼리문이 모여있는 것을 스크립트(Script)라고 한다.
- SQL 내용을 지닌 파일을 의미
FK(Foreign Key)없이 구축하는 관계형 데이터베이스 시스템
- 참고한 자료 => 링크
- 성능이 느려진다는 이유
과거 Oracle 8i 버전까지는 Foregin Key 관련한 테이블 락(Lock) 경합을 회피하기 위해 Foregin key열에 인덱스를 만들어 주어야 했었다.
하지만 Oracle 9i 버전부터는 이 문제가 해결되어 Foreign Key 열에 굳이 인덱스를 만들어 주지 않아도 된다.
(물론 성능을 위해서는 인덱스가 필요하며, 사실 Foreign Key 열들은 대부분 인덱싱 대상이기도 하다.)
OLTP 시스템에서 Foreign Key는 DML 작업간 Validation 검사부하의 성능오버헤드가 있지만 무시할만하다.
오히려 어떤 쿼리들에서는 Foreign Key 정보가 옵티마이저에게 보다 나은 실행계획을 만들도록 도움이 되기도 한다.
대량데이터를 로딩할 때 Foreign Key가 있으면 Validation 검사 부하가 있으므로 성능이 느려진다.
이것은 로딩 전에 Foreign Key를 disable 시켰다가 로딩 후 다시 enable 시키면 되겠다.
그러나, 성능이 매우 중요한 증권거래시스템 같은 경우엔 Foreign Key를 달지 않는게 더 나을 것이다. - 기존 데이터들이 Referential Integrity 정합성에 맞지 않아서 Foreign Key를 달고 싶어도 달 수 없다는 이유
이 경우 Foreign Key를 달 때(또는 Alter 명령으로 Enable 시킬 때) Enable Novalidate 옵션으로 생성해 주면 해결된다. 디폴트는 Enable Validate 인데 기존 데이터들에 대해 Validation 검사수행 후 성공하면 Enable 시킨다는 뜻이다.
반면에 Enable Novalidate는 기존 데이터들에 대한 Validation 검사를 수행하지 않고 Foreign Key를 Enable 시키므로 이 문제를 회피할 수 있다.
대량의 데이터 로딩 시 Foreign Key 정합성 검사시간을 생략하고자 할 때에도 사용하면 좋은 옵션이다.
로딩 전 Disable 시키고 로딩 후 이 옵션으로 Enable 시키는 것이다. - 개발할 때 Foreign Key 가 있으면 불편하다는 이유도 있다.
개발할 때 Foreign Key 때문에 불편하다는 이유는 이해할만 하다. 하지만 Foreign Key가 매우 중요한 RDBMS 시스템에서 이정도의 불편은 감수해야 하지 않을까 .어쨋든, Foreign Key 때문에 불편해지는 경우는 두가지 정도 같다.
첫째, 테스트 데이터 생성 시 부모테이블에 먼저 부모 Row를 생성하고 나중에 자식테이블에 자식 Row를 생성해야 하는데, 이게 번거로울 수 있을 것이다. 부모 Row 없이 자식테이블에만 테스트 Row를 생성하고 테스트하면 편리하기 때문이다. 이 문제는 개발 기간 중엔 Foreign Key를 Disable 시켜 놓으면 해결될 것이다.
둘째, 트랜잭션 안에서 부모테이블과 자식테이블의 관계에 따라 DML 작업의 순서가 필요해지기 때문이다.
예를 들어 Insert 작업이라면 부모 Row 먼저 자식 Row 나중의 순서로 작업해야 하고 Delete 라면 자식 Row 먼저
부모 Row 나중의 순서로 작업해야 한다. Foreign Key가 없다면 이런 순서에 얽매이지 않고 개발할 수 있을 것이다.
여기에도 해결책은 있다. Foreign Key 를 만들 때 Deferred 옵션으로 만들면 된다.
Deferred의 의미는 Validation 검사를 트랜잭션 단위로 한다는 뜻이다. 쉽게 말해 Commit 할 때 적합성 검사를 수행한다는 뜻이다. 디폴트는 Not Deferred이다. Not Deferred의 의미는 문장단위로 검사한다는 뜻이다.
즉 매 문자(insert, Update, Delete) 마다 검사하기 때문에 순서가 맞지 않으면 오류가 발생되는 것이다.
반면에 Deferred는 Commit 할 때 검사를 수행하므로 문장들의 순서는 상관없는 것이다.
Foreign Key를 Deferred로 만들어서 Disable 시켜놓은 후 개발하고 개발이 끝나고 테스트하기 전에 Enable 시키면
개발단계에서의 불편들을 해결할 수 있을 것이다.
물론 최선은, 다소 불편하더라도 Foreign Key를 디폴트(Not Deferred)로 만들어서 Enable 시켜놓은 상태에서 코딩하는게 좋다. 이렇게 하면 무엇보다 부모 자식테이블 간에 발생하는 Deadlock (ORA-60 에러)을 예방 할 수 있기 때문이다. 복수 테이블 트랜잭선에서 발생하는 Deadlock은 대부분 테이블들의 DML 작업 순서가 서로 다른 두 트랜잭션 사이에서 발생하기 때문이다. 일단 오픈 후 Deadlock이 발생되면 해결하는게 만만치 않다.
SQL에서 JOIN과 UNION의 차이는?
- UNION
- UNION은 SQL 쿼리문을 이용해 여러개의 테이블의 결과를 결합할 때 사용합니다.
- 새로운 열에 레코드들을 결합한다.
- JOIN
- JOIN은 SQL 쿼리문을 이용해 하나 이상의 테이블에서 레코드를 가져올 때 사용한다.
- 레코드들을 새로운 컬럼으로 결합한다.
📣 피드백
하루 반성 및 칭찬
- 궁금한 내용 혹은 단어가 있으면 블로그에 정리
- 궁금한게 생길 때 마다 블로그에 질문으로 정리 후 나중에 서칭(정리)
- 당연하다고 얘기하는 것에서 똑같이 수긍을 하지 말고 의문을 가져보기
- 그 의문을 바탕으로 블로그에 글로 작성
- 그 의문과 연관있는 개념들을 공부하면서 내것으로 만들기
- 계속 생각하는 개발자가 될 수 있도록 목표 설정
- 프로그래머는 자신에게 주어지는 문제를 고민하고 해결할 줄 알아야 한다는 것을 알게 되었습니다.
- 현업분과 프로젝트를 하면서 같은 문제를 받아도 그분들은 고민하고 결국 해결하는 모습을 봤습니다.
코딩 실력도 당연히 차이가 나지만 이 부분이 상당한 차이를 보이는 것 같습니다. - 제공되는 자료가 적더라도 문제의 요점을 파악하고 결국에 해결하는 모습
- 현업분과 프로젝트를 하면서 같은 문제를 받아도 그분들은 고민하고 결국 해결하는 모습을 봤습니다.
반응형