728x90
# 일대일 관계 만들기(one-to-one)
- @OneToOne 데코레이터를 사용하고, 안에 연결하고 싶은 엔티티를 다음과 같은 형식으로 기재한다. () => <Entity>
- @JoinColumn 데코레이터를 사용해서 관계 설정 시 중심이 되는 엔티티를 표현한다. (Owner side of the relationship)
// photometadata.entity.ts
import {
Column,
Entity,
JoinColumn,
OneToOne,
PrimaryGeneratedColumn,
} from 'typeorm';
import { Photo } from './photo.entity';
@Entity()
export class PhotoMetadata {
@PrimaryGeneratedColumn()
id: number;
@Column('int')
height: number;
@Column('int')
width: number;
@Column()
orientation: string;
@Column()
compressed: boolean;
@Column()
comment: string;
@OneToOne(() => Photo)
@JoinColumn()
photo: Photo;
}
# 관계 반전
- 관계는 단방향, 양방향 가능
- 단방향의 관계에서는 관계의 소유권이 있는 엔티티가 아니라면 데이터에 접근하기가 복잡하다. 이를 해결하기 위해 관계를 양방향으로 만들어 준다
- @OneToOne(() => Photo, (photo) => photo.metadata) 일대일 관계를 양쪽으로 설정
- Photo 엔티티(소유권이 없는 엔티티)에도 @OneToOne 데코레이터 사용하여 양쪽으로 관계 설정 및 metadata 컬럼 명시
- @OneToOne(() => PhotoMetadata, (photoMetadata) => photoMetadata.photo) metadata: PhotoMetadata
//photo.entity.ts
import {
Column,
Entity,
ManyToMany,
ManyToOne,
OneToOne,
PrimaryGeneratedColumn,
} from 'typeorm';
import { PhotoMetadata } from './photometadata.entity';
import { Author } from './author.entity';
import { Album } from './album.entity';
@Entity()
export class Photo {
@PrimaryGeneratedColumn()
id: number;
@Column({ length: 100 })
name: string;
@Column('text')
description: string;
@Column()
filename: string;
@Column('double')
views: number;
@Column()
isPublished: boolean;
@OneToOne(() => PhotoMetadata, (photoMetadata) => photoMetadata.photo, {
cascade: true,
})
metadata: PhotoMetadata;
@ManyToOne(() => Author, (author) => author.photos)
author: Author;
@ManyToMany(() => Album, (album) => album.photos)
albums: Album[];
}
# 오류 발생
- 관계를 설정하며 엔티티의 속성이 없는 상황에서 공식문서에 기재된 관계식을 적으면 에러가 발생한다. 관계를 맺는 엔티티의 양쪽 코드를 모두 완성하면 오류가 사라진다.
- 해당 모듈(photo)과 app모듈에 새로 추가한 엔티티를 반영해준다.



# 다대일, 일대다 관계 만들기 (many-to-one / one-to-many)
작가는 사진을 여러 개 소유할 수 있고, 사진은 작가를 하나만 소유할(할당받을) 수 있다.
//author.entity.ts
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from 'typeorm';
import { Photo } from './photo.entity';
@Entity()
export class Author {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@OneToMany(() => Photo, (photo) => photo.author)
photos: Photo[];
}
#다대다 관계 만들기(many-to-many)
사진을 앨범 여러 개에 속할 수 있고, 앨범도 사진 여러 개를 가질 수 있다.
//album.entity.ts
import {
Column,
Entity,
JoinTable,
ManyToMany,
PrimaryGeneratedColumn,
} from 'typeorm';
import { Photo } from './photo.entity';
@Entity()
export class Album {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@ManyToMany(() => Photo, (photo) => photo.albums)
@JoinTable()
photos: Photo[];
}
#최종적인 테이블 구조

# MySQL 키 종류들
- Primary Key (고유키)
- NOT NULL & UNIQUE
- 테이블 당 하나의 정의만 가질 수 있음
- 여러 개가 PK로 지정되었다면 key 조합에 대한 유일성이 보장됨
- Unique Key
- NULL & UNIQUE
- 테이블 당 여러개 가능
- 복잡한 테이블에서 부분적인 정합성을 살리기 위해 많이 이용됨
- Foreign Key
- 다른 DB와 관계를 맺을 때, 다른 테이블의 PK를 참조하는 컬럼(FK)
- 서버의 안정성을 위해 지양하는 편
- 제약 조건 옵션들(Constraint)
- RESTRICT : FK 관계를 맺고 있는 데이터 ROW 의 변경(UPDATE) 또는 삭제(DELETE) 를 막음
- CASCADE : FK 와 관계를 맺은 상대 PK 를 직접 연결해서 DELETE 또는 UPDATE 시, 상대 Key 값도 삭제 또는 갱신
- SET NULL : 논리적 관계상 부모의 테이블, 즉 참조되는 테이블의 값이 변경 또는 삭제될 때 자식 테이블의 값을 NULL 만들음. UPDATE 쿼리로 인해 SET NULL 이 허용된 경우에만 동작
- NO ACTION : RESTRICT 옵션과 동작이 같지만, 체크를 뒤로 미룸
- SET DEFAULT : 변경 또는 삭제 시에 값을 DEFAULT 값으로 세팅
- Multiple Key
- 중복 가능한 인덱스의 첫 번째 컬럼(보통은 FK, 여러 개의 컬럼을 묶어서 unique index를 구성한 경우)
참고자료
- https://typeorm.io/readme#step-by-step-guide
- https://jins-dev.tistory.com/entry/MySQL-%EC%97%90%EC%84%9C-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-Key-%EC%9D%98-%EC%A0%95%EC%9D%98%EC%99%80-%EC%A2%85%EB%A5%98%EB%93%A4%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC
- https://torbjorn.tistory.com/557
'DB > typeORM' 카테고리의 다른 글
TypeORM 다대다 연결 시 관계테이블 이름 커스텀하기 (0) | 2025.01.18 |
---|---|
엔티티(Entity)란 무엇인가? (0) | 2022.12.10 |
시작하기 - Entity 형성 및 연결(Nest.js & MySQL) (0) | 2022.10.10 |
TypeORM Contents (0) | 2022.10.05 |