Skip to content

Commit

Permalink
MySQL과 mongoDB 성능 비교를 위한 코드 작성 (#193)
Browse files Browse the repository at this point in the history
* chore:  mysql과 mongoDB 성능 비교를 위한 코드 작성

* fix: 통합 테스트 코드 삭제
  • Loading branch information
fru1tworld authored Dec 2, 2024
1 parent afa2e9f commit 05f4fb7
Show file tree
Hide file tree
Showing 10 changed files with 402 additions and 0 deletions.
2 changes: 2 additions & 0 deletions packages/backend/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { getTypeOrmConfig } from './common/config/typeorm.config';
import { NoteModule } from './note/note.module';
import { SpaceModule } from './space/space.module';
import { YjsModule } from './yjs/yjs.module';
import { TestModule } from './test/test.module';

@Module({
imports: [
Expand All @@ -26,6 +27,7 @@ import { YjsModule } from './yjs/yjs.module';
SpaceModule,
YjsModule,
NoteModule,
TestModule,
CollaborativeModule,
],
})
Expand Down
11 changes: 11 additions & 0 deletions packages/backend/src/test/mock/mock.constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export const MOCK_CONFIG = {
ITERATIONS: {
DEFAULT: 1000,
CONCURRENT: 500,
},
TEST_PREFIX: {
SPACE: 'test-space-',
NOTE: 'test-note-',
CONCURRENT: 'concurrent-test-space-',
},
} as const;
21 changes: 21 additions & 0 deletions packages/backend/src/test/mock/note.mock.data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { MockNote } from '../types/performance.types';

export const noteMockData: MockNote[] = [
{
id: 'c1ddbb14-689a-49ac-a2fc-a14aebb1c4ed',
userId: 'test-user-id',
name: 'test-name',
content:
'AoIB+Ia//AoABwDujav1AwAGAQD4hr/8CgAEhPiGv/wKBAPthYyB+Ia//AoFAoT4hr/8CgcG7Iqk7Yq4h+6Nq/UDAAMJcGFyYWdyYXBoBwD4hr/8CgoGAQD4hr/8CgsDgfiGv/wKCgEABIH4hr/8Cg8BgfiGv/wKDgKE+Ia//AoWA+yXhIH4hr/8ChcChPiGv/wKGQPssq2B+Ia//AoaA4T4hr/8Ch0H64KY6rKMIIH4hr/8CiAChPiGv/wKIgTquLQggfiGv/wKJASE+Ia//AooA+usuIH4hr/8CikChPiGv/wKKwPsnpCB+Ia//AosAYT4hr/8Ci0D7Je0gfiGv/wKLgGE+Ia//AovA...', // Base64 encoded content
createdAt: new Date(),
updatedAt: new Date(),
},
{
id: 'a4ac29f1-0504-43f4-b087-f47cf99b8186',
userId: 'test-user-id',
name: 'test-name',
content: 'Different base64 encoded content...',
createdAt: new Date(),
updatedAt: new Date(),
},
];
39 changes: 39 additions & 0 deletions packages/backend/src/test/mock/space.mock.data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { MockSpace } from '../types/performance.types';

export const spaceMockData: MockSpace[] = [
{
id: '69bd78b6-0755-4370-be44-3ab0adab011a',
userId: 'test-user-id',
name: 'test',
edges: JSON.stringify({
u7c2xras28c: {
from: '69bd78b6-0755-4370-be44-3ab0adab011a',
to: '65ol60chol8',
},
an5uhqliqpm: {
from: '69bd78b6-0755-4370-be44-3ab0adab011a',
to: 'ousnj3faubc',
},
}),
nodes: JSON.stringify({
'69bd78b6-0755-4370-be44-3ab0adab011a': {
id: '69bd78b6-0755-4370-be44-3ab0adab011a',
x: 0,
y: 0,
type: 'head',
name: 'test space',
src: '69bd78b6-0755-4370-be44-3ab0adab011a',
},
'65ol60chol8': {
id: '65ol60chol8',
type: 'note',
x: 283.50182393227146,
y: -132.99774870089817,
name: 'note',
src: 'c1ddbb14-689a-49ac-a2fc-a14aebb1c4ed',
},
}),
createdAt: new Date(),
updatedAt: new Date(),
},
];
28 changes: 28 additions & 0 deletions packages/backend/src/test/note.test.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import {
Entity,
Column,
PrimaryGeneratedColumn,
CreateDateColumn,
UpdateDateColumn,
} from 'typeorm';

@Entity('notes')
export class Note {
@PrimaryGeneratedColumn('uuid')
id: string;

@Column({ type: 'varchar', length: 255, nullable: false })
userId: string;

@Column({ type: 'varchar', length: 255, nullable: false })
name: string;

@Column({ type: 'text', nullable: true, default: null })
content: string | null;

@CreateDateColumn({ type: 'timestamp' })
createdAt: Date;

@UpdateDateColumn({ type: 'timestamp' })
updatedAt: Date;
}
36 changes: 36 additions & 0 deletions packages/backend/src/test/space.test.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import {
Entity,
Column,
PrimaryGeneratedColumn,
CreateDateColumn,
UpdateDateColumn,
Index,
} from 'typeorm';

@Entity('spaces')
export class Space {
@PrimaryGeneratedColumn('uuid')
id: string;

@Column({ type: 'varchar', length: 255, nullable: true, default: null })
@Index()
parentSpaceId: string | null;

@Column({ type: 'varchar', length: 255, nullable: false })
userId: string;

@Column({ type: 'varchar', length: 255, nullable: false })
name: string;

@Column({ type: 'text', nullable: false })
edges: string;

@Column({ type: 'text', nullable: false })
nodes: string;

@CreateDateColumn({ type: 'timestamp' })
createdAt: Date;

@UpdateDateColumn({ type: 'timestamp' })
updatedAt: Date;
}
159 changes: 159 additions & 0 deletions packages/backend/src/test/test.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import { Controller, Get, Logger } from '@nestjs/common';
import { TestService } from './test.service';
import { spaceMockData } from './mock/space.mock.data';
import { noteMockData } from './mock/note.mock.data';

interface PerformanceResult {
mysqlDuration: number;
mongoDuration: number;
difference: number;
}

@Controller('test')
export class TestController {
private readonly logger = new Logger(TestController.name);

constructor(private readonly testService: TestService) {}

@Get('read/space')
async testSpaceReadPerformance() {
this.logger.log('Testing read performance for Space.');
const iterations = 1000;

const mysqlStartTime = process.hrtime();
for (let i = 0; i < iterations; i++) {
await this.testService.findSpaceByIdSQL(spaceMockData[0].id);
}
const mysqlEndTime = process.hrtime(mysqlStartTime);
const mysqlDuration = (mysqlEndTime[0] * 1e9 + mysqlEndTime[1]) / 1e6;

const mongoStartTime = process.hrtime();

for (let i = 0; i < iterations; i++) {
await this.testService.findSpaceByIdMongo(spaceMockData[0].id);
}

const mongoEndTime = process.hrtime(mongoStartTime);
const mongoDuration = (mongoEndTime[0] * 1e9 + mongoEndTime[1]) / 1e6;

this.logger.log('Read performance test for Space completed.', {
mysqlDuration,
mongoDuration,
difference: Math.abs(mysqlDuration - mongoDuration),
});

return {
mysqlDuration,
mongoDuration,
difference: Math.abs(mysqlDuration - mongoDuration),
};
}

@Get('read/note')
async testNoteReadPerformance() {
this.logger.log('Testing read performance for Note.');
const iterations = 1000;

const mysqlStartTime = process.hrtime();
for (let i = 0; i < iterations; i++) {
await this.testService.findNoteByIdSQL(noteMockData[0].id);
}
const mysqlEndTime = process.hrtime(mysqlStartTime);
const mysqlDuration = (mysqlEndTime[0] * 1e9 + mysqlEndTime[1]) / 1e6;

const mongoStartTime = process.hrtime();
for (let i = 0; i < iterations; i++) {
await this.testService.findNoteByIdMongo(noteMockData[0].id);
}
const mongoEndTime = process.hrtime(mongoStartTime);
const mongoDuration = (mongoEndTime[0] * 1e9 + mongoEndTime[1]) / 1e6;

this.logger.log('Read performance test for Note completed.', {
mysqlDuration,
mongoDuration,
difference: Math.abs(mysqlDuration - mongoDuration),
});

return {
mysqlDuration,
mongoDuration,
difference: Math.abs(mysqlDuration - mongoDuration),
};
}

@Get('write/space')
async testSpaceWritePerformance() {
this.logger.log('Testing write performance for Space.');
const iterations = 1000;
const testData = Array(iterations)
.fill(null)
.map((_, index) => ({
...spaceMockData[0],
id: `test-space-${index}`,
}));

const mysqlStartTime = process.hrtime();
for (const data of testData) {
await this.testService.createSpaceSQL(data);
}
const mysqlEndTime = process.hrtime(mysqlStartTime);
const mysqlDuration = (mysqlEndTime[0] * 1e9 + mysqlEndTime[1]) / 1e6;

const mongoStartTime = process.hrtime();
for (const data of testData) {
await this.testService.createSpaceMongo(data);
}
const mongoEndTime = process.hrtime(mongoStartTime);
const mongoDuration = (mongoEndTime[0] * 1e9 + mongoEndTime[1]) / 1e6;

this.logger.log('Write performance test for Space completed.', {
mysqlDuration,
mongoDuration,
difference: Math.abs(mysqlDuration - mongoDuration),
});

return {
mysqlDuration,
mongoDuration,
difference: Math.abs(mysqlDuration - mongoDuration),
};
}

@Get('write/note')
async testNoteWritePerformance() {
this.logger.log('Testing write performance for Note.');
const iterations = 1000;
const testData = Array(iterations)
.fill(null)
.map((_, index) => ({
...noteMockData[0],
id: `test-note-${index}`,
}));

const mysqlStartTime = process.hrtime();
for (const data of testData) {
await this.testService.createNoteSQL(data);
}
const mysqlEndTime = process.hrtime(mysqlStartTime);
const mysqlDuration = (mysqlEndTime[0] * 1e9 + mysqlEndTime[1]) / 1e6;

const mongoStartTime = process.hrtime();
for (const data of testData) {
await this.testService.createNoteMongo(data);
}
const mongoEndTime = process.hrtime(mongoStartTime);
const mongoDuration = (mongoEndTime[0] * 1e9 + mongoEndTime[1]) / 1e6;

this.logger.log('Write performance test for Note completed.', {
mysqlDuration,
mongoDuration,
difference: Math.abs(mysqlDuration - mongoDuration),
});

return {
mysqlDuration,
mongoDuration,
difference: Math.abs(mysqlDuration - mongoDuration),
};
}
}
23 changes: 23 additions & 0 deletions packages/backend/src/test/test.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { MongooseModule } from '@nestjs/mongoose';
import { TestController } from './test.controller';
import { TestService } from './test.service';
import { Space as SpaceEntity } from './space.test.entity';
import { Note as NoteEntity } from './note.test.entity';
import { SpaceDocument, SpaceSchema } from 'src/space/space.schema';
import { NoteDocument, NoteSchema } from 'src/note/note.schema';

@Module({
imports: [
TypeOrmModule.forFeature([SpaceEntity, NoteEntity]),
MongooseModule.forFeature([
{ name: SpaceDocument.name, schema: SpaceSchema },
{ name: NoteDocument.name, schema: NoteSchema },
]),
],
controllers: [TestController],
providers: [TestService],
exports: [TestService],
})
export class TestModule {}
59 changes: 59 additions & 0 deletions packages/backend/src/test/test.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { Space as SpaceEntity } from './space.test.entity';
import { Note as NoteEntity } from './note.test.entity';
import { SpaceDocument } from 'src/space/space.schema';
import { NoteDocument } from 'src/note/note.schema';

@Injectable()
export class TestService {
constructor(
@InjectRepository(SpaceEntity)
private spaceRepository: Repository<SpaceEntity>,
@InjectRepository(NoteEntity)
private noteRepository: Repository<NoteEntity>,
@InjectModel(SpaceDocument.name)
private spaceModel: Model<SpaceDocument>,
@InjectModel(NoteDocument.name)
private noteModel: Model<NoteDocument>,
) {}

async findSpaceByIdSQL(id: string) {
return this.spaceRepository.findOne({ where: { id } });
}

async findNoteByIdSQL(id: string) {
return this.noteRepository.findOne({ where: { id } });
}

async createSpaceSQL(data: any) {
const space = this.spaceRepository.create(data);
return this.spaceRepository.save(space);
}

async createNoteSQL(data: any) {
const note = this.noteRepository.create(data);
return this.noteRepository.save(note);
}

async findSpaceByIdMongo(id: string) {
return this.spaceModel.findOne({ id }).exec();
}

async findNoteByIdMongo(id: string) {
return this.noteModel.findOne({ id }).exec();
}

async createSpaceMongo(data: any) {
const space = new this.spaceModel(data);
return space.save();
}

async createNoteMongo(data: any) {
const note = new this.noteModel(data);
return note.save();
}
}
Loading

0 comments on commit 05f4fb7

Please sign in to comment.