
트리거(Trigger)는 특정 테이블에 INSERT, DELETE, UPDATE 같은 DML 문이 수행되었을 때, 데이터베이스에서 자동으로 동작하도록 작성된 프로그램 ▶︎ 사용자가 직접 호출하는 것이 아니라, 데이터베이스에서 자동적으로 호출하는 것이 가장 큰 특징
🎈요즘은 Trigger를 DB에서 직접 적용하기보다는 가급적이면 Javascript단에서 적용하는 편
인덱스(= 책갈피)는 테이블을 빨리 조회하기 위해 테이블 데이터에 포인터를 주는 검색 방법
- 옵티마이저: 검색을 효율적으로 해주는 DB 내장기능
- 실행계획: 효율적인 검색 계획
- Explain 명령어: 옵티마이저가 결정한 실행결과를 볼 수 있는 명령어
주의!‼️ 빠른 검색을 위해 모든 컬럼에 인덱스를 적용하게 되면
데이터를 등록, 수정할 때 마다 정렬을 시도하기 때문에 속도가 느려지게됨
따라서, 검색에 자주 사용되는 컬럼에 인덱스를 적용하는 것이 좋음
//dbeaver - Script
# 데이터 개수 조회
select COUNT(*) from board
;
# 쿼리 검색 속도 비교
select *
from board
where title = '0.719410951919305'
;
select *
from board
where number = 36
;
# 옵티마이저로 실행계획 확인
explain
select *
from board
where title = '0.719410951919305'
;
explain
select *
from board
where number = 36
;
# 인덱스 확인
show index from board
;
#인덱스 생성
create index idx_title on board(title)
;
# 옵티마이저로 실행계획 다시 확인
explain
select *
from board
where title = '0.719410951919305'
;
#인뎅싱된 컬럼으로 재쿼리 후, 성능 비교
select *
from board
where title = '0.719410951919305'
;
Feature of Redis
- NoSQL로서 Key-Value 타입의 저장소인
레디스(Redis, Remote Dictionary Server)영속성을 지원하는 인메모리 데이터 저장소읽기 성능 증대를 위한 서버 측 복제를 지원쓰기 성능 증대를 위한 클라이언트 측 샤딩(Sharding) 지원다양한 서비스에서 사용되며 검증된 기술문자열, 리스트, 해시, 셋, 정렬된 셋과 같은 다양한 데이터형을 지원. 메모리 저장소임에도 불구하고 많은 데이터형을 지원하므로 다양한 기능을 구현
1ms 이하의 응답대기시간
1ms 이하의 응답시간을 제공 → 데이터를 메모리에 저장하기 때문에, 디스크 기반의 데이터 베이스보다 빠르게 데이터를 읽을 수 있음
개발의 용이성
문법적으로 사용하기 쉽고, 개발코드 양 또한 적음
데이터 파티셔닝
데이터를 여러 노드에 분산하여 저장 → 수요가 증가할 때 더 많은 데이터를 효과적으로 처리하기 위하여 스케일아웃이 가능
다양한 프로그래밍 언어 지원
자바, 파이썬, C, C++, C#, JavaScript, Node.Js, Ruby, Go 등
멀티스레드를 지원하기 때문에, 멀티프로세스코어를 사용 가능 → 스케일업을 통하여 더욱 많은 작업처리를 할 수 있음
1. 더욱 다양한 데이터 구조
문자열 뿐만 아니라 List, Set, 정렬된 Set, Hash, Bit 배열, hyperloglogs (매우 적은 메모리로 집합의 개수를 추정할 수 있는 방법)을 지원 i.e)Sorted Set을 활용하여 게임유저의 상위랭크 정보 제공 가능
2. Snapshots
레디스는 특정시점에 데이터를 디스크에 저장하여 파일 보관이 가능
또한, 장애 상황시 복구에 사용할 수 있음
3. 복제
Master — Salves 구조로, 여러개의 복제본을 만들 수 있음 → 데이터베이스 읽기를 확장할 수 있기 때문에 높은 가용성(오랜 시간동안 고장나지 않음) 클러스터를 제공
4. 트랜젝션
트렌젝션이란 데이터베이스 상태를 변경시키는 작업 단위를 의미하고, 원자성, 일관성, 독립성, 지속성의 특징을 가지고 있음 → Redis 지원
5. Pub / Sub messaging
Publish(발행)과 Sub(구독)방식의 메시지를 패턴 검색이 가능 →높은 성능을 요구하는 채팅, 실시간 스트리밍, SNS 피드 그리고 서버상호통신에 사용 가능
6. 루아 스크립트 지원
매우 경량화된 절차스크립트 언어인 루아를 지원 → eval 명령어를 사용하여 루아스크립트를 실행시킬 수 있음, 프로그램을 명료하게하고 성능을 높일 수 있음
7. 위치기반 데이터 타입 지원
Redis는 실시간 위치기반데이터를 지원 → 두 위치의 거리를 찾거나, 사이에 있는 요소 찾기등의 작업을 수행할 수 있음 i.e) 맛집, 길찾기 그리고 지도기반의 고성능 서비스를 제공

검색 시 Redis에서 먼저 찾아보고 Redis에 저장된 내용이 있다면 저장된 정보를 바로 보여주고
없다면 MySQL에서 정보를 보여준 다음 검색된 내용을 redis에 저장하는 방식
Cache-Aside패턴를 사용한다면 같은 내용의 2번째 검색부터는 redis에 저장된 정보를 보여주기 때문에 속도가 빨라짐

// app.module.ts
@Module({
imports: [
//
//
//
CacheModule.register<RedisClientOptions>({ // CacheModule.register<CacheModule의 타입 명시>
store: redisStore, //저장 위치
url: 'redis://my-redis:6379', // redis 주소
isGlobal: true,// 모든 API에서 사용가능하게 하는 역할
}),
],
})
// boards.resolver.ts
import { Cache } from 'cache-manager';
import { CACHE_MANAGER, Inject } from '@nestjs/common';
@Resolver()
export class BoardResolver {
constructor(
private readonly boardService: BoardService,
@Inject(CACHE_MANAGER)
private readonly cacheManager: Cache,
) {}
@Mutation(() => String)
async createBoard(
@Args({ name: 'writer', nullable: true }) writer: string,
@Args('title') title: string,
@Args('contents') contents: string,
@Args('createBoardInput') createBoardInput: CreateBoardInput,
) {
// 1. 캐시에 등록하는 연습
await this.cacheManager.set('aaa', createBoardInput, {
ttl: 0,
}); //key-value 형태 저장, ttl : 0 무제한 저장
// 2. 캐시에서 조회하는 연습
const mycache = await this.cacheManager.get('aaa');// get을 통해 저장된 정보 가져옴 (key값)
console.log(mycache);
return '지금은 캐시 테스트 중!!!';
////////////////////////////////////////////////////////
// 레디스 연습을 위해서 잠시 주석걸기!!
// console.log(args);
// console.log(writer);
// console.log(title);
// console.log(contents);
// console.log(createBoardInput);
// return this.boardService.create();
}
set를 통해 redis에 저장get을 통해 redis에 저장된 정보를 가져올 수 있음ttl 을 통해 저장 기간을 지정 가능ttl을 생략한다면 default값은 5초ttl: 0 무제한 저장