전체 글 7

[TypeORM] Bulk Upsert 사용시 주의할 점 (with PostgreSQL)

데이터를 관리하다보면 SELECT한 결과에 따라 데이터를 INSERT할지 UPDATE할지 나뉘는 코드를 작성해야 할 때가 있다. 이를 위해 TypeORM은 save method를 제공한다. save는 SELECT 문을 실행한 후 데이터가 없으면 INSERT, 데이터가 있으면 UPDATE 문을 실행한다. 하지만 save를 한 번 실행할 때 두 개의 쿼리가 실행되므로 비효율적이다. (SELECT + INSERT or SELECT + UPDATE) PostgreSQL에서는 이를 해결하기 위해 ON CONFLICT DO UPDATE 절을 사용할 수 있다. 기본적인 INSERT 문은 데이터 충돌 시 오류가 발생하는데 ON CONFLICT 절과 함께 사용하면 충돌 시 UPDATE를 수행한다. TypeORM에서는 u..

ORM 2024.08.28

[PostgreSQL] Materialized View (with NestJS + TypeORM)

도입 배경약 3천만 건의 데이터 있는 테이블에 대한 통계 자료가 필요해서 쿼리를 실행했더니 너무 오래 걸리는 문제가 발생했다. 가장 먼저 떠오른 방법은 결과를 Cache 해두는 것이었지만 추가적인 Query를 적용하기 어렵다는 생각이 들어 다른 방법을 찾아보았다. 검색을 하던 중 materialized view라는 구체화 뷰에 대해 알게 되었는데 통계 자료를 보여주기에 적합한 기능인 것 같아서 적용해보기로 했다. Materialized View란Materialized View(구체화 뷰)란 쿼리의 결과를 담아두고 있는 테이블이다. 자주 사용되는 쿼리나 비용이 많이 드는 쿼리의 결과를 저장해서 쿼리 속도를 향상시킬 수 있다. 참조 테이블에서 Select한 결과를 저장해두고 사용한다는 관점에서 Cache의 ..

데이터베이스 2024.08.28

[PostgreSQL] Statistics를 활용하여 다중 컬럼 인덱스 제대로 사용하기

들어가며대용량 데이터를 다룰 때 인덱스의 역할은 매우 중요하다. 인덱스를 통해 빠른 데이터 검색이 가능하기 때문이다.인덱스는 한 개 또는 두 개 이상의 컬럼에 복합적으로 설정할 수 있는데, 두 개 이상의 컬럼으로 구성된 인덱스를 다중(복합) 컬럼 인덱스라고 한다.본 글은 다중 컬럼 인덱스를 설계하며 겪은 문제 상황과 이에 대한 해결책을 정리한 글이다.본론에 앞서 PostgreSQL에서의 쿼리 실행 방식과 EXPLAIN 명령어에 대해서 간단히 살펴보자. Planner/OptimizerSQL Query는 다양한 방식으로 실행될 수 있다. (Scan, Join 방식 등) PostgreSQL의 Optimizer는 CBO(Cost Based Optimizer)로 파라미터 및 통계 정보를 바탕으로 이러한 다양한 실..

데이터베이스 2024.08.28

[NestJS] Refactoring (2) - Custom Decorator (with TypeORM)

2024.05.21 - [NestJS] Refactoring (1) - Entity Inheritance (with TypeORM) [NestJS] Refactoring (1) - Entity Inheritance (with TypeORM)TypeORM에서 엔티티들이 공통으로 갖는 컬럼이 있는 경우에는 엔티티 상속을 통해 중복되는 코드를 제거할 수 있다.@Entity('item_consumable')export class ItemConsumable { @PrimaryColumn() code: number; @Column() name: sthjhdev.tistory.com  들어가며NestJS에서 PostgreSQL과 TypeORM으로 데이터를 관리하고 있습니다. 이전 글에서 Entity Inheritan..

2024.05.23

[NestJS] Refactoring (1) - Entity Inheritance (with TypeORM)

TypeORM에서 엔티티들이 공통으로 갖는 컬럼이 있는 경우에는 엔티티 상속을 통해 중복되는 코드를 제거할 수 있다.@Entity('item_consumable')export class ItemConsumable { @PrimaryColumn() code: number; @Column() name: string; @Column({ enum: ItemType, }) itemType: ItemType; @Column({ enum: ItemGrade, }) itemGrade: ItemGrade; @Column() hpRecover: number; ...}@Entity('item_wearable')export class ItemWearable { @PrimaryCo..

2024.05.21

[React] MUI 컴포넌트에 CSS Module 적용하기 (MUI css 적용안될 때)

프로젝트를 진행하던중 Button에 css를 적용하려고 다음과 같이 코드를 짰더니 컴포넌트 자체 스타일이 나중에 적용되어 원하는대로 작동하지 않았다. import styles from '../style/Header.module.css'; import Button from '@mui/material/Button'; 버튼 먼저 시도해본 방법은 @mui/styles에서 제공하는 StylesProvider를 사용하는 것이었는데 여전히 해결되지 않아 공식 문서를 찾아보니 React.StrictMode와 React 18이상부터는 호환이 되지 않는다. import React from 'react'; import ReactDOM from 'react-dom'; import store from './app/store';..

2023.11.21

[Nginx + Express] SSL 적용하기

Let's encrypt라는 기관을 통해 무료로 SSL 인증서를 발급받을 수 있다. 1. SSL 인증서 발급받기 # 설치된 패키지 업데이트 sudo apt-get update # Let's Encrypt 사용을 위한 Certbot 설치 sudo apt-get install python3-certbot-nginx # SSL 인증서 발급 [domain.com]에는 본인의 도메인 주소를 입력 sudo certbot certonly --nginx -d domain.com 인증서가 정상적으로 발급되면 /etc/letsencrypt/live/domain.com 경로에 총 5개의 파일이 생성된다. 1. cert.pem 2. chain.pem 3. fullchain.pem 4. privkey.pem 5. README ..

2023.11.08