Procedure 를 통해 방대한 양의 데이터를 핸들링했던 과정에 대해 정리하고자 합니다.
Stored
(저장) + Procedure
(절차) = 일련의 절차를 정리해서 저장한 것
일련의 SQL문장을 선언해서 MySQL에 저장하고, 해당 SQL문을 함수처럼 사용하는 것이다.
사전에 준비 한 많은 명령을 함수처럼 호출하여 자동으로 실행할 수 있기 때문에, 작업의 효율성을 높일 수 있다.
단, 제대로 검증되지 않은 저장 프로시저를 실행하는 것은 매우 위험하므로 주의해야한다.
다만, 처리성능과 유지보수, 재사용면에서 좋지 않다는 점은 유의해야한다.
서비스의 데이터들을 추가하는 과정에서 방대한 양의 데이터를 어떻게 핸들링 할 수 있을지 고민하게 되었다.
이때 방대한 양의 데이터를 일련의 일정한 규칙을 따라 insert
하기 위해서,
MySQL에도 for, while 문 등 여러가지 연산을 가능하게 해주는 문법이 있다는 것을 알게 되어 프로시저를 사용하게 되었다.
그리고 프로시저를 사용하여 데이터를 직접 하나하나 insert하지 않고도 (발생할 수 있는 휴먼에러들을 방지하며) 안전하고 편리하게 핸들링할 수 있었다.
(1) 작성한 프로시저 코드
delimiter $$
drop procedure if exists p1;
create procedure p1(title VARCHAR(100), ageGrade INT, photoUrl TEXT, year INT,
season INT, resolution VARCHAR(30), summary TEXT)
begin
DECLARE CstrIDs varchar(150) DEFAULT '논쟁의 중심';
DECLARE GstrIDs varchar(150) DEFAULT '다큐시리즈';
DECLARE AstrIDs varchar(500) DEFAULT '';
DECLARE DstrIDs varchar(150) DEFAULT '마크 루이스';
DECLARE element varchar(1000);
-- 중복 데이터 무시하고 삽입하기
insert ignore into Video (title, ageGrade, photoUrl, year, season, resolution, summary, previewVideoUrl)
values (title, ageGrade, photoUrl, year, season, resolution, summary, photoUrl);
set @V := (select max(videoIdx) from Video);
select @V;
-- While 문1
WHILE CstrIDs != '' DO
SET element = SUBSTRING_INDEX(CstrIDs, ',', 1);
insert ignore into `Character`(name) values(element);
set @C := (select characterIdx from `Character` where name = element);
insert ignore into CharacterContact (characterIdx, videoIdx) values (@C, @V);
select @C;
IF LOCATE(',', CstrIDs) > 0 THEN
SET CstrIDs = SUBSTRING(CstrIDs, LOCATE(',', CstrIDs) + 1);
ELSE
SET CstrIDs = '';
END IF;
END WHILE;
-- While 문2
WHILE GstrIds != '' DO
SET element = SUBSTRING_INDEX(GstrIds, ',', 1);
set @G := (select genreIdx from Genre where name = element);
insert ignore into GenreContact (genreIdx, videoIdx) values (@G, @V);
select @G;
IF LOCATE(',', GstrIds) > 0 THEN
SET GstrIds = SUBSTRING(GstrIds, LOCATE(',', GstrIds) + 1);
ELSE
SET GstrIds = '';
END IF;
END WHILE;
-- While 문3
WHILE AstrIds != '' DO
SET element = SUBSTRING_INDEX(AstrIds, ',', 1);
insert ignore into Actor(name) values(element);
set @A := (select actorIdx from Actor where name = element);
insert ignore into ActorParticipate (actorIdx, videoIdx) values (@A, @V);
select @A;
IF LOCATE(',', AstrIds) > 0 THEN
SET AstrIds = SUBSTRING(AstrIds, LOCATE(',', AstrIds) + 1);
ELSE
SET AstrIds = '';
END IF;
END WHILE;
-- While 문4
WHILE DstrIDs != '' DO
SET element = SUBSTRING_INDEX(DstrIDs, ',', 1);
insert ignore into Director(name) values(element);
set @D := (select directorIdx from Director where name = element);
insert ignore into DirectorParticipate (directorIdx, videoIdx) values (@D, @V);
select @D;
IF LOCATE(',', DstrIDs) > 0 THEN
SET DstrIDs = SUBSTRING(DstrIDs, LOCATE(',', DstrIDs) + 1);
ELSE
SET DstrIDs = '';
END IF;
END WHILE;
end $$
delimiter ;
(2) 프로시저 호출 코드
call p1('디어 마이 프렌즈', 15, 'https://~', 2016, 1, 'HD', "노년에 접어들었지만 인생, 아직 저물지 않았다.");
[참고]
https://velog.io/@donghoim/MySQL-%EC%A0%80%EC%9E%A5-%ED%94%84%EB%A1%9C%EC%8B%9C%EC%A0%80-Stored-Procedure
https://heestory217.tistory.com/18
https://epthffh.tistory.com/entry/Mysql-Procedure%ED%94%84%EB%A1%9C%EC%8B%9C%EC%A0%80-%EA%B0%9C%EB%85%90%EA%B3%BC-%EC%98%88%EC%A0%9C