이 프로젝트는 각 분야 별로 흩어진 포트폴리오 및 작업물을 하나의 플랫폼으로 관리하고, 협업을 촉진하는 웹 서비스입니다.
-
주요 기능: 포트폴리오, 채팅, 멘토링 -
인원: 개발 3인 -
기간- 설계 기간: 2024.01.02 ~ 2024.03.01
- 개발 기간: 2024.03.02 ~ 2024.06.19
역할: 팀장주요 기여- 로그인 및 회원 가입: 암호화, 유효성 처리, 메일 인증, session인증 방식, 이메일 및 유저 아이디 중복 방지
- 포트폴리오 파트: 검색, 인기 유저 갱신, 조회 수 중복 방지, 페이징, 방문 기록, 좋아요 기능 등
- CI/CD: 무중단 배포 구축
- 백오피스: 관리자 기능, 사용자 제재(로그인 차단), 저작권 신고
- hasRole 4권한(USER, MENTO, ADMIN, BAN)
- 사용자 페이지: 팔로우 및 팔로잉
- ERD 설계
- 포트폴리오, 멘토링
- 문서화 작업(UML- 유스케이스, DB 테이블 명세서, 화면설계서)
- 일정관리 (WBS)
- 모니터링 추가
약 10만개의 테스트 데이터 추가
- 기존: 페이징 시 전체 데이터 검색으로 인해 레이턴시 발생
- 개선: 페이징에 필요한 20개의 데이터만 불러오도록 코드 수정
EXPLAIN ANALYZE를 활용하여 코드 실행 계획 확인- FullText Index 적용
- JMeter를 활용한 부하 테스트 진행
- 최적화 전후 성능 비교 → 검색 성능 16.5% 향상
- 조회의 경우 트랜잭션 제거
- 업데이트 연관 작업 시 트랜잭션 추가
Portfolios테이블에서Title을 검색할 때LIKE CONCAT('%', #{searchQuery}, '%')사용.EXPLAIN결과, 인넷을 효과적으로 활용하지 못하고Using where; Using temporary; Using filesort발생.
CREATE FULLTEXT INDEX idx_title ON Portfolios(Title);✅ 기존 LIKE 검색 대시 MATCH(Title) AGAINST(...) 활용하여 성능 개선
- 10만 개 데이터 기준
- 10개 스레드 동시 실행, 10회 복잡 측정
EXPLAIN확인 및 실제 DB 응답 시간 측정
| 테스트 | 평균 실행 시간 (ms) | 개선 |
|---|---|---|
기존 코드 (LIKE) |
113ms | - |
개선 코드 (FULLTEXT INDEX) |
95ms | 16.5% |
- 기존 코드:
Using index condition; Using where; Using temporary; Using filesort - 개선 코드:
Using where; Using filesort,type=fulltext,key=idx_title활용
FULLTEXT INDEX적용으로 검색 속도 약 16.5% 향상- 페이징 최적화로 전체 데이터 검색 문제 해결
- 트랜잭션 제거 및 변경으로 불필요한 오버헤드 감소 및 데이터 정확성 유지
통합 포트폴리오 웹 서비스
![]() |
![]() |
|---|---|
| 메인 홈 | 검색 기능 |
![]() |
![]() |
| 결제 시스템 | 멘토 인증 |
![]() |
![]() |
| 멘토 등록 | 무중단 배포 |
![]() |
![]() |
| 사용자 제재 | 어드민 페이지 |
![]() |
![]() |
| 채팅 기능 | 챗봇 시스템 |
![]() |
![]() |
| 포트폴리오 관리 | 포트폴리오 기능 |
![]() |
![]() |
| 프로필 수정 | 회원가입 |
-
application.yml 파일을 src/main/resources에 생성
server: port: 8080 spring: datasource: driver-class-name: org.mariadb.jdbc.Driver url: /* */ username: /* */ password: /* */ servlet: multipart: #file upload size max-file-size: 20MB max-request-size: 20MB mail: host: /* */ port: /* */ username: /* */ password: /* */ properties: mail: smtp: auth: true starttls: enable: true # required: true # connectiontimeout: 5000 # timeout: 5000 # writetimeout: 5000 # auth-code-expiration-millis: 300000 #Colud S3 cloud: aws: s3: bucket: /* */ stack.auto: false region.static: ap-northeast-2 credentials: accessKey: /* */ secretKey: /* */ # mybatis mybatis: mapper-locations: classpath:mapper/*.xml config-location: classpath:mybatis-config.xml #iamport imp: code: /* */ api: key: /* */ secretkey: /* */ chatGpt: key: /* */ management: server: port: 9292 endpoint: health: show-details: always endpoints: web: base-path: /actuator exposure: include: "*" -
Database
CREATE TABLE `Categories` ( `CategoryID` int(11) NOT NULL AUTO_INCREMENT, `CategoryName` varchar(255) NOT NULL, PRIMARY KEY (`CategoryID`) ) CREATE TABLE `CopyrightReport` ( `ReportID` int(11) NOT NULL AUTO_INCREMENT, `PortfolioID` int(11) NOT NULL, `Contents` text NOT NULL, `ReporterEmail` varchar(255) NOT NULL, `ReportedID` int(11) NOT NULL, `ReportState` tinyint(1) NOT NULL DEFAULT 0, PRIMARY KEY (`ReportID`) ) CREATE TABLE `Follows` ( `FollowerID` int(11) NOT NULL, `FollowingID` int(11) NOT NULL, PRIMARY KEY (`FollowerID`,`FollowingID`) ) CREATE TABLE `Mento` ( `MentoID` int(11) NOT NULL AUTO_INCREMENT, `UserID` int(11) NOT NULL, `Introduction` text DEFAULT NULL, `Ability` varchar(255) DEFAULT NULL, `CompanyName` varchar(255) DEFAULT NULL, `CareerCertification` longtext DEFAULT NULL, `UnivName` varchar(255) DEFAULT NULL, `UnivCertification` longtext DEFAULT NULL, `CertificationName` varchar(255) DEFAULT NULL, `IssueCertification` longtext DEFAULT NULL, `credit` int(11) DEFAULT 0, PRIMARY KEY (`MentoID`) ) CREATE TABLE `MentoFile` ( `MentoFileID` int(11) NOT NULL AUTO_INCREMENT, `ActivityID` int(11) NOT NULL, `File_url` varchar(255) DEFAULT NULL, `contents` text DEFAULT NULL, PRIMARY KEY (`MentoFileID`) ) CREATE TABLE `MentoProcess` ( `ProcessID` int(11) NOT NULL AUTO_INCREMENT, `MentoID` int(11) NOT NULL, `Process` varchar(1) NOT NULL, PRIMARY KEY (`ProcessID`) ) CREATE TABLE `Mentoring` ( `MentoringID` int(11) NOT NULL AUTO_INCREMENT, `MentoID` int(11) NOT NULL, `CategoryID` int(11) DEFAULT NULL, `Title` varchar(255) DEFAULT NULL, `Content` text DEFAULT NULL, `Price` decimal(10,2) DEFAULT NULL, `Thumbnail` varchar(255) DEFAULT NULL, `file_urls` longtext DEFAULT NULL, `mentoring_delete` int(11) DEFAULT 0, PRIMARY KEY (`MentoringID`) ) CREATE TABLE `MentoringOrder` ( `OrderID` int(11) NOT NULL AUTO_INCREMENT, `pg` varchar(50) NOT NULL, `pay_method` varchar(50) NOT NULL, `merchant_uid` text DEFAULT NULL, `goods_id` int(11) NOT NULL, `pay_name` longtext NOT NULL, `amount` int(11) NOT NULL, `buyer_email` varchar(50) NOT NULL, `buyer_name` varchar(50) NOT NULL, PRIMARY KEY (`OrderID`) ) CREATE TABLE `PopularUser` ( `PopularID` int(11) NOT NULL AUTO_INCREMENT, `UserID` int(11) NOT NULL, `UserName` varchar(255) NOT NULL, `Email` varchar(255) NOT NULL, `ProfileImage` longtext DEFAULT NULL, `aff` longtext DEFAULT NULL, PRIMARY KEY (`PopularID`) ) CREATE TABLE `PortfolioLikes` ( `PortfolioLikesID` int(11) NOT NULL AUTO_INCREMENT, `PortfolioID` int(11) NOT NULL, `Email` varchar(255) NOT NULL, `Heart_Check` tinyint(1) NOT NULL DEFAULT 0, PRIMARY KEY (`PortfolioLikesID`) ) CREATE TABLE `Usermeta` ( `MetaID` int(11) NOT NULL AUTO_INCREMENT, `UserID` int(11) NOT NULL, `intro` longtext DEFAULT NULL, `aff` longtext DEFAULT NULL, `link` longtext DEFAULT NULL, `career` longtext DEFAULT NULL, PRIMARY KEY (`MetaID`) ) CREATE TABLE `Users` ( `UserID` int(11) NOT NULL AUTO_INCREMENT, `UserName` varchar(255) NOT NULL, `Email` varchar(255) NOT NULL, `PasswordHash` varbinary(255) NOT NULL, `ProfileImage` longtext DEFAULT NULL, `RegistrationDate` datetime NOT NULL, `AdditionalInfo` text DEFAULT NULL, `Role` text DEFAULT 0, `backImage` longtext DEFAULT NULL, `PaidProduct` longtext DEFAULT NULL, PRIMARY KEY (`UserID`), UNIQUE KEY `Email` (`Email`) ) CREATE TABLE `Chats` ( `ChatID` int(11) NOT NULL AUTO_INCREMENT, `SenderID` int(11) NOT NULL, `ReceiverID` int(11) NOT NULL, `Content` text NOT NULL, `DateTime` datetime NOT NULL, `SessionID` varchar(64) DEFAULT NULL, PRIMARY KEY (`ChatID`), KEY `SenderID` (`SenderID`), KEY `ReceiverID` (`ReceiverID`), KEY `fk_ChatSessions` (`SessionID`), CONSTRAINT `Chats_ibfk_1` FOREIGN KEY (`SenderID`) REFERENCES `Users` (`UserID`), CONSTRAINT `Chats_ibfk_2` FOREIGN KEY (`ReceiverID`) REFERENCES `Users` (`UserID`) ) CREATE TABLE `Payments` ( `PaymentID` int(11) NOT NULL AUTO_INCREMENT, `PayerID` int(11) NOT NULL, `PayeeID` int(11) NOT NULL, `PaymentDate` datetime NOT NULL, `Amount` decimal(10,2) NOT NULL, `PaymentStatus` varchar(255) NOT NULL, PRIMARY KEY (`PaymentID`), KEY `PayerID` (`PayerID`), KEY `PayeeID` (`PayeeID`), CONSTRAINT `Payments_ibfk_1` FOREIGN KEY (`PayerID`) REFERENCES `Users` (`UserID`), CONSTRAINT `Payments_ibfk_2` FOREIGN KEY (`PayeeID`) REFERENCES `Users` (`UserID`) ) CREATE TABLE `Portfolios` ( `PortfolioID` int(11) NOT NULL AUTO_INCREMENT, `AuthorID` int(11) NOT NULL, `Thumbnail_url` varchar(255) DEFAULT NULL, `Title` varchar(255) NOT NULL, `Hearts_count` int(11) DEFAULT NULL, `Views_count` int(11) DEFAULT NULL, `CreationDate` datetime NOT NULL, `CategoryID` int(11) DEFAULT NULL, `AttachmentsOrLinks` text DEFAULT NULL, PRIMARY KEY (`PortfolioID`), KEY `AuthorID` (`AuthorID`), KEY `CategoryID` (`CategoryID`), CONSTRAINT `Portfolios_ibfk_1` FOREIGN KEY (`AuthorID`) REFERENCES `Users` (`UserID`), CONSTRAINT `Portfolios_ibfk_2` FOREIGN KEY (`CategoryID`) REFERENCES `Categories` (`CategoryID`) ) CREATE TABLE `SessionParticipants` ( `SessionKey` varchar(64) NOT NULL, `UserID` int(11) NOT NULL, PRIMARY KEY (`SessionKey`,`UserID`), KEY `UserID` (`UserID`), KEY `idx_SessionParticipants_SessionKey` (`SessionKey`), CONSTRAINT `SessionParticipants_ibfk_1` FOREIGN KEY (`UserID`) REFERENCES `Users` (`UserID`) ) CREATE TABLE `Images` ( `ImageID` int(11) NOT NULL AUTO_INCREMENT, `PortfolioID` int(11) DEFAULT NULL, `Image_url` varchar(255) DEFAULT NULL, `contents` mediumtext DEFAULT NULL, PRIMARY KEY (`ImageID`), KEY `PortfolioID` (`PortfolioID`), CONSTRAINT `Images_ibfk_1` FOREIGN KEY (`PortfolioID`) REFERENCES `Portfolios` (`PortfolioID`) ) CREATE TABLE `PortfolioTags` ( `TagID` int(11) NOT NULL AUTO_INCREMENT, `PortfolioID` int(11) NOT NULL, `TagName` varchar(255) NOT NULL, PRIMARY KEY (`TagID`), KEY `PortfolioID` (`PortfolioID`), CONSTRAINT `PortfolioTags_ibfk_1` FOREIGN KEY (`PortfolioID`) REFERENCES `Portfolios` (`PortfolioID`) )

















