공통 코드 VS Enum 클래스
미해결
김영한의 실전 데이터베이스 - 설계 2편, 실무에서 반드시 마주치는 9가지 설계 패턴
DB에 공통 코드를 저장하는 테이블을 만드는 것과 코드에서 Enum 클래스를 만들어서 관리하는 것 중 어떤 방법이 더 괜찮은걸까요?? 각 방식의 장단점이 있을까요??
- sql
- mysql
- dbms/rdbms
- 소프트웨어-설계
- SQLD
176만명의 커뮤니티!! 함께 토론해봐요.
미해결
김영한의 실전 데이터베이스 - 설계 2편, 실무에서 반드시 마주치는 9가지 설계 패턴
DB에 공통 코드를 저장하는 테이블을 만드는 것과 코드에서 Enum 클래스를 만들어서 관리하는 것 중 어떤 방법이 더 괜찮은걸까요?? 각 방식의 장단점이 있을까요??
미해결
김영한의 실전 데이터베이스 - 성능 최적화, 실행 계획과 인덱스 완전 정복
--order 프로시저 DELIMITER $$ CREATE PROCEDURE sp_generate_orders(IN p_count INT) BEGIN DECLARE v_i INT DEFAULT 0; DECLARE v_batch_size INT DEFAULT 2000; DECLARE v_member_id BIGINT; DECLARE v_item_count INT; DECLARE v_product_id BIGINT; DECLARE v_unit_price INT; DECLARE v_total INT; DECLARE v_order_id BIGINT; DECLARE v_j INT; DECLARE v_status VARCHAR(20); DECLARE v_rand DOUBLE; DECLARE v_days_ago INT; DECLARE v_max_member BIGINT; DECLARE v_max_product BIGINT; DECLARE v_base_date DATETIME DEFAULT '2026-04-01 00:00:00'; SELECT MAX(member_id) INTO v_max_member FROM member; SELECT MAX(product_id) INTO v_max_product FROM product; SET autocommit = 0; WHILE v_i < p_count DO SET v_rand = RAND(); IF v_rand < 0.12 THEN SET v_member_id = FLOOR(RAND() FLOOR(v_max_member 0.02)) + FLOOR(v_max_member * 0.98) + 1; ELSEIF v_rand < 0.35 THEN SET v_member_id = FLOOR(RAND() FLOOR(v_max_member 0.08)) + FLOOR(v_max_member * 0.90) + 1; ELSEIF v_rand < 0.59 THEN SET v_member_id = FLOOR(RAND() FLOOR(v_max_member 0.20)) + FLOOR(v_max_member * 0.70) + 1; ELSE SET v_member_id = FLOOR(RAND() FLOOR(v_max_member 0.70)) + 1; END IF; SET v_rand = RAND(); IF v_rand < 0.50 THEN SET v_days_ago = FLOOR(RAND() * 180); ELSE SET v_days_ago = 180 + FLOOR(RAND() * 915); END IF; SET v_rand = RAND(); SET v_status = CASE WHEN v_rand < 0.60 THEN 'DELIVERED' WHEN v_rand < 0.70 THEN 'SHIPPED' WHEN v_rand < 0.80 THEN 'PAID' WHEN v_rand < 0.90 THEN 'ORDERED' ELSE 'CANCELLED' END; INSERT INSERT INTO orders (member_id, order_status, total_price, ordered_at) VALUES (v_member_id, v_status, 0, DATE_SUB(v_base_date, INTERVAL v_days_ago DAY) + INTERVAL FLOOR(RAND() * 86400) SECOND); SET v_order_id = LAST_INSERT_ID(); SET v_item_count = 1 + FLOOR(RAND() RAND() 5) SET v_total = 0; SET v_j = 0; WHILE v_j < v_item_count DO SET v_rand = RAND(); IF v_rand < 0.30 THEN SET v_product_id = FLOOR(RAND() (v_max_product 0.01)) + 1; ELSE SET v_product_id = FLOOR(RAND() * v_max_product) + 1; END IF; SET v_unit_price = GREATEST(1000, ROUND(EXP(RAND() 3.0 + 8.0) / 100) 100); INSERT INTO order_item (order_id, product_id, quantity, unit_price) VALUES (v_order_id, v_product_id, 1 + FLOOR(RAND() * 3), v_unit_price); SET v_total = v_total + v_unit_price; SET v_j = v_j + 1; END WHILE; UPDATE orders SET total_price = v_total WHERE order_id = v_order_id; SET v_i = v_i + 1; IF v_i % v_batch_size = 0 THEN COMMIT; END IF; END WHILE; COMMIT; SET autocommit = 1; END$$ DELIMITER ; --리뷰 프로시저 DELIMITER $$ CREATE PROCEDURE sp_generate_reviews(IN p_count INT) BEGIN DECLARE v_i INT DEFAULT 0; DECLARE v_batch_size INT DEFAULT 5000; DECLARE v_product_id BIGINT; DECLARE v_member_id BIGINT; DECLARE v_rating TINYINT; DECLARE v_rand DOUBLE; DECLARE v_max_member BIGINT; DECLARE v_max_product BIGINT; DECLARE v_base_date DATETIME DEFAULT '2026-04-01 00:00:00'; SELECT MAX(member_id) INTO v_max_member FROM member; SELECT MAX(product_id) INTO v_max_product FROM product; SET autocommit = 0; WHILE v_i < p_count DO SET v_rand = RAND(); IF v_rand < 0.40 THEN SET v_product_id = FLOOR(RAND() (v_max_product 0.05)) + 1; ELSE SET v_product_id = FLOOR(RAND() * v_max_product) + 1; END IF; SET v_member_id = FLOOR(RAND() * v_max_member) + 1; SET v_rand = RAND(); SET v_rating = CASE WHEN v_rand < 0.30 THEN 5 WHEN v_rand < 0.60 THEN 4 WHEN v_rand < 0.75 THEN 3 WHEN v_rand < 0.90 THEN 2 ELSE 1 END; INSERT INTO review ( product_id, member_id, rating, content, created_at ) VALUES ( v_product_id, v_member_id, v_rating, CASE WHEN RAND() < 0.5 THEN CONCAT('리뷰 내용 ', v_i) ELSE NULL END, DATE_SUB( v_base_date, INTERVAL FLOOR(RAND() * 1095) DAY ) ); SET v_i = v_i + 1; IF v_i % v_batch_size = 0 THEN COMMIT; END IF; END WHILE; COMMIT; SET autocommit = 1; END$$ DELIMITER ; 위 상태에서 멈춰있어요 지금 order관련된 프로시저랑 review 관련된 프로시저가 너무 오래걸려서 안되는데 확인 부탁드립니다.
미해결
김영한의 실전 데이터베이스 - 설계 2편, 실무에서 반드시 마주치는 9가지 설계 패턴
안녕하세요, 해당 내용을 보다가 의문이 있어 질문남깁니다. SELECT SUM(stock_quantity) AS total_stock FROM product WHERE '2026-01-13 23:59:59' >= valid_from AND '2026-01-13 23:59:59' < valid_to; 해당 쿼리에서 valid_to가 13일 이면 13일 기준 데이터에서 위 쿼리에서는 제외되는데 그렇다면 AND '2026-01-13 00:00:00' < valid_to 조건은 틀린건가요?
해결됨
가장 쉽고 깊게 알려주는 MongoDB 완벽 가이드 [ By. 비전공자 & Kakao 개발자 ]
샤딩에 대한 언급이 초반에 대용량 데이터를 여러 샤드에 저장할거고 언젠간 알려줄게 하셨는데 강의에는 해당 내용이 없네요 ㅠㅠ 이건 보강으로 해주실 수 있으실까요?
해결됨
가장 쉽고 깊게 알려주는 MongoDB 완벽 가이드 [ By. 비전공자 & Kakao 개발자 ]
선생님께서 몽고DB는 AP라고 주장하셨는데... 페일오버시에 대장(프리머리)가 죽으면 부하(세컨더리)들이 대장의 직전 Oplog를 주어서 처리하고, 애초에 리드 프리퍼런스가 Primary가 기본이라고 하셨으니 쓰기 가용성을 포기하고 일관성을 찾는 모델 아닌가요? 또 검색하니까 몽고DB는 CP라고 하던데요... 또 이게 사람 생각마다 다를수 있는건가요?
미해결
김영한의 실전 데이터베이스 입문 - 모든 IT인을 위한 SQL 첫걸음(SQL부터 차근차근)
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] SQL 치다가 갑자기 오류가 나서 확인해보니 my_shop 데이터베이스가 사라지고 아래처럼 RECOVER_YOUR_DATA 무슨 복구프로그램 같은 느낌으로 되어있는데 이건 어떻게 해야하는거죠?
미해결
김영한의 실전 데이터베이스 - 성능 최적화, 실행 계획과 인덱스 완전 정복
안녕하세요 RealMySQL책을 참고해서 보면서 강의를 듣고 있습니다 책에는 InnoDB가 언두로그를 메모리에서 관리한다고 되어있는데 강의와 책 중 어떤 자료가 맞는 것인지 궁금하여 질문드립니다
해결됨
BigQuery(SQL) 활용편(퍼널 분석, 리텐션 분석)
안녕하세요. 강사님 최종 과제 제출합니다. Foodie Express 현황과 개선 전략으로 심플하게 작성하였습니다. 피드백 있으시면 말씀 부탁드립니다:) https://app.notion.com/p/3ca0de0d9a16807c81f8d4cbbe27f800?source=copy_link
미해결
김영한의 실전 데이터베이스 - 성능 최적화, 실행 계획과 인덱스 완전 정복
SELECT m.member_id, m.member_name, m.grade, COUNT(o.order_id) AS order_count, SUM(o.total_price) AS total_spent FROM member m JOIN orders o ON m.member_id = o.member_id WHERE m.grade = 'VIP' GROUP BY m.member_id, m.member_name, m.grade ORDER BY total_spent DESC LIMIT 20; 안녕하세요! 해당 쿼리에서는 group by 순서가 member_id, member_name, grade 순으로 되어있습니다. 강의에서는 group by 는 그룹핑을 할때 (member_id, member_name, grade) 을 기준으로 그룹핑 하여 순서가 상관없지만 인덱스 순서를 GROUP BY 순서에 맞게 인덱스를 설계 해야한다고 하셨습니다. grade 는 where 절에서 vip 상수로 필터링 하므로 인덱스에서 가장 왼쪽(앞)에 와야하지만 왜 member_id, member_name 순서에 맞게 인덱스를 줘야하는지 잘 모르겠습니다. 실제로 (grade, member_name, member_id) 순서로 member 테이블에 인덱스를 주고 EXPLAIN ANALZYZE 를 해보니 Aggregate using temporary table (actual time=373..373 rows=59999 loops=1) 가 나오는것을 확인했습니다. 임시테이블을 만들지 말지의 기준은 GROUP BY 로 그룹핑 하는 대상들이 연속적으로 올 경우는 굳이 임시테이블을 만들 필요가 없다는것으로 이해를 했습니다.(순서대로 오니까 미리 저장할 필요가 없으므로) 하지만 인덱스를 (grade, member_name, member_id) 순서로 줄 경우도 결국 인덱스 Grouping 순서에 맞게 오니까 임시테이블을 만들 필요가 없으니까 using temporary table 역시 발생하지 않아야 하는거 아닌가요? 그리고 설령 (grade, member_name, member_id) 로 주지 않고 (grade, member_name) 로 member테이블에 인덱스를 걸더라도 되는거 아닌가요? 어차피 세컨더리 인덱스 리프노드에는 member_id (pk) 가 선행컬럼을 기준으로 정렬되어 존재하니깐용 감사합니다!
해결됨
BigQuery(SQL) 활용편(퍼널 분석, 리텐션 분석)
안녕하세요 과제 제출합니다! 감사합니다. https://app.notion.com/p/3db130f3c2d88053b03cdac6b65cd928?source=copy_link
미해결
다양한 사례로 익히는 SQL 데이터 분석
안녕하세요. 강사님 강사님께서 26강 5일 가중이동평균 문제풀이 해주신 방법외에 아래와 같이 lag 함수 활용해서 문제 풀어도 현업에서 사용하기 문제 없을까요? with temp_01 as (select a.order_date as d_day, sum(b.amount) as sum_amount , row_number() over(order by date(a.order_date) asc) as rnum from nw.orders a join nw.order_items b on a.order_id = b.order_id where a.order_date >= date('1996-07-08') group by a.order_date) , temp_02 as ( select * , count(*) over(order by d_day rows between 4 preceding and current row) as cnt , avg(sum_amount) over(order by d_day rows between 4 preceding and current row) as m_avg_5days #일반 이동평균 구하기 , ( lag(sum_amount,1) over(order by d_day) * 1 + lag(sum_amount,2) over(order by d_day) * 1 + lag(sum_amount,3) over(order by d_day) * 1 + lag(sum_amount,4) over(order by d_day) * 0.5 + sum_amount * 1.5 ) / 5 as w_m_avg_5days #5일 가중이동평균 구하기 from temp_01 order by d_day ) select * from temp_02 where rnum >= 5; 이런식으로 풀어도 괜찮을까요? 현업에서 활용할때 어떤 방식이 더 효율적일지 궁금합니다!
해결됨
초보자를 위한 BigQuery(SQL) 입문
배틀 테이블 설정 시 계속해서 이 오류 창이 뜨는데 어떤 게 문제인지 알 수 있을까요..? 파티션 나누기, 건너 뛸 헤더 행 등 모든 설정은 정확하게 완료했습니다..
미해결
김영한의 실전 데이터베이스 - 성능 최적화, 실행 계획과 인덱스 완전 정복
DB 쿼리를 설계하면서 항상 궁금했던 점이 있습니다. 쿼리가 점점 복잡해지다 보면 Sort , GROUP BY 등의 연산을 DB에서 처리하는 것보다, 데이터를 애플리케이션으로 가져온 후 애플리케이션에서 처리하는 것이 더 효율적이지 않을까 하는 생각이 들 때가 있습니다. 그렇다면 일반적으로 DB 쿼리를 최적화할 때는 애플리케이션으로 데이터를 가져와 처리하기보다는, 적절한 Index 설계를 통해 가능한 한 DB에서 연산을 처리하는 것이 맞는 방향일까요? 아니면 상황에 따라서는 필요한 데이터를 DB에서 조회한 후, 일부 연산을 애플리케이션에서 처리하는 것도 하나의 최적화 방법이 될 수 있을까요? 제가 생각하는 방향 자체가 잘못된 것인지, 아니면 실제로 상황에 따라 고려할 수 있는 방법인지 궁금해서 질문드립니다.
미해결
김영한의 실전 데이터베이스 - 성능 최적화, 실행 계획과 인덱스 완전 정복
안녕하세요 영한님! 강의에서 말씀해 주신 것처럼, 인덱스를 생성한다고 해서 항상 옵티마이저가 해당 인덱스를 사용하는 것은 아니라는 점은 이해했습니다. 그렇다면 실무에서는 특정 인덱스를 어떤 쿼리나 사용 패턴을 고려해서 만들었는지, 그리고 어떤 의도로 설계했는지를 별도로 기록하거나 관리하는 방법이 있을까요? 예를 들어 시간이 지나 다른 개발자가 인덱스를 보더라도, “이 인덱스는 특정 조회 쿼리의 성능을 개선하기 위해 만들었다”와 같은 설계 의도를 파악할 수 있도록 관리하는지가 궁금합니다. 설계 1편에서 소개해 주신 용어 사전처럼 별도의 문서나 규칙을 두고 관리하는 방법이 있는지, 혹은 실무에서 일반적으로 사용하는 다른 방법이 있는지도 궁금합니다!
미해결
데이터 분석 SQL Fundamentals
안녕하세요! product_id를 집계 기준으로 하는 GROUP BY 구문을 작성할 때, 해당 product_id와 맵핑되는 category_id은 SELECT절에서 max(category_id)으로 처리하는 방식으로 설명해주셨습니다. 혹시 아래처럼 category_id도 GROUP BY에 같이 작성한다면, 어떤 점이 다르며 이슈나 문제가 될만한 상황이 있는지 궁금합니다! SELECT a.PRODUCT_ID, b.CATEGORY_ID, sum(amount) AS sum_by_prod FROM nw.ORDER_ITEMS a JOIN nw.PRODUCTS b ON a.PRODUCT_ID = b.PRODUCT_ID GROUP BY a.PRODUCT_ID, b.CATEGORY_ID
미해결
김영한의 실전 데이터베이스 - 기본편
[질문 내용] 여기에 질문 내용을 남겨주세요. 저는 1번문제에서 FK -> PK 로풀었습니다 영한님은 PK -> FK 로 푸셨던것에 질문입니다. FK -> PK는 항상 다대일으로 e.managed_id가 가리키는 PK 행은 0~1개라서 조인해도 왼쪽 테이블 행이 늘지 않아서 왼쪽 테이블이 행을 정하고, 조인은 컬럼만 붙인다고 생각했습니다. PK -> FK는 일대로써 한 행이 여러 행으로 늘어나는데, 그럼 on 조건까지 다 읽어야 이해되지 않을까 해서 여쭤봅니다. select e.employee_id, e.name, e.managed_id, m.name as manager_name from employees e join employees m on e.managed_id = m.employee_id where m.name = '최과장';
해결됨
초보자를 위한 BigQuery(SQL) 입문
1번 문제에서 catch_date를 기준으로 계산하라고 되어있는데, catch_date와 catch_datetime의 비교검증을 통해 catch_date가 KST가 아닌 UTC 기준이라는 것을 알았고, 그 다음에 왜 데이터의 기간을 catch_datetime을 사용해야 하는지 이해가 잘 가지 않습니다. 기준이 catch_date라고 명시되어 있다면 번거롭게 KST 기준으로 변환을 하는 게 아니라 그냥 UTC 기준으로 계산하는게 맞는 거 아닌가요?
해결됨
BigQuery(SQL) 활용편(퍼널 분석, 리텐션 분석)
안녕하세요! 3-13 리텐션 과제 제출합니다. 2, 3번 과제의 경우 클로드의 도움을 조금 받았으며, 최대한 스스로 생각하고 검토만 받는 방향으로 진행하였습니다. 부족한 부분이나 더 생각해볼 수 있는 부분들 피드백 주시면 감사하겠습니다! 과제 링크 https://inquisitive-toy-5d0.notion.site/3c6bc12dee6d80dc9b2ed0e7d1c9a33c?source=copy_link
미해결
다양한 사례로 익히는 SQL 데이터 분석
안녕하세요 선생님, 좋은 강의 잘 수강하고 있습니다. 다름이 아니라 실습 환경 세팅 중에 막히는 부분이 있어서 문의를 남기게 되었습니다. 제가 현재 개인 PC가 아닌 회사 노트북을 사용하여 실습을 진행하려다 보니, 사내 보안 및 권한 문제로 인해 로컬에 PostgreSQL을 설치할 수가 없는 상황입니다. 현재 DBeaver를 통해 사내 시스템인 Hive DB에만 접근이 가능 합니다. 제공해 주신 실습 파일( data_schema.backup )을 확인해 보았는데, 해당 파일은 PostgreSQL 전용 백업 파일이라서 제가 사용하는 Hive 환경에서는 복원(Restore)을 하거나 데이터를 읽어 들일 수가 없습니다. 강의를 계속 따라가고 싶은데, 혹시 이 백업 파일 대신 아래 두 가지 형태의 파일을 별도로 제공해 주실 수 있으실까요? 로우 데이터 파일: 엑셀이나 텍스트 형태의 원본 데이터 파일 (예: .csv 또는 .txt ) 스키마 쿼리 파일: 각 테이블의 컬럼명과 데이터 타입을 알 수 있는 테이블 생성 스크립트 (예: CREATE TABLE 문이 적힌 .sql 또는 텍스트 파일) CSV 파일과 테이블 생성 쿼리만 제공해 주시면, 제가 Hive 문법에 맞게 데이터 타입(예: VARCHAR -> STRING 등)을 직접 수정하여 테이블을 생성한 뒤 DBeaver의 데이터 Import 기능으로 밀어 넣어서 실습을 진행해 보겠습니다. 환경이 달라 번거로운 요청을 드리게 되어 죄송합니다. 확인해 주시면 정말 감사하겠습니다!
미해결
중고급 SQL과 실전 데이터 분석 101 문제 풀이
안녕하세요, sakila실전 17번에서 궁금증이 생겼는데요, store 테이블에 manager_staff_id가 있고, staff에 저는 staff_id만 존재해가지고 manager_staff_id가 staff_id안에 있을거라고 판단하고 join을 staff와 store로 하였습니다. 그래서 간단히 풀기는 하였는데 현업에서도 혹시 이와 같은 경우가 발생할 경우, 분석가가 판단하고서 join을 진행하는게 맞는건가요? 아니면 유관 부서에 질문해서 두 테이블에 있는 내용이 같은지 다른지를 묻고 진행하는게 맞는건가요?