RDBMS vs NOSQL에 대해서 설명해주세요.
핵심답변
- 관계형 데이터베이스 관리 시스템(RDBMS, Relational Database Management System)의 핵심적인 특징은 두가지 입니다.
첫째, 모든 정보는 정해진 데이터 스키마에 따라 행과 열을 갖춘 테이블 형태로 저장됩니다.
둘째, 관계형 데이터베이스에서는 데이터의 집합인 엔티티끼리 서로 관계를 맺을 수 있습니다. (1:1, 1:N, N:M 관계) 관계를 이용하면 하나의 테이블에서 중복 없이 하나의 데이터만을 관리할 수 있습니다.
데이터는 테이블에 레코드로 저장되며, 각 테이블마다 필드의 이름과 데이터 유형(스키마)으로 정의된 구조가 있습니다. 따라서 스키마를 준수하지 않은 레코드는 테이블에 추가되지 않습니다.
RDBMS는 일반적으로 SQL(Structured Query Language)로 관리하는 것이 표준화되어 있습니다.
- NoSQL(Not Only SQL)은 관계형 데이터베이스가 아니며, 스키마 없이 혹은 느슨한 형태의 스키마로도 사용할 수 있습니다. 여기에서 데이터 테이블은 그냥 하나의 테이블로, 관계를 설정하지도 않고 JOIN도 할 수 없습니다.
🤔 두 DB의 장단점을 간략하게 말해볼 수 있을까요?
- RDBMS
- 장점: 정해진 스키마에 따라 데이터가 저장되므로 데이터 구조가 명확하고, 각 관계를 따라 저장된 데이터는 중복 없음이 보장됩니다.
- 단점: 테이블 간 관계로 얽혀 있어 시스템이 커진다면 쿼리가 복잡해질 수 있습니다. 또한 성능 향상을 위해 서버 자체의 성능을 Scale-up하는 방법 밖에 없기 때문에 비용이 기하급수적으로 늘어날 수 있습니다.
- NoSQL
- 장점: 스키마가 없기 떄문에 데이터 구조가 자유롭습니다. 언제든지 데이터를 조정하거나 새로운 필드 추가가 가능합니다. 데이터 분산이 용이하기 때문에 대량의 데이터를 빠르게 처리해야 하는 요즘 상황에 적합할 수 있습니다. 성능 향상을 위해서도 Scale-Up과 Scale-Out 모두 가능합니다.
- 단점: 데이터 중복 문제가 발생할 수 있고 스키마가 존재하지 않으므로 데이터 구조가 명확하지 않습니다.
🤔 그렇다면 어떤 기준으로 DB를 선택할 수 있죠?
RDBMS는 데이터 구조가 명확하고 명확한 스키마가 중요할 때 사용할 수 있습니다. 데이터 중복이 없음이 보장되므로 재무관련, 보안, 개인 건강정보 시스템과 같은 곳에서 선택할 만 합니다.
반면 NoSQL은 막대한 데이터를 저장해야 할 필요가 있고 작성 속도가 빨라야 하는 데이터 분석, 빠른 트로토타입 작업 등에서 사용할 수 있습니다.
Index
Q) Index란 무엇인가요?
A) 인덱스는 DB에서 마치 책의 처음에 있는 색인과 같은 역할을 합니다. 즉 칼럼의 값과 해당 레코드가 저장된 주소를 키와 값의 쌍으로 묶어 빠르게 데이터를 검색하고 원하는 결과를 가져올 수 있게 해줍니다.
데이터베이스에서 index를 만들면 내부적으로 어떤동작이 이루어지는지 설명해주시고 장단점에 대해 설명해주세요.
**핵심답변**
Q) 데이터베이스에서 index를 만들면 성능이 빨라지게 되는 이유를 설명해주세요.
A) 인덱스를 사용하지 않으면 수 만개의 데이터가 있는 테이블에서 데이터를 조회할 경우 기준이 없기 때문에 FULL TABLE SCAN을 통해 원하는 데이터를 찾게 됩니다. 반면 인덱스는 데이터를 색인화하여 검색하므로 속도가 빨라지게 됩니다.
Q) hash index를 사용했을 때의 단점과 이유를 설명하세요.
A) 해시 테이블은 (Key, Value)로 데이터를 저장하는 자료구조 중 하나입니다. Key값을 이용해 고유한 인덱스를 생성하고 그 인덱스에 저장된 값을 꺼내오는 구조입니다. 미리 저장된 메모리 bucket에 한 번에 접근하기 때문에 탐색 시간이 O(1)로 빠릅니다. 하지만 이는 '단 하나의 데이터를 검색하는 시간'에 한정한 시간 복잡도입니다. 또, 해시는 등호(=) 연산에만 특화되어 있다는 단점이 있습니다. 따라서 부등호 연산이 자주 사용되는 데이터베이스 검색을 위해서는 해시 테이블이 적합하지 않습니다.
Q) 인덱스에 왜 해쉬 보다 B-Tree를 쓰는가?
A) B-Tree는 밸런스 트리의 일종으로, 트리의 노드가 한 방향으로 쏠리지 않도록 노드 삽입 및 삭제 시 특정 규칙에 의해 재정렬 되어 왼쪽과 오른쪽의 자식이 균형을 유지합니다.
B-Tree는 항상 정렬된 상태로 특정 값보다 크고 작은 부등호 연산이 가능합니다. 또한 참조 포인터가 적어 데이터 양이 방대해지더라도 빠른 데이터 접근이 가능합니다. 마지막으로 데이터 탐색, 저장, 수정, 삭제에 항상 O(logN)의 시간 복잡도를 가져 상대적으로 탐색 시간이 빠릅니다.
Transaction
Q) 트랜잭션에 대해서 설명해주세요.
A) 트랜잭션은 하나의 논리적인 작업 단위를 구성하는 연산들의 집합입니다. 예컨대 한 계좌에서 다른 계좌로 10만원을 송금할 경우 전체 작업은 정상적으로 완료되어야 하고, 만약 정상적인 처리가 불가능하면 아무 것도 실행되지 않은 처음 상태로 되돌려져야 합니다. 트랜잭션은 이렇듯 작업의 일부만 적용되는 현상이 발생하지 않도록 해줍니다.
Q) 트랜잭션을 사용할 때의 장점은 무엇인가요
A) 트랜잭션을 통해 작업의 안정성을 보장받을 수 있습니다. 데이터를 입력, 갱신, 처리하는 도중에 오류가 발생하면 모든 작업을 원 상태로 되돌리기 때문입니다. 처리 과정이 모두 성공했을 때에만 DB에 반영됩니다.
Q) 트랜잭션의 특성에 대해 설명해주세요(ACID)
- Atomicity (원자성)
- 트랜잭션은 데이터베이스에 모두 반영되거나, 아니면 전혀 반영되지 않아야 한다는 특성입니다.
- Consistency (일관성)
- 트랜잭션의 작업 처리 결과는 항상 일관성이 있어야 합니다. 트랜잭션이 진행되는 동안 DB가 변경되더라도 업데이트 된 DB로 진행되는 것이 아니라, 처음 참조한 DB로 진행됩니다.
- Isolation (독립성)
- 둘 이상의 트랜잭션이 동시에 실행되고 있을 경우 어떤 하나의 트랜잭션이라도 다른 트랜잭션의 연산에 끼어들 수 없습니다.
- Durability (지속성)
- 트랜잭션이 성공적으로 왼성되면 결과는 영구적으로 반영되어 지속됩니다.
Q) 트랜잭션 격리 수준(Transaction Isolation Levels)에 대해서 설명해주세요.
A) 여러 트랜잭션이 처리될 때, 특정 트랜잭션이 다른 트랜잭션에서 변경하거나 조회하는 데이터를 볼 수 있도록 허용할지 여부를 결정하는 것입니다.
- READ UNCOMMITTED: 각 트랜잭션 변경 내용이 Commit이나 Rollback 여부에 상관 없이 다른 트랜잭션에서 값을 읽을 수 없음
- READ COMMITTED: RDB에서 대부분 기본적으로 사용되는 격리 수준
- REPEATABLE READ: 트랜잭션마다 트랜잭션 ID를 부여하여 트랜잭션 ID보다 작은 트랜잭션 번호에서 변경한 것만 읽음
- SERIALIZABLE: 가장 단순하지만 가장 엄격한 격리 수준
4가지로 구분되고, 아래로 내려갈수록 트랜잭션 간 고립정도는 높아지고 성능은 떨어집니다.
Q) 잠금 타임아웃(Lock Timeout)과 교착 상태(Deadlock)가 발생하는 이유에 대해서 설명해주세요.
- 잠금 타임아웃: 트랜잭션A의 갱신과 트랜잭션B의 갱신이 충돌하는 경우, wait이 발생하고 지정 시간이 지나면 잠금 타임아웃이 발생한다.
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
- 교착상태: 트랜잭션A는 a에, 트랜잭션B는 b에 갱신을 한 상태일 떄, 트랜잭션 A가 b에 갱신을 하려 하고, 트랜잭션B는 a에 갱신을 하려고 하면 교탁 상태가 발생한다.ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
Q) 트랜잭션 Rollback은 어떤 경우에 하나요?
Rollback은 트랜잭션이 행한 모든 연산을 취소시키거나 트랜잭션을 재시작하는 것으로, 트랜잭션의 실행 중에 장애가 발생한 경우 수행합니다. 롤백을 수행하면 트랜잭션으로 인한 하나의 묶음 처리가 시작되기 이전, 직전 커밋 직후의 상태로 돌아갑니다.
JPA
Q) ORM이란?
객체와 관계형 데이터베이스를 매핑해주는 것으로 쿼리문 작성 없이 객체를 데이터베이스에 직접 저장할 수 있게 도와주는 기술입니다.
Q) JPA, Hibernate 그리고 Spring Data JPA 각각에 대해서 설명해주세요.
-
JPA란 Java Persistance API의 약자로 JAVA ORM 표준 기술 명세입니다.자바에서 데이터를 DBMS에 영구히 기록할 수 있는 환경을 제공하는 API이자, 인터페이스입니다.
-
Hibernate는 JPA의 구현체 중 하나입니다.JPA는 단순히 명세이기 때문에 구현이 없습니다. 따라서 인터페이스를 직접 구현한 라이브러리가 필요하며, Hibernate가 그 역할을 합니다. 내부적으로 JDBC API를 사용합니다.
-
Spring Data JPA는 JPA를 편하게 쓸 수 있도록 만들어 놓은 모듈입니다. JPA를 한 단계 추상화시킨 Repository라는 인터페이스를 제공합니다.
참고 자료
Q) 데이터 정합성에 대해서 설명해주세요. JPA에서 이것들을 어떻게 처리하는가요?
데이터 정합성은 데이터들의 값이 모순됨이 없이 서로 일치함을 뜻합니다.
Q) DB Lock에 대해서 설명해주세요. JPA에서 이것들을 어떻게 처리하는가요?
Lock은 데이터 영속성과 트랜잭션 처리의 순차성을 보장하기 위한 방법입니다. 데이터 시스템은 여러곳에서 동시에 접근할 수 있는 구조이기 때문에 필연적으로 데이터의 변경 또는 충돌로 인한 오염의 가능성이 있습니다. Lock은 이러한 경우를 방지해줍니다.
- Shared Lock: Read Lock이라고도 하는 공유 락은 데이터를 읽을 때 사용합니다. 같은 Read Lock끼리는 동시 접근이 가능한데, 읽는 것 만으로는 이는 데이터 일관성과 무결성을 해치지 않기 때문입니다. 다만 Exclusive Lock의 접근은 제한됩니다.
- Exclusive Lock: Write Lock, 베타락이라고도 하는 Exclusive Lock은 데이터를 변경할 때 사용합니다. 트랜잭션이 완료될 때 까지 유지 됩니다. Exclusive Lock이 끝날 때 까지는 어떠한 접근도 허용되지 않습니다.
👉 JPA Lock
- Optimistic Lock: 데이터 갱신 시 경합이 일어나지 않을 것이라고 낙관적으로 보고 잠그는 기법입니다. 예컨대 회원 정보는 해당 회원에 의해서만 발생할 것이므로 동시 요청이 발생할 가능성이 낮습니다.
- Pessimistic Lock: 동일 데이터를 동시에 수정할 가능성이 높다는 비관적 전제에서 잠그는 방식입니다. 예컨대 상품의 재고는 동시에 여러 사람이 주문할 가능성이 높습니다. 이럴 경우 비관적 잠금을 통해 예외를 발생시키지 않으면서 정합성을 유지하는 것이 중요합니다. 주로 Exclusive Lock을 이용합니다.
- Implicit Lock: 코드에 명시적으로 지정하지 않아도 잠금이 발생하는 Lock입니다. @Version이나 @OptimisticLocking 어노테이션이 있는 경우 자동적으로 충돌 감지를 위해 잠금이 실행됩니다. DB의 경우에는 업데이트, 삭제 쿼리 발행시 암시적인 Row Exclusive Lock이 실행됩니다.
- Explicit Lock: 프로그램을 통해 명시적으로 잠금을 실행합니다. JPA에서 엔티티를 조회할 떄 LockMode를 지정하거나, SELECT FOR UPDATE 쿼리를 통해 직접 지정할 수 있습니다.
Q) JPA는 로그 기법에 대해 어떻게 처리하는가?
- 표준 출력: application.properties에 아래 코드를 추가합니다. 간단한 방식이지만 로깅 프레임 워크를 최적화하지 않고 모든 것을 표준 출력으로 직접 언로드하기 때문에 권장되는 방식은 아닙니다.
spring.jpa.show-sql=true
- 로거를 통한 처리: 속성 파일에서 로거를 구성해 SQL문을 기록하는 방식도 있습니다.
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
- JDBCTemplate 쿼리 로깅: JdbcTemplate을 사용할 때 로깅을 구성하는 방식은 다음 속성이 필요합니다.
logging.level.org.springframework.jdbc.core.JdbcTemplate=DEBUG
logging.level.org.springframework.jdbc.core.StatementCreatorUtils=TRACE
참고 링크
QueryDSL을 사용하는 이유와 JPQL과 차이점에 대해서 설명해주세요.
Spring Data Jpa가 기본적으로 제공하는 CRUD 메서드 및 Query 메서드 기능을 사용하더라도, 원하는 조건의 데이터를 수집하기 위해서는 필연적으로 JPQL을 작성하게 됩니다. 그러나, JPQL 문자열에 오타나 문법적 오류가 있는 경우 정적 쿼리는 어플리케이션 로딩 시점에 발견할 수 있지만 그 외에는 런타임 시 에러가 발생합니다. 이러한 경우를 해소하기 위해 QueryDSL을 사용합니다.
QueryDSL은 정적 타입을 이용해 SQL 등의 쿼리를 생성하는 프레임워크 입니다.
1. 문자가 아닌 코드로 쿼리를 작성해 컴파일 시점에 문법 오류 파악이 손쉽다.
2. 자동완성과 같은 IDE의 도움을 받을 수 있다.
3. 동적인 쿼리 작성이 편리하다.
4. 쿼리 작성 시 제약 조건 등을 메서드 추출을 통해 재사용 할 수 있다.
정규화
Q) Nomalization 이 무엇인가요? Denormalization은 무엇이고, 언제 시행하게 되는지 설명해주세요.
정규화(Nomalization)는 관계형 데이터 베이스에서 데이터의 중복을 줄이고, 무결성을 향상시킬 수 있도록 데이터를 구조화 하는 작업입니다.
- 제1정규화(InF): 테이블 컬럼이 하나의 값을 갖도록 테이블을 분리시킵니다. '어떤 릴레이션에 속한 모든 도메인은 원자값으로만 되어 있을 것', '모든 속성에 반복되는 그룹이 나타나지 않을 것', '기본키를 사용해 관련 데이터의 각 집합을 고유하게 식별할 수 있을 것'을 조건으로 합니다.
- 제2정규화(2NF): 테이블의 모든 컬럼이 완전 함수적 종속을 만족해야 합니다. 완전 함수적 종속이란 X->Y라고 가정했을 때 X의 어떠한 Attribute라도 제거하면 더 이상 함수적 종속성이 성립하지 않는 경우를 말합니다. 즉, 테이블에서 기본키가 복합키(키1,키2)로 묶여 있을 때 두 키 중 하나의 키만으로 다른 컬럼을 결정지을 수 있으면 안됩니다.
- 제3정규화(3NF): 2NF가 진행된 테이블에서 이행적 종속을 없애기 위해 테이블을 분리하는 것입니다. (이행적 종속? A->B 이고 B->C이면 A->C) 릴레이션이 2NF에 만족되면서 기본 키가 아닌 속성은 기본 키에 의존해야 한다는 두 조건이 있습니다.
Denormalization는 정규화의 단점인 릴레이션간의 연산(Join 연산)이 많아져 응답시간이 느려질 수 있다는 점을 대응하기 위한 것입니다.
정규화된 엔티티, 속성, 관계를 시스템의 성능 향상 및 개발과 운영의 단순화를 위해 중복 통합, 분리 등을 수행하는 데이터 기법입니다. 다음의 경우에는 비정규화를 고려해볼 수 있습니다.
1. 자주 사용되는 테이블에 접근하는 프로세스 수가 가장 많고 항상 일정 범위만을 조회하는 경우
2. 테이블에 대량의 데이터가 있고 이를 자주 처리해 성능 상 이슈가 발생하는 경우
3. 테이블에 지나치게 조인을 많이 사용해 데이터 조회가 기술적으로 어려울 경우
Elastic Search
Q) Elastic Search에 대해서 간단히 설명해주세요.
Elastic Search는 Apache Lucene 기반의 Java 오픈소스 분산 검색 엔진입니다. 텍스트, 숫자, 위치 기반 정보, 정형 및 비정형 데이터 등 모든 유형의 데이터를 검색, 분석할 수 있습니다. 분산형 및 개방형을 특징으로 합니다.
Q) Elastic Search의 인덱스구조와 RDBMS의 인덱스 구조의 차이에 대해 설명해주세요.
출처
Q) Elastic Search의 키워드 검색과 RDBMS의 LIKE 검색의 차이에 대해 설명해주세요.
RDBMS에서는 where like '%...%'의 형식으로 데이터 검색이 가능합니다. 그러나 단순 텍스트 매칭에 대한 검색만을 제공하고 특히 한글 검색의 경우 빈약한 편입니다. 또 비정형 데이터의 색인과 검색이 불가능합니다.
반면 ES의 키워드 검색은 텍스트를 여러 단어로 변형하거나 텍스트 특질을 이용한 동의어, 유의어를 활용한 검색이 가능합니다. 또한 비정형 데이터 검색 및 색인이 가능하고, 형태소 분석을 통한 자연어 처리를 할 수 있습니다. 더불어 역색인 지원으로 매우 빠르게 검색할 수 있습니다.
SQL
Q) A라는 테이블이 존재할 때, 새로운 속성(Column)을 추가한다고 할때, 모든 행(row)에 Default값을 넣어주고 싶을때, 어떤 쿼리문을 작성해야할까요?
ALTER TABLE [테이블명] ALTER COLUMN [컬럼명] SET DEFAULT [기본값]
ALTER TABLE ex_table ALTER COLUMN [컬럼명] SET DEFAULT 'Default값';