이제 데이터베이스 schema를 정의해보려고 한다.
오 근데 이 글 미리 써두고 나중에서야 수정하게 됐는데,
MySQL workbench에 기존에 코드로 작성해두었던 모델을 E-R Diagram으로 표현해주는 기능이 있더라...!
개꿀이네...
일단 프로젝트 이미 완성된 시점(2022-11-11)에 글을 수정하고 있는데,
전반적인 전체 DB의 다이어그램은 아래 그림과 같다.
여기서는 일단 가장 기본이 되는 User, Event, Comment 정도만 작성해두고 점점 확장해 나아갔다.
import {BaseEntity, Column, CreateDateColumn, Entity, OneToMany, PrimaryGeneratedColumn} from 'typeorm';
import Event from './Event';
import Comment from './Comment';
/**
* 사용자!
*/
@Entity()
export class User extends BaseEntity {
@PrimaryGeneratedColumn({comment: '식별자.'})
id: number;
@Column({comment: '가입한 이메일.'})
email: string;
@Column({comment: '사용자 닉네임.'})
nickname: string;
@Column({comment: '로그인한 방법(카카오, 구글 등).'})
oauthProvider: string;
@Column({comment: 'OAuth로 로그인한 경우, provider가 제공한 식별자.'})
oauthId: string;
@CreateDateColumn({comment: '생성 일시.'})
createdAt: Date;
// User 1 : Event N
@OneToMany(() => Event, (e) => e.user)
events: Event[];
// User 1 : Comment N
@OneToMany(() => Comment, (c) => c.user)
comments: Comment[];
}
소셜 로그인(구글, 애플 등)을 사용할 계획이라 OauthProvider에 따라서도 구분해주었음.
User 1명에 대해 Event N개가 매핑되는 관계이므로 OneToMany
를 작성한다.
Comment 도 마찬가지로 1:N관계
import {BaseEntity, Column, CreateDateColumn, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn} from 'typeorm';
import {User} from './User';
import {JoinColumn} from 'typeorm';
import Comment from './Comment';
@Entity()
export default class Event extends BaseEntity {
@PrimaryGeneratedColumn({comment: '식별자.'})
id: number;
@ManyToOne(() => User, (u) => u.events)
@JoinColumn()
user: User;
@Column({comment: '단체.'})
host: string;
@Column({comment: '분류.'})
category: string;
@Column({comment: '제목.'})
title: string;
@Column({comment: '본문.'})
body: string;
@Column({comment: '이미지 식별자.'})
imageUuid: string;
@Column({nullable: true, comment: '행사 시작 일시.'})
startAt?: Date;
@Column({nullable: true, comment: '행사 종료 일시.'})
endAt?: Date;
@CreateDateColumn({comment: '생성 일시.'})
createdAt: Date;
// Event 1 : Comment N
@OneToMany(() => Comment, (c) => c.event)
comments: Comment[];
}
Event에는 대표 이미지가 하나 씩 올라가게 된다.
이미지를 업로드 할 때 uuid를 임의로 생성하여 파일을 보관하게 되고,
이벤트에 들어가는 이미지 필드에는 uuid값만 들어가게 된다.
import {BaseEntity, Column, CreateDateColumn, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn} from 'typeorm';
import Event from './Event';
import {User} from './User';
@Entity()
export default class Comment extends BaseEntity {
@PrimaryGeneratedColumn({comment: '식별자.'})
id: number;
@ManyToOne(() => User, (u) => u.comments)
@JoinColumn()
user: User;
@ManyToOne(() => Event, (e) => e.comments)
@JoinColumn()
event: Event;
@Column()
content: string;
@CreateDateColumn({comment: '생성 일시.'})
createdAt: Date;
}
댓글에는 댓글을 작성한 User 테이블, 그 댓글이 소속된 Event 가 들어가고
댓글 내용인 contest 가 string으로 들어가있다.
댓글 달기를 요청하면 createAt에 요청 시각을 자동으로 넣어준다.
src/index.ts
import 'reflect-metadata';
import 'dotenv/config';
import {createConnection} from 'typeorm';
async function run() {
const connection = await createConnection();
await connection.synchronize(true);
console.log('ㅎㅎ');
}
run().then().catch((e) => console.log(e));
서버 시작
$ npm run start
MySQL 들어가서 직접 확인해보니 table이 잘 생성되었다.