본문 바로가기
기타 CS

기술 면접 준비 - 데이터베이스(1)

by 밝지 2023. 2. 22.
728x90
반응형

트랜잭션 특징 ACID

트랜잭션의 특징은 원자성(Atomicity), 일관성(Consistency), 격리성(Isolation), 지속성(Durability)입니다. 원자성은 트랜잭션의 작업이 부분적으로 실행되거나 중단되지 않는 것입니다. (모두 성공하거나 모두 실패해야 한다.) 일관성은 일관성 있는 데이터 베이스 상태를 유지하는 것입니다. 격리성은 동시에 실행되는 트랜잭션은 서로 영향을 미치지 않아야 한다는 것이고, 지속성은 트랜잭션 완료 시 결과가 영구적으로 반영되어야 하는 것입니다.

 

 

NOSQL

Not Only SQL의 약자로 SQL을 보완한다는 뜻입니다. SQL과 NOSQL의 차이는 스키마의 유무 그리고 관계의 명확성 입니다. NOSQL은 스키마가 없습니다. 데이터 조회나 삽입 속도가 빨라 대량의 분산 데이터 처리에 적합합니다.

 

 

 

파티셔닝

테이블을 컬럼 단위로 나누어 관리하는 기법입니다. 테이블을 컬럼 단위로 나누는 것이 파티셔닝입니다. UPDATE, INSERT 와 같은 장업이 분산되어 성능이 향상됩니다. 테이블 간 조인 비용이 증가하고 인덱스를 별도로 파티셔닝 할 수 없다는 단점도 있습니다. 

 

 

 

샤딩

테이블을 로우(행) 단위로 분산하여 저장하는 방법입니다. Horizontal Partitioning이라고도 합니다. Shard Key를 정의에 따라 데이터 분산이 결정됩니다. 샤딩 방법에는 크게 Hash Sharding 과 Dynamic Sharding이 있습니다. Hash Sharding은 Cluster 안의 Node 개수에 따라 Database id를 Hashing 하여 샤드키를 결정합니다. 단점은 테이블 확장이 필요한 경우 샤드키를 정하는 규칙 자체를 바꾸고 데이터를 전체적으로 조정해야 한다는 점입니다. Dynamic Sharding은  샤딩 범위를 따로 관리하고 그에 맞춰 테이블을 관리하는 방식으로 테이블 확장이 필요한 경우 샤딩 범위를 조절하고 그에 맞게 일부 테이블의 데이터만 조정하면 된다는 장점이 있습니다. 

 

 

 

Join 종류와 원리

조인이란 두 개 이상의 테이블을 하나의 집합으로 만드는 연산입니다. 조인 연산은 두 테이블 사이에서 수행됩니다. 주로 쓰는 조인 기법의 종류에는 NL Join, Hash Join, Sort Merge Join 이 있습니다.

[NL Join]

NL Join은 중첩 반복문과 유사한 방식으로 조인을 하는 것입니다. 반복문의 외부에 있는 테이블을 선행 테이블 또는 Outer 테이블이라고 하고 반복문의 내부에 있는 테이블을 후행 또는 Inner 테이블이라고 합니다. 선행 테이블의 조건을 만족하는 행을 추출하여 후행 테이블을 읽으면서 조인을 수행합니다. 이 작업을 선행 테이블의 조건을 만족하는 모든 행의 수만큼 반복합니다. 따라서 결과 행의 수가 적은 테이블을 조인 순서 상 선행 테이블로 선택하면 전체 작업량을 줄일 수 있습니다. NL join은 랜덤 방식으로 데이터를 액세스 하기 때문에 처리 범위가 좁을수록 유리합니다. 

[Sort Merge Join]

Sort Merge Join은 조인 컬럼을 기준으로 데이터를 정렬하여 조인을 수행하는 것입니다. Sort Merge Join은 스캔 방식으로 데이터를 읽습니다. 랜덤 액세스를 하는 NL Join이 부담이 될 수 있는 넓은 범위의 데이터 처리 시 이용됩니다. 하지만 정렬할 데이터가 많아 메모리에서 모든 정렬 작업을 수행하기 어려운 경우 임시 디스크를 사용하기 때문에 성능이 떨어질 수 있습니다. 일반적으로 대량의 조인 작업 시에는 정렬 작업이 필요한 Sort Merge Join 보다는 CPU 작업 위주로 처리하는 Hash Join이 성능 상 유리합니다. 그러나 Sort Merge Join은 해시 조인과 달리 비동등 조인에서도 조인 작업이 가능하다는 장점이 있습니다. Sort Merge Join은 조인 컬럼의 인덱스를 사용하지 않기 때문에 조인 컬럼의 인덱스가 존재하지 않은 경우에도 사용이 가능합니다. 앞 단계 작업에서 정렬 작업이 미리 수행된 경우 조인을 위한 정렬은 추가로 발생하지 않습니다.

[Hash Join]

Hash Join은 해싱 기법을 이용하여 조인을 수행합니다. 조인을 수행할 테이블의 조인 컬럼을 기준으로 해시 함수를 수행하여 서로 동일한 해시 값을 가진 것들 사이에서 실제 값이 같은지를 비교하면서 조인을 수행합니다. NL Join의 랜덤 액세스 문제점과 Sort Merge Join의 정렬 작업에 대한 부담을 해결하기 위한 대안으로 등장했습니다. 조인 컬럼의 인덱스를 사용하지 않기 때문에 조인 컬럼의 인덱스가 존재하지 않은 경우에도 사용할 수 있습니다. 해시 조인은 선행 테이블의 해싱 결과를 해시 테이블에 저장하고, 후행 테이블은 해시 테이블에 대해 해시 값의 존재 여부를 검사하는 방식으로 조인합니다. 해시 함수를 이용해 조인을 하기 때문에 동등 조인에서만 사용할 수 있습니다. 해시 조인은 조인 작업을 수행하기 위해 해시 테이블을 메모리에 생성합니다. 생성된 해시 테이블의 크기가 메모리보다 커지면 임시 디스크에 해시 테이블을 저장하기 위해 작업이 추가되고 성능이 저하됩니다. 때문에 선행 테이블의 결과를 완전히 메모리에 저장할 수 있도로고 해시 조인 시 결과 행의 수가 적은 테이블을 선행 테이블로 사용하는 것이 좋습니다. 

 

 

 

JDBC, ODBC 차이

DBC의 경우는 자바와 데이터베이스와 연결해주는 것이고, ODBC는 윈도우용 어플을 데이터베이스와 연결시켜준다는 것이다. JDBC는 자바에서만 가능한 반면 ODBC는 자바, C, C++과 같이 언어에 상관없이 사용할 수 있다.

 

 

 

인덱스

인덱스의 기본 목적은 검색 성능의 최적화로 원하는 데이터를 쉽게 찾을 수 있도록 돕는 책의 목차와 유사한 개념입니다. 인덱스는 테이블을 기반으로 선택적으로 생성할 수 있는 구조입니다. 인덱스는 생성하지 않아도 되고 여러개를 생성해도 됩니다. Insert, Update, Delete와 같은 DML 작업 시에는 오히려 인덱스로 인해 성능히 느려질 수도 있습니다.

[B-트리 인덱스]

트리 기반 인덱스 중 가장 일반적으로 사용하는 인덱스 입니다. B-트리 인덱스는 브랜치 블록과 리프 블록으로 구성됩니다. 브랜치 블록 중 가장 상위의 블록이 루트 블록입니다. 브랜치 블록은 분기를 목적으로 하는 블록으로 다음 단계의 블록을 가리키는 포인터를 가지고 있습니다. 리프 블록은 트리의 가장 아래 단계에 존재합니다. 리프 블록은 인덱스를 구성하는 컬럼의 데이터와 해당 데이터를 가지고 있는 행의 위치를 가리키는 레코드 식별자(Rowid)로 구성되어 있습니다. 인덱스 데이터는 인덱스를 구성하는 컬럼의 값으로 정렬됩니다. 만약 인덱스의 데이터 값이 동일하면 레코드 식별자의 순서로 저장됩니다. 리프 블록은 양방향 링크(더블 링크)를 가지고 있어 오름차순과 내림차순 검색을 쉽게 할 수 있습니다. 일치 검색과 범위 검색 모두에 적합합니다. 인덱스를 경유하여 반환된 결과 데이터는 인덱스 데이터와 동일한 순서를 가집니다. 인덱스 컬럼의 순서는 질의 성능에 중요한 영향을 미칩니다. 오라클에는 트리 기반 인덱스로 B-트리 인덱스 외에도 비트맵 인덱스, 리버스 키 인덱스, 함수 기반 인덱스 등이 존재합니다. 

[SQL Server의 클러스터형 인덱스]

SQL Server 인덱스는 저장 구조에 따라 클러스터형과 비클러스터형으로 나뉩니다. 클러스터형 인덱스는 두 가지 중요한 특징이 있습니다. 첫 째, 인덱스의 리프 페이지가 곧 데이터 페이지 입니다. 클러스터형 인덱스의 리프 페이지를 탐색하면 해당 테이블의 모든 컬럼과 값을 바로 얻을 수 있습니다. 때문에 클러스터형 인덱스를 흔히 사전에 비유합니다. (색인에서 페이지 번호만 알려주는 것과 다름) 둘 째, 리프 페이지의 모든 로우(데이터)는 인덱스 키 칼럼 순으로 물리적으로 정렬되어 저장됩니다. 테이블 로우는 물리적으로 한 가지 순서로만 정렬됩니다. 따라서 클러스터형 인덱스는 테이블 당 한 개만 생성할 수 있습니다. 

 

 

 

728x90
반응형