이 글은 데이터베이스 스터디 중 데이터베이스 기본개념 관련 질문을 정리한 것입니다.
SQL에 대해서 설명해주세요. C언어와 같은 프로그래밍 언어와 어떤차이가 있나요?
SQL이란 RDB와 상호작용하기 위한 컴퓨터 언어입니다. 데이터베이스를 관리 및 조작하기 위한 언어입니다. 이때, SQL은 DBMS가 어떤 동작을 수행하면 되는지 알려주는 역할을 합니다. C언어와 같은 프로그래밍 언어와 비교했을 때, SQL은 DB를 대상으로 하는 언어인 반면, C언어는 OS를 대상으로 한다는 점에서 다릅니다. 또한, SQL은 원하는 작업의 결과만을 기술하고, 그 작업이 어떻게 수행되는지 고려하지 않아도 되는 비절차적 언어인 반면, C언어는 절차적 언어입니다.
개발자가 작성한 SQL이 어떤 과정을 통해 실행 되는지 설명해주세요.
SQL이 실행되는 과정은, SQL 요청 → 쿼리 파서 → 전처리기 → 옵티마이저 → 쿼리 실행기 → SQL 응답 순으로 진행됩니다. 쿼리 파서는 SQL문장을 DBMS가 이해할 수 있는 최소단위로 나누며, 문법 오류를 확인합니다. 전처리기는 쿼리 파서를 통해 도출된 ‘파서 트리’를 기준으로, 쿼리 문장의 구조와 실제 테이블과의 매핑관계를 검사합니다. 옵티마이저는 쿼리 문장을 실행하기 위한 최적화된 전략을 수립하며, 쿼리 실행기는 옵티마이저에게 넘겨받은 계획을 토대로 실제 쿼리문을 실행하는 역할을 수행합니다.
DML은 무엇인가요? 어떤 구문이 있는지도 설명해주세요.
DML은 데이터 조작 언어로서, 데이터 검색, 삽입, 수정, 삭제를 수행하는 언어입니다. DML에 포함되는 구문으로는 SELECT , INSERT, UPDATE, DELETE가 있습니다. INSERT, UPDATE, DELETE 구문은 대부분 레코드 단위로 작업이 진행되지만, SELECT 구문은 테이블 단위로 작업이 진행되기 때문에, SELECT 절이 어떠한 순서로 처리되는지 유의해야 합니다.
DDL은 무엇인가요? 어떤 구문이 있는지도 설명해주세요.
DDL은 데의터 정의어로서, DBMS의 구성요소인 DB, 테이블, 프로시저등을 생성하거나 변경할 때 사용합니다. 대표적인 구문으로는 CREATE, ALTER, DROP 세 가지 구문이 존재합니다. 각 구문의 역할을 이해하기 위해 테이블 생성을 예시로 들 수 있습니다. CREATE 구문을 통해 속성, 키, 제약조건을 갖고있는 테이블을 생성합니다. ALTER 구문을 통해서 앞서 생성한 테이블의 속성들을 변경할 수 있습니다. DDL의 DROP 구문은 테이블을 삭제할 때 사용하며, 테이블의 속성을 삭제하고 싶을 때는 ALTER의 DROP 옵션을 활용합니다.
DCL은 무엇인가요? 어떤 구문이 있는지도 설명해주세요.
DCL은 데이터 제어 언어로서, 데이터에 대한 접근 권한 및 DB 시스템에 대한 전반적인 권한 설정을 하는데 사용됩니다. GRANT와 REVOKE 구문을 포함하고 있습니다. 대표적인 접근 권한의 대상으로는 테이블이며, 테이블에 대해 DML 실행 가능 구문 권한을 부여할 수 있습니다. GRANT는 사용자에게 권한을 부여하는 것이며, REVOKE는 사용자의 권한을 해제하는 것입니다.
참조 무결성에 대해서 설명해주세요.
참조 무결성이란, 다른 테이블의 기본키를 어느 테이블의 외래키로 사용할 때, 외래키로 사용되는 값은 다른 테이블의 기본키로 실제 존재한다는 특성입니다. 이러한 특성을 유지하기 위한 기능으로 SQL의 DDL문에서는 CASCADE 설정을 지원합니다.
CASCADE 설정에 대해서 설명해주세요.
CASCADE 설정은 외래키를 지정할 때 함께 적용할 수 있는 제약조건입니다. CASCADE 설정 시, 외래키가 참조하는 기본키가 삭제될 경우, 외래키도 함께 삭제되는 기능을 수행합니다. 삭제의 경우에는 ON DELETE CASCADE라는 구문을 사용하는데요, ON UPDATE CASCADE라고 참조되는 기본키가 수정될 경우, 외래키도 동일하게 수정되도록 하는 기능도 지원합니다.
VIEW에 대해서 설명해주세요.
VIEW란 다른 테이블을 기반으로 만들어지는 가상의 테이블입니다. VIEW는 실제 물리적으로 저장되는 기본 테이블과는 달리, VIEW에 대한 데이터는 저장되지 않습니다. VIEW 생성 시, SELECT 문을 참조하는데, 여기서 참조되는 테이블들이 VIEW가 참조할 수 있는 데이터가 됩니다. 만약 VIEW에 INSERT 문을 수행할 경우, VIEW가 활용하고 있는 기본 테이블에 데이터가 저장될 것입니다. 다만, VIEW는 데이터의 보안을 유지하는 목적으로도 사용되기 때문에, 실제 데이터 변경 권한에는 제한이 있을 수 있습니다.
SELECT 절의 처리순서에 대해서 설명해주세요.
SELECT 문장에 포함되는 각 절의 실행 순서에 대해 설명하겠습니다. 가장 먼저, FROM절과 JOIN절이 실행되는데요, 쿼리문에서 사용할 데이터 셋을 결정합니다. 이후 WHERE절에서 각 튜플에 대해 조건과 부합하는 지 여부를 확인하고 필터링을 수행합니다. 만약 GROUP BY절이 있다면 WHER절을 통해 필터링된 튜플들에 대해 그룹화를 수행합니다. HAVING 절이 있다면 GROUP BY에 의해 그룹화된 튜플들에 대한 필터링을 수행합니다. 이후 SELECT 절이 실행되는데요, SELECT 절이 포함하고 있는 표현식들이 최종적으로 수행됩니다.
SELECT ~ FOR UPDATE 구문에 대해서 설명해주세요.
SELECT FOR UPDATE 구문은 pessimistic 락을 쿼리 레벨에서 지원하기 위한 구문입니다. pessimistic 락이란, 먼저 접근 권한을 얻으면 수정 가능하도록 하는 락인데요, SELECT FOR UPDATE 구문의 경우, 수정을 위해서 SELECT를 한다는 것을 알리고 락을 잡는다는 의미를 갖고 있습니다. 행 레코드 단위로 동시 접근 제어를 수행하며, 락이 걸린 이후에 접근한 커넥션은 트랜잭션이 종료될 때까지 대기하게 됩니다. SELECT FOR UPDATE는 간단하는 장점이 있지만, 락을 사용하는 만큼 데드락에 유의해야 된다는 단점이 있습니다.
GROUP BY절에 대해서 설명해주세요.
GROUP BY절은 테이블에서 특정 속성들의 값이 동일한 튜플들을 모아 그룹으로 만든 뒤, 그룹별로 검색하기 위해서 사용하는 절입니다. 그룹에 대한 특정 조건들을 적용시킬 수 있는데요, 이때는 HAVING 키워드를 함께 사용합니다. GROUP BY절 사용 시 유의할 점은, GROUP BY절에 명시된 컬럼 중 하나라도 인덱스에 없으면, 인덱스이용하지 못한다는 것입니다.
ORDER BY절에 대해서 설명해주세요.
SELECT문 요청으로 출력되는 데이터의 정렬을 수행할 때 ORDER BY 키워드를 사용합니다. 2개 이상의 컬럼에 대해서도 정렬을 수행할 수 있으며, 컬럼별로 오름차순 및 내림차순을 다르게 설정할 수 있습니다. ORDER BY 사용시 유의할 점은, GROUP BY와 함께 사용시 정렬로 사용할 컬럼은 GROUP BY에서 사용되는 컬럼이여야 한다는 것이다.
INNER JOIN과 OUTER JOIN의 차이점에 대해서 설명해주세요.
INNER JOIN은 조인 컬럼의 값이 일치하는 튜플만을 원할 때 사용하지만, OUTER JOIN은 조인 컬럼의 값이 존재하지 않는 경우도 고려할 때 사용한다는 차이점이 있습니다. 이러한 특성에 의해 INNER JOIN은 조인 조건에 의해 필터링된 데이터에 대해 JOIN 연산을 수행하여, 상대적으로 OUTER JOIN보다 성능면에서 우위가 있습니다.
LEFT OUTER JOIN, RIGHT OUTER JOIN에 대해서 설명해주세요.
두 테이블간의 JOIN을 가정했을 때, LEFT OUTER JOIN은 우측 테이블의 튜플에서 조인 조건을 만족하지 않더라도, 해당 튜플을 NULL 값으로 비워두는 형태를 말합니다. 반대로 RIGHT OUTER JOIN은 좌측 테이블의 튜플에서 조인 조건을 만족하지 않더라도, 해당 튜플을 NULL 값으로 비워둡니다.
CROSS JOIN에 대해서도 설명해주세요.
CROSS JOIN은 카타시안 곱이라고 표현하기도 합니다. 두 테이블의 모든 튜플들에 대해 n * m의 형태로 매핑시켜 데이터를 추출하는 것을 말합니다. CROSS JOIN에서는 조인 컬럼이 존재하지 않으며, 중복을 고려하지 않는다. 예를 들어, 어느 테이블의 튜플이 4개이고, 다른 테이블의 튜플이 3개일 때, CROSS JOIN은 12개의 로우들을 반환할 것이다.
서브쿼리에 대해서 설명해주세요.
서브쿼리를 사용하면 쿼리를 작성할 때 단위 처리별로 쿼리를 독립적으로 작성할 수 있습니다. JOIN을 사용할 때보다 상대적으로 작성하기 쉽다는 장점이 있습니다. 그러나, 서브쿼리에 대해 옵티마이저의 최적화에 영향을 줄 수 있다는 단점이 있기 때문에 이점을 유의해야 합니다. 서브쿼리가 사용될 수 있는 위치는 대표적으로 SELECT절, FROM 절, WHERE 절 입니다.
DROP, TRUNCATE, DELETE에 각각에 대해 설명해주세요. 어떤차이가 있나요?
DROP 명령어는 테이블 전체를 삭제하며, 테이블에 할당되었던 디스크 공간과 객체를 모두 삭제합니다. TRUNCATE는 테이블은 삭제하지 않지만, 관련된 데이터와 인덱스는 삭제됩니다. DELETE의 경우 데이터는 삭제하지만, 테이블의 용량은 그대로 유지된다는 특징을 가지고 있습니다.
DISTINCT에 대해서 설명해주세요. 사용해본 경험도 설명해주세요.
DISTINCT절은 SELECT 되는 레코드 중에서 유니크한 레코드만 가져오고자 할 떄 사용합니다. 다만, 특정 컬럼만을 유니크하게 조회하는 것이 아니라, SELECT 하는 레코드를 유니크하게 조회하는 것이기 때문에, 여러 컬럼들에 대해 DISTINCT절을 사용할 경우 이 점을 유의해야 합니다. 실제 사용해본 경험은, 사내 시스템에서 사용자 계정에 할당된 권한 코드 필드가 어떤 것이 있는지 조회할 떄 사용한 경험이 있습니다.
SQL Injection 공격이 무엇인지 어떻게 공격을 예방할 수 있는지 설명해주세요.
SQL 인젝션은 DB에 임의의 SQL문을 주입하여, DB가 비정상적인 동작을 하도록 조작하는 웹 해킹 기법을 말합니다. 웹 서버로 전달하는 API 호출을 예시로 들 수 있는데요, API 요청 파라미터에 특정 구문을 넘어, 서버의 DB에서 실행될 쿼리를 조작할 수 있습니다. SQL 인젝션을 예방하는 대표적인 방법으로는, 클라이언트에게 넘겨받은 값에 불필요한 문자가 포함되어있는지 체크하는 방법과 DB에게 전달하는 쿼리문을 만들 때, 클라이언트에게 넘겨받은 값을 매개변수 형태로 전달하여, 특수문자를 escape하도록 방법이 있습니다.
페이지네이션을 구현한다고 했을때 쿼리를 어떻게 작성해야할까요?
MySQL을 기준으로 했을 때, LIMIT와 OFFSET함께 사용하거나, 정렬된 데이터를 가져올 때 cursor를 사용하여 구현 가능합니다. LIMIT와 OFFSET을 사용하는 경우는 사용자가 직접 페이지 번호를 선택할 수 있을 때 적합하고, cursor를 이용하는 방법은 이전 페이지와 다음 페이지 기능을 구현할 때 적합합니다.
'CS > 데이터베이스' 카테고리의 다른 글
[DB] SQL - JOIN (1) | 2024.01.23 |
---|---|
[DB] Real MySQL 8.0 - 4.2 InnoDB 스토리지 엔진 아키텍처 (2) | 2024.01.22 |
[DB] SELECT 문장 처리 순서 (2) | 2024.01.18 |
[DB] SQL -DDL (0) | 2024.01.17 |
[DB] SQL 개요 (0) | 2024.01.17 |