devlog_owen
MySQL 배열로 데이터 저장하기 (+nest.js, swagger) 본문
문제상황
Gallery 엔티티에서 photo 컬럼을 다중파일 업로드를 해야한다.
하지만 MySQL과 같은 관계형 데이터베이스(RDBMS)는 일반적으로 배열을 데이터로 받을 수 없다.
그 이유는 정규화(Normalization) 때문이다.
RDBMS는 데이터를 정규화하여 중복을 최소화하려는 경향이 있다. 각 열은 단일 값을 포함하며 배열과 같은 중첩된 구조는 데이터 정규화의 원칙에 어긋난다.
해결방안
1. Photo 엔티티 추가
테이블을 분리(정규화)하는 것이 가장 정석적인 방법이라고 한다. DB에서 배열을 그대로 하나의 레코드에 저장하는 것은 제 1정규형에 위반되므로 기본적으로 RDBMS에서 제한한다.
따로 Gallery 이미지를 저장하는 테이블을 맞들고 relation 걸고 갤러리 조회할 때 조인을 해서 가져오는것이 정석이다.
2. 배열 자료형을 문자열로 변환해 저장
1번의 방법대로 하기에는 단순히 갤러리의 이미지는 갤러리와만 연결되어 있기때문에 굳이 테이블을 추가해서 DB의 성능을 떨어뜨리는 것보다 역정규화를 통해 단순히 배열 그대로 테이블에 집어 넣는 방식을 선택했다.
구현방식
//갤러리 등록
//gallery.controller.ts
@ApiBearerAuth('accessToken')
@ApiConsumes('multipart/form-data')
@ApiBody({
description: 'Upload gallery with image.',
type: 'multipart/form-data',
schema: {
type: 'object',
properties: {
files: {
type: 'array',
items: {
type: 'string',
format: 'binary',
description: 'The image files to upload.',
},
},
content: {
type: 'string',
description: 'The content of the gallery.',
},
date: {
type: 'date',
description: 'date of the gallery.',
},
},
},
})
@Post()
@UseInterceptors(FilesInterceptor('files', 5))
@UseGuards(accessTokenGuard)
async addgallery(
@Body() createGalleryDto: CreateGalleryDto,
@UserId() userId: number,
@UploadedFiles() files: Express.Multer.File[],
) {
const urls = await Promise.all(
files.map(async (file) => await this.galleryService.imageUpload(file)),
);
return await this.galleryService.addgallery(createGalleryDto, userId, urls);
}
@UseInterceptors(FilesInterceptor('files', 5)) :
클라이언트로부터 전송된 파일들을 처리하기위한 인터셉터. 여기서 files는 배열이고 5는 최대파일의 갯수.
@UploadedFiles() files: Express.Multer.File[],:
FilesInterceptor를 사용하기 위해 적용됨.
//갤러리 등록
//gallery.service.ts
async addgallery(
createGalleryDto: CreateGalleryDto,
userId: number,
urls: string[],
) {
const user = await this.userService.findUserById(userId);
if (user.role !== 1) {
throw new BadRequestException('관리자만 등록이 가능합니다.');
}
const gallery = await this.galleryRepository.save({
...createGalleryDto,
photos: JSON.stringify(urls),
user: user,
});
return gallery;
}
여기서 JSON.stringify를 통해 문자열로 변환시켜 저장한다.
결과
배열로 잘 들어간다!!
'TIL' 카테고리의 다른 글
주석 안먹힐때(ctrl+/ 안먹힐때) (0) | 2024.07.10 |
---|---|
파이썬의 f-string(f-문자열) 기능 (0) | 2024.07.09 |
[TIL] Redis maxmemory 설정, LRU 캐시전략 설정하기 (0) | 2024.01.29 |
[TIL]Nest can't resolve dependencies of the StorebookService 오류 해결 (0) | 2024.01.22 |
[TIL] .env 파일이 gitignore에 있는데도 푸시될때 해결법 (0) | 2024.01.19 |