💡 이 글은 대용량 처리 및 성능 개선 경험을 위해 진행하는 사이드 프로젝트 “여기서 놀자”의 더미 데이터를 삽입하는 과정을 정리한 글입니다.
데이터베이스는 AWS의 RDS(MySQL)를 사용했다.
요구사항에 맞게 우선 위와 같이 ERD를 설계하였다.(추후 변경될 수 있다.)
테이블명 | 레코드 수 |
---|---|
users | 80만 |
hotels | 20만 |
rooms | 약 60만 |
reservations | 150만 |
더미 데이터는 프로시저를 통해 삽입하였으며, 그 과정은 이 글의 가장 아래에 정리하였다.
users
설명: 숙소 예약 서비스에 가입한 사용자, 사용자 1명당 여러개의 예약을 할 수 있으므로 reservations 테이블과 1 : N 관계
이름은 한글 20글자 중 3글자 무작위로 조합해서 생성
전화번호, 이메일은 순서대로 생성
비밀번호는 user{id} 를 인코딩
categories
설명: 숙소의 카테고리, 하나의 숙소 카테고리에는 여러개의 숙소가 있으므로 hotels 테이블과 1 : N 관계
regions
설명: 도 / 특별시 단위의 지역 정보, 각 지역에 속한 상세지역이 여러개 있으므로 detail_regions 테이블과 1 : N 관계
detail_regions
설명: 더 상세한 단위의 지역 정보, 하나의 상세 지역에 여러 숙소가 있으므로 hotels 테이블과 1 : N 관계
hotels
설명: 숙소의 정보, 하나의 숙소에는 여러개의 객실이 있으므로 rooms 테이블과 1 : N 관계
이름은 3~5글자로 무작위로 생성
주소는 지역, 상세지역, 숙소 이름 정보를 활용하여 생성
평점은 1~5사이 소숫점 1자리 소수
소개글은 10%가 NULL, 나머지는 3종류의 소개글을 무작위로 작성
상세 지역과 카테고리는 무작위 선택
rooms
설명: 객실의 정보, 하나의 숙소에는 여러건의 예약이 있으므로 reservations 테이블과 1: N 관계
객실의 이름은 싱글룸, 더블룸, 트윈룸, 트리플룸, 패밀리룸, 스위트룸 이렇게 6가지 중 설정
각 숙소는 평균적으로 3종류의 객실을 가짐
객실의 가격은 객실의 종류와 숙소의 카테고리에 따라 달라짐
객실의 개수는 1~3개 사이 (객실의 종류마다 확률이 다름)
최대 인원수는 객실의 종류에 따라 달라짐
reservations
설명: 예약 정보, 예약을 한 유저와 객실의 id, 숙소에 머무는 기간에 대한 정보를 담고있음
SET autocommit=0;
START TRANSACTION;
CALL 프로시저();
CALL 프로시저();
CALL 프로시저();
...
COMMIT;
SET autocommit=1;
DELIMITER //
CREATE PROCEDURE generate_users(IN start_id INT, IN end_id INT)
BEGIN
DECLARE i INT DEFAULT start_id;
DECLARE name_list VARCHAR(200) DEFAULT '김이박최정강조윤장임오서신권황안송류홍고문양손배조백';
WHILE i <= end_id DO
INSERT INTO users (name, email, phone, password)
VALUES (
CONCAT(
SUBSTRING(name_list, FLOOR(RAND() * 20) + 1, 1),
SUBSTRING(name_list, FLOOR(RAND() * 20) + 1, 1),
SUBSTRING(name_list, FLOOR(RAND() * 20) + 1, 1)
),
CONCAT('user', i, '@example.com'),
CONCAT('010-', LPAD(i DIV 10000, 4, '0'), '-', LPAD(i MOD 10000, 4, '0')),
MD5(RAND())
);
SET i = i + 1;
END WHILE;
END //
DELIMITER ;
INSERT INTO categories (name)
VALUES ('모텔'), ('호텔'), ('리조트'), ('펜션'), ('캠핑'), ('게스트하우스');
INSERT INTO regions (name)
VALUES ('서울'), ('부산'), ('제주'), ('경기'), ('인천'), ('강원'), ('경상'), ('전라'), ('충청');
랜덤 이름 생성 함수
CREATE FUNCTION `generate_hotel_name`() RETURNS VARCHAR(10)
BEGIN
DECLARE i INT DEFAULT 0;
DECLARE str_list_len INT DEFAULT 45;
DECLARE name_len INT DEFAULT RAND() * 2 + 3;
DECLARE str_list VARCHAR(200) DEFAULT '가나다라마바사아자차카타파하고노도로모보소오조초코토포호구누두루무부수우주추쿠투푸후기니디리미비시이지치키티피히거너더러머버서어저처커터퍼허';
DECLARE name VARCHAR(10) DEFAULT '';
WHILE i < name_len DO
SET name = CONCAT(name, SUBSTRING(str_list, FLOOR(RAND() * str_list_len) + 1, 1));
SET i = i + 1;
END WHILE;
RETURN name;
END;
프로시저
DELIMITER //
CREATE PROCEDURE `generate_hotels`(IN p_num_rows INT)
BEGIN
DECLARE i INT DEFAULT 0;
DECLARE rand_name VARCHAR(100);
DECLARE rand_category_id BIGINT;
DECLARE rand_detail_region_id BIGINT;
DECLARE rand_rating DECIMAL(2,1);
DECLARE rand_content LONGTEXT;
DECLARE rand_address VARCHAR(255);
DECLARE region_name VARCHAR(255) DEFAULT NULL;
DECLARE detail_region_name VARCHAR(255) DEFAULT NULL;
DECLARE category_name VARCHAR(255) DEFAULT NULL;
DECLARE rand_num INT;
WHILE i < p_num_rows DO
SET rand_num = RAND() * 3;
SET rand_category_id = FLOOR(1 + RAND() * 6);
SET category_name = (SELECT categories.name FROM categories WHERE categories.id = rand_category_id);
SET rand_name = CONCAT(generate_hotel_name(), ' ', category_name);
SET rand_detail_region_id = FLOOR(1 + RAND() * 75);
SET detail_region_name = (SELECT detail_regions.name FROM detail_regions WHERE id = rand_detail_region_id);
SET region_name = (SELECT regions.name FROM detail_regions join regions ON detail_regions.region_id = regions.id WHERE detail_regions.id = rand_detail_region_id);
SET rand_address = CONCAT(CONVERT(region_name USING utf8), ' ', CONVERT(detail_region_name USING utf8), ' ', CONVERT(rand_name USING utf8));
SET rand_rating = ROUND(RAND() * 4 + 1, 1);
IF RAND() < 0.1 THEN
SET rand_content = NULL;
ELSEIF rand_num < 1 THEN
SET rand_content = CONCAT('당신의 휴식과 여행을 위한 최적의 공간, ', rand_name, '입니다. 저희 숙소는 고객의 만족을 위해 최선을 다하고 있습니다. 고객들이 가장 필요로 하는 편의시설과 서비스를 제공하기 위해 노력하며, 아늑하고 깨끗한 객실과 편안한 침구를 제공합니다. 또한, 매일 청소를 하여 깨끗하고 편안한 환경을 유지합니다. 저희는 훌륭한 위치와 탁월한 서비스로 고객들의 여행을 즐겁게 만들어줄 것입니다.');
ELSEIF rand_num < 2 THEN
SET rand_content = CONCAT('최신 시설과 아름다운 자연이 조화를 이루는 최적의 휴식처, ', rand_name, '. ', rand_name, '은 지역에서 가장 멋진 경관을 자랑합니다. 객실 내부는 편안하고 넓은 공간으로 구성되어 있으며, 모던한 디자인과 고급스러운 인테리어가 돋보입니다. 휴식을 취하며 편안한 휴가를 보내기에는 최적의 장소이니, 언제든지 편안한 휴식을 취하실 수 있습니다.');
ELSE
SET rand_content = CONCAT('쾌적하고 세련된 분위기를 자랑하는 ', rand_name, '은 매일 아침 제공되는 풍성한 조식과 함께 편안한 휴식을 취할 수 있는 공간을 제공합니다. 유럽풍의 인테리어와 편안한 침구류로 꾸며진 객실은 숙면에 최적화된 공간이며, 다양한 관광지와 쇼핑몰이 밀집한 지역에서의 이동성도 용이합니다. 또한 레스토랑에서는 지역적인 식재료와 요리를 즐길 수 있으며, 주변에는 다양한 레스토랑과 카페가 위치하고 있습니다. 여행자들의 편안하고 즐거운 여행을 위해 최선을 다하는 ', rand_name, '에서 편안하고 기억에 남을 숙박을 즐겨보세요.');
END IF;
INSERT INTO hotels (name, address, rating, content, detail_region_id, category_id)
VALUES (rand_name, rand_address, rand_rating, rand_content, rand_detail_region_id, rand_category_id);
SET i = i + 1;
END WHILE;
END //
DELIMITER ;