목차
View란 무엇인가요?
View란 하나 이상의 테이블로 만들어지는 가상 테이블 입니다.
View는 쿼리문의 결과를 나타냅니다.
여러 개의 테이블에서 정보를 규합하거나, 복잡한 쿼리문의 결과를 저장하여 사용자가 편하게 사용할 수 있게 합니다. 또한 테이블의 숨기고 싶은 컬럼은 숨기고 보여주고 싶은 컬럼만 보여줄 수 있어 보안이 증가합니다. 가상 테이블답게 물리적으로 저장되지 않습니다. 다만, 쿼리문을 저장하므로 논리적으로 저장이 됩니다.
하지만 View는 한 번 만들어진 정의를 변경할 수 없습니다. 뷰는 뷰로부터 만들수도 있는데 복잡한 뷰는 성능 저하를 일으킬 수 있습니다.
RDB와 NoSQL
RDB는 관계형 데이터베이스 입니다.
스키마에 따라 데이터를 저장하며 테이블끼리 관계를 맺을 수 있습니다.
테이블의 관계를 이용하여 Join, Group과 같은 하나의 테이블이 아닌 여러 테이블에서 정보를 취합하는 복잡한 쿼리문을 실행할 수 있습니다. 정형화된 데이터로 저장되어서 트랜잭션 ACID를 적용해 일관성을 보장합니다.
하지만, 입력 데이터를 스키마에 맞추어 저장하므로 지연 시간이 발생할 수 있습니다. 이는 대용량 데이터 처리에 적합하지 않으며 빠르게 변환하는 데이터에 적응하는데 한계가 있을 수 있습니다.
예시로는 MySQL, MariaDB, PostgreSQL 등이 있습니다.
NoSQL은 비관계형 데이터베이스 입니다.
NoSQL은 RDB의 단점을 극복하기 위해 나왔으며 느슨한 스키마에 따라 자유로운 형식으로 데이터를 저장할 수 있습니다. RDB는 스키마에 따라 저장하기에 데이터를 가공하는 시간이 필요하지만 NoSQL은 바로 데이터를 저장할 수 있습니다. 이에 대규모 데이터 처리에 적합합니다. 관계를 맺지 않기 때문에 독자적으로 작업을 처리할 수 있어 분산 처리에 용이합니다.
하지만 데이터 형식이 자유로워 느슨한 트랜잭션을 사용합니다. 이로 인해 일관성이 지켜지지 않을 수 있습니다. 최종적 일관성을 지원하여 결국에는 일관성이 지켜지나 실시간으로 이루어지지 않을 수 있습니다. 또한 관계를 맺지 않으므로 복잡한 쿼리문을 사용할 수 없습니다.
인덱스란 무엇인가요?
인덱스란 테이블의 검색 속도를 향상시키는 자료구조 입니다.
인덱스는 책의 목차같은 개념으로 인덱스를 사용하면 모든 레코드를 스캔하는 대신 인덱스만 탐색하므로 검색 속도가 올라갑니다.
대신, 데이터의 추가, 수정, 삭제 성능은 하락됩니다.
이유는 데이터가 변경될 때 마다 인덱스도 업데이트 해줘야 하기 때문입니다.
또한, 인덱스를 사용하기 위한 추가적인 공간이 필요합니다. (대략 10%)
즉, 읽기가 많고, 변경이 적은 데이터에 인덱스를 사용하는 것이 효과적입니다.
또한, WHERE, JOIN 연산 등이 자주 사용되는 컬럼에 인덱스를 생성하는 것이 좋습니다.
인덱스에 사용하는 자료구조는 뭔가요?
인덱스에서 B+Tree를 사용합니다. (B는 Balanced)
B+Tree는 균형 이진 트리로 리프 노드에만 데이터를 저장하고 그 외에 노드는 포인터를 저장합니다. 균형 이진 트리의 특징은 리프 노드까지의 트리의 깊이가 동일합니다. 즉 어떤 데이터를 검색해도 일정한 속도를 가집니다.
포인터만 저장하기에 메모리가 남아 더 많은 키를 담을 수 있습니다. 그 결과, 트리의 길이가 낮아져 검색 속도가 올라갑니다.
데이터를 저장한 리프노드는 링크드리스트로 연결되어 좀 더 빠른 선형 검색이 가능합니다.
B+Tree는 B-Tree에서 발전된 형태입니다.
B+Tree와 B-Tree의 차이는 데이터 저장 위치입니다. B+Tree는 리프 노드에만 저장하지만 B-Tree는 모든 노드에 데이터를 저장합니다. 그 결과 풀스캔이나 순차검색을 할 때, B+Tree는 링크드리스트로 연결된 리프 노드만 탐색해서 속도가 빠르지 B-Tree는 모든 노드를 탐색해서 속도가 느립니다.
검색, 삽입, 삭제의 시간 복잡도는 O(log n) 입니다.
기본키와 외래키는 무엇인가요?
기본키(Primary Key) 란 데이터베이스의 테이블의 각 레코드를 고유하게 식별하기 위해 사용하는 컬럼 혹은 컬럼의 집합 입니다.
기본키의 값은 테이블 내에서 고유합니다.
기본키는 NULL 값을 허용하지 않습니다.
한 번 설정된 기본키 값은 변경되면 안됩니다.
외래키(Foreign Key) 란 테이블의 필드가 다른 테이블의 기본키를 참조하는 것 입니다.
외래키는 레코드가 참조하는 다른 테이블의 레코드가 실제로 존재함을 보장합니다.
이를 통해 잘못된 데이터가 입력되는 것을 방지하고 데이터의 일관성과 무결성을 보장합니다.
트랜잭션과 트랜잭션 특징에 대해 설명해 주세요.
트랜잭션이란 DB의 상태를 변화시키기 위한 작업의 단위 입니다.
트랜잭션의 특징은 원자성, 일관성, 독립성, 지속성 4가지가 있습니다.
(ACID, Atomicity, Consistency, Isolation, Durability)
원자성
트랜잭션은 DB에 반영되거나 전혀 반영되지 않아야 합니다.
즉, 일부만 완료되는 상황이 있어서는 안됩니다.
일관성
트랜잭션 작업 처리 결과는 항상 동일해야 합니다.
독립성
트랜잭션이 수행 될 때, 다른 트랜잭션이 간섭할 수 없습니다.
지속성
한 번 성공적으로 DB에 적용된 트랜잭션은 영구 반영 됩니다.
정규화란 무엇인가요?
정규화란 데이터 중복을 최소화하여 무결성을 향상시키기 위해 테이블을 분리하는 것 입니다.
정규화는 여러 단계가 있습니다.
제1 정규화
테이블 컬럼이 하나의 값을 갖도록 테이블을 분리하는 것 입니다.
제2 정규화
테이블의 모든 컬럼이 완전 함수적 종속을 만족하게 테이블을 분리하는 것 입니다.
테이블의 모든 열이 기본키에 완전히 종속되되게 합니다.
예를 들어, 다음의 테이블이 있다 가정하겠습니다.
학생과 강의 테이블
학생ID | 이름 | 과목코드 | 과목 이름 | 강사 이름 |
1 | 홍길동 | CS101 | 컴퓨터 과학 | 홍수동 |
2 | 박영희 | CS101 | 컴퓨터 과학 | 홍수동 |
이 테이블은 과목코드에 따라 과목이름과 강사이름이 정해집니다. 이것을 부분 함수 종속성이라 합니다.
완전 함수 종속은 기본키인 학생ID에 종속되어야 합니다.
제 2정규화를 위해 학생ID를 기본키로 하는 테이블과 과목코드를 기본키로 하는 테이블로 분리할 수 있습니다.
학생 테이블
학생ID | 이름 | 과목코드 |
1 | 홍길동 | CS101 |
2 | 박영희 | CS101 |
강의 테이블
과목코드 | 과목 이름 | 강사 이름 |
CS101 | 컴퓨터 과학 | 홍수동 |
제3 정규화
제2 정규화가 진행된 테이블에서 이행적 함수 종속을 제거하기 위해 테이블을 분리하는 것 입니다.
이행적 함수 종속이란 간접적으로 다른 열에 종속되어 있는 경우를 뜻 합니다.
즉 A가 B에 종속되어 있고, B가 C에 중속되어 있을 때 A는 간접적으로 C에 종속되어 있습니다.
이런 종속성을 제거해 각 테이블이 하나의 주제에 집중하도록 만듭니다.
예시는 다음과 같습니다.
고객과 판매자 테이블
고객ID | 고객 이름 | 판매자 이름 | 판매자 지역 |
1 | 김철수 | 이영희 | 서울 |
2 | 박영희 | 이영희 | 서울 |
이 테이블에서 고객ID -> 판매자 이름 -> 판매자 지역이 결정되는 이행적 함수 종속성이 생겼습니다. 제3 정규화를 만족시키기 위해 고객ID를 키로 하는 테이블과 판매자 이름을 key로 하는 테이블로 분리할 수 있습니다.
고객 테이블
고객ID | 고객 이름 | 판매자 이름 |
1 | 김철수 | 이영희 |
2 | 박영희 | 이영희 |
판매자 테이블
판매자 이름 | 판매자 지역 |
이영희 | 서울 |
BCNF 정규화 (보이스-코드 정규화)
제3 정규화가 진행된 테이블에서 모든 결정자가 후보키가 되도록 분리 합니다.
결정자란 다른 속성을 함수적으로 결정 짓는 속성을 뜻 합니다.
후보키는 테이블에서 레코드를 식별할 수 있는 속성 혹은 속성 집합을 뜻 합니다.
판매자ID 테이블
판매자 ID | 이름 | 지역 |
1 | 김철수 | 서울 |
2 | 박영희 | 부산 |
이 테이블은 이름이 중복이 될 수 있기 때문에 이름을 기준으로 나누면 BCNF를 만족하지 않습니다. 왜냐하면 이름은 후보키가 아니기 때문입니다. 이 문제를 해결하기 위해 판매자ID를 기준으로 나눕니다.
판매자 ID | 이름 |
1 | 김철수 |
2 | 박영희 |
판매자 ID | 지역 |
1 | 서울 |
2 | 부산 |
반정규화란 무엇일까요?
반정규화란 데이터베이스의 성능 향상을 위해 데이터 중복을 허용하는 것 입니다.
반정규화를 하면 조회 속도는 향상되지만 모델의 유연성을 낮아지게 됩니다.
ORM이란 무엇일까요?
ORM(Object Relation Mapping) 이란 객체와 관계형 데이터베이스 데이터를 자동으로 매핑하는 것 입니다.
ORM은 객체를 구현한 클래스와 RDB의 테이블을 자동으로 매핑합니다.
객체와 테이블은 기존에 서로 호환 가능성을 생각하고 만든 것이 아니기에 불일치가 발생합니다.
이것을 ORM을 통해 객체 간의 관계를 바탕으로 SQL문을 자동으로 생성하여 불일치를 해결합니다.
ORM을 사용하면 SQL문을 작성하지 않아도 객체를 통해 간접적으로 DB를 조작할 수 있습니다.
JOIN이란 무엇일까요?
Join 이란 두 개 이상의 테이블을 서로 묶어서 하나의 결과 집합을 만들어 내는 것 입니다.
SQL Injection이란 무엇인가요?
SQL Injection 이란 조작된 SQL 쿼리문을 날려 DB에 그대로 전달되어 비정상적인 명령어를 실행시키는 공격 기법 입니다.
RDBMS와 NoSQL이란 무엇이며, 이 둘의 차이점은 무엇인가요?
RDBMS란 관계형 데이터베이스 관리 시스템 입니다.
RDBMS는 테이블의 관계를 맺으며 정해진 데이터 스키마에 따라 테이블에 저장 합니다.
즉, 정의된 구조에 따른 값만 집어 넣을 수 있습니다. 또한 데이터 중복을 피하기 위해 관계를 이용합니다.
대표적인 예로는 MySQL, Oracle Database, PostgreSQL, MS SQL Server 등이 있습니다.
NoSQL이란 비관계형 데이터베이스 입니다.
NoSQL은 스키마 제약, 관계 설정 등의 제한을 벗어나 데이터를 저장하고 처리합니다.
NoSQL은 주로 대규모 데이터를 처리하거나 분산 처리에 사용됩니다.
대표적인 예로는 MongoDB, Redis 등이 있습니다.
이 둘의 중요 차이점은 데이터 스키마와 관계의 유무 입니다.
교착상태(Deadlock)란 무엇인가요?
교착상태, 데드락이란 두 개 이상의 프로세스나 스레드가 서로 상호 대기 상태에 빠져 진행이 불가능한 상황을 말합니다.
데드락의 발생은 다음 네 가지 조건이 동시에 성립할 때 발생됩니다.
네 가지 조건이란 상호 배제, 점유와 대기, 비선점, 순환 대기를 말합니다.
상호 배제
한 번에 한 프로세스만이 자원을 사용하는 것을 뜻 합니다. 이 때 다른 프로세스는 그 자원에 접근할 수 없습니다.
점유와 대기
프로세스가 이미 할당된 자원을 보유한 상태에서 다른 프로세스가 점유한 자원을 요청하고 대기하는 것 입니다.
비선점
다른 프소세스가 점유하고 있는 자원을 강제로 빼았을 수 없습니다.
순환 대기
프로세스의 집합이 서로의 점유 자원을 대기하고 있는 상태 입니다.
이 네 가지 중 조건 중 하나라도 만족하지 않으면 데드락은 발생하지 않습니다.
즉, 데드락 예방 방법은 네 가지 조건 중 하나를 깨뜨리는 것 입니다.
데드락 예방 방법은 예방, 회피, 탐지, 회복이 있습니다.
예방
예방이란 데드락 발생하기 전 미리 조치를 취하는 것으로 4가지 조건 중 하나를 제거하는 것 입니다.
1. 상호 배제 -> 모든 자원 공유 허용
2. 점유와 대기 -> 모든 자원에 대한 선점 허용
3. 비선점 -> 필요한 자원 모두 할당
4. 순환 대기 -> 자원에 순서를 부여해 한 방향으로만 자원 요청
다만 이 방법은 자원의 낭비가 심할 수 있습니다.
회피
자원 할당 요청을 수락했을 때 안전하지 판단하는 방법입니다.
자원을 할당한다고 가정했을 때 안전하다 판단되면 자원을 할당하고 그렇지 않다면 다른 프로세스가 작업을 마치고 자원을 반납하는 것을 기다립니다.
회피의 예시로는 뱅크시 알고리즘(은행원 알고리즘)이 있습니다.
탐지
데드락이 발생하면 빠르게 발견하고 문제를 해결하는 방법입니다.
자원 할당 그래프를 통해 데드락의 발생 여부를 탐지할 수 있습니다.
회복
데드락을 일으킨 프로세를 종료하거나 할당된 자원을 해제 회복하는 방법입니다.