묻고 답해요
160만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결김영한의 실전 데이터베이스 - 기본편
is_active 컬럼의 인덱스 활용 방법
is_active는 0/1의 두 개의 값만 존재하기 떄문에 카디널리티값이 상대적으로 낮은데요,, 그렇다면 단독으로 인덱스 사용시 그 이점을 크게 누리기 어렵다고 보면 되나요?그렇다면 문제와 풀이처럼 복합 인덱스에서는 사용되는데 여러 컬럼을 복합 인덱스로 사용될 땐 효과가 극대화 된다고 보면 되나요? (0/1의 값 정렬 유무가 후위 컬럼 값 정렬에 영향을 미침)
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
Outbox와 OutBoxEvent 무엇이 다른 것인가요?
OutBoxEvent.class의 필드에 그대로 OutBox를 받으시던데 생성이유와 OutBox와 OutBoxEvent의 차이점이 궁금합니다
-
해결됨React & FastAPI로 만드는 투표 커뮤니티 플랫폼: 결제 시스템으로 수익화까지!
Github repository는 없나요?
Notion에 있는 코드말고, Github Repository는 따로 없나요?
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
12.7 socket.js코드 그대로 뱃겨서 했는데, socket.request.session.color가안나오네요
socket.request.session은 서버쪽으로 잘 전달되는데, socket.request.session.color가 전달이안되네요 cors에러도 잡았는데 그래도 안잡히네요
-
미해결김영한의 실전 데이터베이스 입문 - 모든 IT인을 위한 SQL 첫걸음(SQL부터 차근차근)
DB 설계편 예상 출시일
안녕하세요. 지속적으로 질문을 드려 번거롭게 하여 죄송합니다. 혹시나DB 설계편은 언제쯤 출시되는지 여쭤볼 수 있을까요 ?
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
12.7 코드 그대로 뱃겨서 햇는데 스샷같이 오류가뜹니다.
완전히 똑같이 복붙하고 실행했는데 계속 이메시지가 프론트엔트에 뜨네요
-
미해결김영한의 실전 데이터베이스 입문 - 모든 IT인을 위한 SQL 첫걸음(SQL부터 차근차근)
강의 내용
안녕하세요. 김영한 선생님! 자바에서부터 DB 까지 정말 훌륭한 과목들을 개설해주셔서 정말 감사합니다.저는 학교에서 배우는 DB 예습용으로 배우고 싶은 마음이 큰데, 영한 선생님께서 입문편, 기본편에서 다루는 내용들이 아래에 있는 내용들을 상당 부분 커버가 가능한지 여쭤보고 싶습니다. 바쁘실텐데 시간내어 댓글을 작성해주셔서 감사드려요. 데이터베이스의 기초 및 관계형 데이터베이스 (Foundational concepts)데이터베이스 시스템이 무엇인지, 데이터베이스를 효과적으로 설계하는 방법데이터 모델, 관계형 모델, 관계형 데이터베이스 및 애플리케이션, 스키마, 정규화 등엔티티-관계 모델링 (Entity-Relationship Modeling)관계형 데이터베이스의 논리적 설계 (Logical design)관계형 대수 (Relational Algebra)데이터베이스 보안데이터베이스 관리 시스템의 아키텍처 및 구현 (Database management system architecture and implementation)데이터베이스 관리 시스템의 소프트웨어 아키텍처, 알고리즘 및 구현 기술메모리 계층, 저장 시스템, 캐싱/버퍼 풀, 인덱스, 쿼리 처리, 쿼리 최적화트랜잭션 처리, 격리 및 동시성 제어데이터베이스 질의 및 애플리케이션 개발데이터베이스를 쿼리하는 방법 (SQL)데이터베이스 애플리케이션을 개발하는 방법쿼리 최적화 및 트랜잭션 처리 개요다양한 데이터베이스 유형 및 데이터 처리 (NoSQL – “Not Only SQL” databases & Data Enabled Decision Support)NoSQL 데이터베이스: "NoSQL" 데이터 모델과 데이터베이스의 필요성, 예시 및 사용 사례클라우드 데이터베이스 및 DaaS (Databases-as-a-service)데이터 기반 의사결정 지원: 데이터 웨어하우스, 데이터 가져오기 및 정제 (data import and cleanse), OLAP, 피벗 테이블, 스타 스키마, 보고 및 시각화클러스터링, 분류, 분석, 마이닝 등 분석 기법 개요
-
미해결김영한의 실전 데이터베이스 - 기본편
문제와 풀이: 특정 상사의 부하 직원 찾기
[질문 내용]저는 FK에서 PK로 조인하고 id로 찾았는데,PK에서 FK를 조인한 후 name으로 찾는 것과의 차이를 모르겠습니다.자식 입장에서는 PK가 하나이기 때문에 한 행이고, 부모에서 FK를 볼 땐 여러 개일 수도 있으니 여러 행일 수 있다는 것은 이해했지만이 경우에는 어떤 차이점이 있는지, 안좋은 방식인지, 틀린 건지 궁금합니다.
-
미해결김영한의 실전 데이터베이스 - 기본편
문제 4번 실행 결과
[질문 내용]문제 4번 실행 결과가 강의와 pdf에서는이렇게 돼있는데 영한님이 직접 실행해보신 것과 제가 실행했을 때에는'세종대왕'님과 '션'의 위치가 달라서 잘못 푼 줄 알았습니다! ㅋㅋㅋ
-
해결됨자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
21강 생성자에서 의존성 주입과 관련하여 질문 있습니다.
생성자에서 필드에 의존성 주입하면예를 들어 컨트롤러 생성자를 만들때 서비스 필드에 의존성 주입해주면 그때는 @Autowired가 자동으로 존재한다고 했는데 이 @Autowired 는 생성자의 파라미터를 전부 빈으로 등록시켜주는건가요?만약 그렇다고 한다면 생성자의 파라미터가 객체가 아닌 경우는 어떻게 되는건가요?혹시 객체 타입 파라미터만 빈으로 등록시켜주고 객체가 아닌 파라미터는 빈으로 등록시켜주지 않나요?
-
해결됨자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
20강 강의 내용중 Interface 만드는 부분에서 질문이 있어요
Interface 만드는 중에 메서드 정의할때 public은 추상 메서드라면 지우셨는데 추상 메서드는 public을 왜 지워야 하나요? 아니면 안 지워도 되는데 어떤 이유로 인해 지운건가요?
-
미해결김영한의 실전 데이터베이스 입문 - 모든 IT인을 위한 SQL 첫걸음(SQL부터 차근차근)
오류 원인
1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]안녕하세요! DML-등록 강의 듣고 있는 중입니다. 선생님이 입력한시대로 동일하게 입력했는데, 첨부한 화면 보시면 이순신이 들어간 서울시 관악구에는 활성화가 되지 않아(?) 계속 오류가 뜹니다 무엇이 문제일까요ㅠㅠ
-
해결됨React & FastAPI로 만드는 투표 커뮤니티 플랫폼: 결제 시스템으로 수익화까지!
백엔드 도커 실행 에러가 뜹니다 ㅠ
에러 로그는 아래와 같아요File "<frozen importlib._bootstrap_external>", line 999, in exec_module File "<frozen importlib._bootstrap>", line 488, in callwith_frames_removed File "/app/main.py", line 6, in <module> from app.db.database import Base, async_engine File "/app/app/db/database.py", line 1, in <module> from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine ModuleNotFoundError: No module named 'sqlalchemy' WARNING: WatchFiles detected changes in 'app/db/crud/user.py'. Reloading... Process SpawnProcess-2: Traceback (most recent call last): File "/usr/local/lib/python3.12/multiprocessing/process.py", line 314, in _bootstrap self.run() File "/usr/local/lib/python3.12/multiprocessing/process.py", line 108, in run self._target(*self._args, **self._kwargs) File "/usr/local/lib/python3.12/site-packages/uvicorn/_subprocess.py", line 80, in subprocess_started target(sockets=sockets) File "/usr/local/lib/python3.12/site-packages/uvicorn/server.py", line 67, in run return asyncio.run(self.serve(sockets=sockets)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/asyncio/runners.py", line 195, in run return runner.run(main) ^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/asyncio/runners.py", line 118, in run return self._loop.run_until_complete(task) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "uvloop/loop.pyx", line 1518, in uvloop.loop.Loop.run_until_complete File "/usr/local/lib/python3.12/site-packages/uvicorn/server.py", line 71, in serve await self._serve(sockets) File "/usr/local/lib/python3.12/site-packages/uvicorn/server.py", line 78, in _serve config.load() File "/usr/local/lib/python3.12/site-packages/uvicorn/config.py", line 436, in load self.loaded_app = import_from_string(self.app) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/site-packages/uvicorn/importer.py", line 22, in import_from_string raise exc from None File "/usr/local/lib/python3.12/site-packages/uvicorn/importer.py", line 19, in import_from_string module = importlib.import_module(module_str) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/importlib/__init__.py", line 90, in import_module return bootstrap.gcd_import(name[level:], package, level) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "<frozen importlib._bootstrap>", line 1387, in gcdimport File "<frozen importlib._bootstrap>", line 1360, in findand_load File "<frozen importlib._bootstrap>", line 1331, in findand_load_unlocked File "<frozen importlib._bootstrap>", line 935, in loadunlocked File "<frozen importlib._bootstrap_external>", line 999, in exec_module File "<frozen importlib._bootstrap>", line 488, in callwith_frames_removed File "/app/main.py", line 6, in <module> from app.db.database import Base, async_engine File "/app/app/db/database.py", line 1, in <module> from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine ModuleNotFoundError: No module named 'sqlalchemy' 위 에러 때문인지 코드에서 아래 에러? 도 뜨네요 uvicorn main:app --reload도 당연 에러 뜨구요..어떤 부분을 확인하면 될까요? ㅠ
-
해결됨6주 완성! 백엔드 이력서 차별화 전략 4가지 - 똑같은 이력서 속에서 돋보이는 법
강의를 듣다가 알림전송 관련 궁금한 점이 생겨 질문드립니다!
1. 현재 학습 진도몇 챕터/몇 강을 수강 중이신가요? 5-15. 비동기 처리 - 대표적인 사례 (22분~23분)여기까지 이해하신 내용은 무엇인가요? 여러개의 알림을 전송 할 때 비동기로 알림을 전송하게 된다면 n개의 알림을 1개의 알림을 전송하는 시간과 같은 시간으로 전송할수 있다. 2. 어려움을 겪는 부분어느 부분에서 막히셨나요?100만개의 알림을 1개의 알림 전송 시간으로 보내려면 어떻게 해야하나요? 3. 시도해보신 내용문제 해결을 위해 어떤 시도를 해보셨나요? 제 생각에는 메세지 큐를 중간에 두어서 100만개의 알림을 일단 메세지 큐에 넣고 알림 서버의 리소스를 고려해서 토픽?을 주면 될거 같은데 맞나요?갑자기 궁금해져서 질문드립니다! 이렇게 구체적으로 알려주시면, 더 정확하고 도움이 되는 답변을 드릴 수 있습니다!
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
카프카 이외의 메시지 큐 사용
완강하고 갑자기 생각난 질문입니다만, 이번 강의에서 카프카 아닌 rabbitmq 와 같은 다른 메시지 큐를 사용한다면 어떨까요? 어차피 거의 사용용도가 같다면 크게 달라지는 부분은 없을지 고견 부탁드립니다.
-
미해결김영한의 실전 데이터베이스 입문 - 모든 IT인을 위한 SQL 첫걸음(SQL부터 차근차근)
DataGrip 사용시
안녕하세요! 학교에서는 MYSQL Workbench 가 아니라 Datagrip 을 사용할거라고 말씀해주셨는데, 이 강의를 통해서 MYSQL Workbench 를 배워도 다시 또 Datagrip 을 배워야 하는건가요 ?
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
페이징 조건시 조회수 정렬 기능 질문
강사님 안녕하세요.게시판 조회시 페이징으로 처리할때 조회수를 오름차순, 내림차순 정렬하는 기능이 있다면 현재 강의 설계 기준으로 어떻게 구현할 수 있을까요? 제가 생각한 방법은 다음과 같습니다.사전 조건:view에서 조회수 데이터는 redis를 바라봄개수 백업 적용 / 단위는 10페이징 쿼리에서 RDB 백업 테이블의 조회수 기준으로 정렬코드 레벨에서 redis 데이터 기준으로 한번 더 정렬 문제는, 2번에서 한 페이지의 데이터만 정렬이 되기 대문에 페이지를 넘어갈때 정렬이 깨지는 현상이 발생합니다 ㅠ 데이터 전체를 메모리에 한번에 조회하지 않고 할 수 있는 방법이 있을까요?
-
미해결[리뉴얼] 처음하는 SQL과 데이터베이스(MySQL) 부트캠프 [입문부터 활용까지]
강의 자료 다운로드 관
[리뉴얼] 처음하는 SQL과 데이터베이스(MySQL)부트캠프 [입문부터 활용까지] 강의 결제하여 수강 시작했는데요!강의자료는 연습문제만 있는 거고 강의 중에 활용하시는 파일은 따로 없는 게 맞는건가요?
-
해결됨김영한의 실전 데이터베이스 - 기본편
셀프조인 상사 출력
employee_id와 manager_id를 사용해서 셀프조인 하는 과정에서자신의 상사를 모두 표시하고 싶다는 생각이 들었습니다. SELECT a.employee_id, a.name, b.employee_id, b.name, c.employee_id, c.name, d.employee_id, d.name, e.employee_id, e.name FROM employees a left join employees b on a.manager_id = b.employee_id left join employees c on b.manager_id = c.employee_id left join employees d on c.manager_id = d.employee_id left join employees e on d.manager_id = e.employee_id 이와같이 직원 코드가 있고 상사 코드가 있는 경우 자기로부터 가장 높은 상사까지 한 행에 다 출력하고 싶은 경우에는 어떤 방법이 최선인지 알고 싶습니다.지금은 단순히 데이터 개수가 적기 때문에 몇번의 조인으로 해결되었지만 실무에서 데이터 개수가 많다고 할때 이와같이 구하려면 어떻게 구해야하는지 궁금합니다. 즉 위 코드처럼 여러번 조인을 쓰는게 아니라 원하는 결과를 얻을 때 까지 자동으로 반복시킬 방법이 있는지 궁금합니다.
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
12.7.1스스로 해보기 질문되나요
//채팅창에 현재 참여자 수나 목록표시하기구현한chat.html코드와 socket.j코드입니다. 그런데 chat: ${socket.request.session.color} 이부분이 undefined으로 계속 나옵니다. console.log에 찍어보면 socket.request.session에 color만 빼고 나오네요.{% extends 'layout.html' %} {% block content %} <h1>{{title}}</h1> <a href="/" id="exit-btn">방 나가기</a> <fieldset> <legend>채팅 내용</legend> <div style="display: flex; gap: 20px;"> <!-- 채팅 목록 --> <div id="chat-list" style="flex: 3;"> {% for chat in chats %} {% if chat.user === user %} <div class="mine" style="color: {{chat.user}}"> <div>{{chat.user}}</div> {% if chat.gif %} <img src="/gif/{{chat.gif}}"> {% else %} <div>{{chat.chat}}</div> {% endif %} </div> {% elif chat.user === 'system' %} <div class="system"> <div>{{chat.chat}}</div> </div> {% else %} <div class="other" style="color: {{chat.user}}"> <div>{{chat.user}}</div> {% if chat.gif %} <img src="/gif/{{chat.gif}}"> {% else %} <div>{{chat.chat}}</div> {% endif %} </div> {% endif %} {% endfor %} </div> <!-- 참여자 목록 --> <div style="flex: 1;"> <h3>참여자</h3> <ul id="user-list"></ul> </div> </div> </fieldset> <form action="/chat" id="chat-form" method="post" enctype="multipart/form-data"> <label for="gif">GIF 올리기</label> <input type="file" id="gif" name="gif" accept="image/gif"> <input type="text" id="chat" name="chat"> <button type="submit">전송</button> </form> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <script src="/socket.io/socket.io.js"></script> <script> const socket = io.connect('http://localhost:8005/chat', { path: '/socket.io', transports: ['websocket'] }); socket.emit('join', new URL(location).pathname.split('/').at(-1)); socket.on('join', function (data) { const div = document.createElement('div'); div.classList.add('system'); const chat = document.createElement('div'); chat.textContent = data.chat; div.appendChild(chat); document.querySelector('#chat-list').appendChild(div); if (data.userList) { const ul = document.querySelector('#user-list'); // 참여자 목록이 들어갈 ul ul.innerHTML = ''; // 기존 목록 초기화 data.userList.forEach(function (user) { const li = document.createElement('li'); li.textContent = user; ul.appendChild(li); }); } }); socket.on('exit', function (data) { const div = document.createElement('div'); div.classList.add('system'); const chat = document.createElement('div'); chat.textContent = data.chat; div.appendChild(chat); document.querySelector('#chat-list').appendChild(div); }); socket.on('chat', function (data) { const div = document.createElement('div'); if (data.user === '{{user}}') { div.classList.add('mine'); } else { div.classList.add('other'); } const name = document.createElement('div'); name.textContent = data.user; div.appendChild(name); if (data.chat) { const chat = document.createElement('div'); chat.textContent = data.chat; div.appendChild(chat); } else { const gif = document.createElement('img'); gif.src = '/gif/' + data.gif; div.appendChild(gif); } div.style.color = data.user; document.querySelector('#chat-list').appendChild(div); }); document.querySelector('#chat-form').addEventListener('submit', function (e) { e.preventDefault(); if (e.target.chat.value) { axios.post('/room/{{room._id}}/chat', { chat: this.chat.value, }) .then(() => { e.target.chat.value = ''; }) .catch((err) => { console.error(err); }); } }); document.querySelector('#gif').addEventListener('change', function (e) { console.log(e.target.files); const formData = new FormData(); formData.append('gif', e.target.files[0]); axios.post('/room/{{room._id}}/gif', formData) .then(() => { e.target.file = null; }) .catch((err) => { console.error(err); }); }); </script> {% endblock %} const SocketIO = require('socket.io');const { removeRoom } = require('./services'); module.exports = (server, app, sessionMiddleware) => { const io = SocketIO(server, { path: '/socket.io',transports: ['websocket'] }); app.set('io', io); const room = io.of('/room'); const chat = io.of('/chat'); const wrap = middleware => (socket, next) => middleware(socket.request, {}, next); chat.use(wrap(sessionMiddleware)); room.on('connection', (socket) => { console.log('room 네임스페이스에 접속'); socket.on('disconnect', () => { console.log('room 네임스페이스 접속 해제'); }); }); chat.on('connection', (socket) => { console.log('chat 네임스페이스에 접속'); console.log(socket.request.session); socket.on('join', (roomId) => { socket.join(roomId); const room = socket.adapter.rooms.get(roomId); // Set const userList = room ? Array.from(room) : []; // 시스템 메시지 + 사용자 목록 전송 socket.to(roomId).emit('join', { user: 'system', chat: `${socket.request.session.color}님이 입장하셨습니다.`, userList, }); }); socket.on('disconnect', async () => { console.log('chat 네임스페이스 접속 해제'); const { referer } = socket.request.headers; // 브라우저 주소가 들어있음 const roomId = new URL(referer).pathname.split('/').at(-1); const currentRoom = chat.adapter.rooms.get(roomId); const userCount = currentRoom?.size || 0; if (userCount === 0) { // 유저가 0명이면 방 삭제 await removeRoom(roomId); // 컨트롤러 대신 서비스를 사용 room.emit('removeRoom', roomId); console.log('방 제거 요청 성공'); } else { socket.to(roomId).emit('exit', { user: 'system', chat: `${socket.request.session.color}님이 퇴장하셨습니다.`, }); } }); });}