<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>earthworm_o_o.log</title>
        <link>https://velog.io/</link>
        <description>지렁이</description>
        <lastBuildDate>Tue, 28 Jan 2025 07:31:28 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>earthworm_o_o.log</title>
            <url>https://velog.velcdn.com/images/earthworm_o_o/profile/3a9f536f-13cb-479a-8a55-797a679933dd/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. earthworm_o_o.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/earthworm_o_o" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Chrome Extension Privacy Policy]]></title>
            <link>https://velog.io/@earthworm_o_o/Chrome-Extension-Privacy-Policy</link>
            <guid>https://velog.io/@earthworm_o_o/Chrome-Extension-Privacy-Policy</guid>
            <pubDate>Tue, 28 Jan 2025 07:31:28 GMT</pubDate>
            <description><![CDATA[<h3 id="개인정보-처리방침---크롬-확장프로그램">개인정보 처리방침 - 크롬 확장프로그램</h3>
<p>본 크롬 확장프로그램은 사용자의 개인정보 및 민감한 데이터를 일체 수집하거나 처리하지 않습니다. </p>
<ul>
<li>데이터 수집 및 공유
본 확장프로그램은 어떠한 형태의 사용자 데이터도 수집하지 않습니다.
개발사 및 제 3자와의 데이터 공유는 전혀 이루어지지 않습니다.</li>
<li>문의 안내
본 개인정보 처리방침과 관련하여 궁금한 점이 있으시면 언제든지 아래 이메일로 문의해 주시기 바랍니다. 성심껏 답변 드리겠습니다.
연락처: <a href="mailto:rlaqhqo9372@gmail.com">rlaqhqo9372@gmail.com</a> </li>
</ul>
<h3 id="privacy-policy---chrome-extension">Privacy Policy - Chrome Extension</h3>
<p>This Chrome extension does not collect or process any personal or sensitive user data. </p>
<ul>
<li>Data Collection and Sharing
This extension does not collect any form of user data.
No data is shared with the developers or any third parties.</li>
<li>Contact Information
If you have any questions regarding this privacy policy, please feel free to contact us at any time. We will be happy to assist you.
Email: <a href="mailto:rlaqhqo9372@gmail.com">rlaqhqo9372@gmail.com</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[LLM] RAG가 뭐야..?]]></title>
            <link>https://velog.io/@earthworm_o_o/LLM-RAG%EA%B0%80-%EB%AD%90%EC%95%BC-btahzblk</link>
            <guid>https://velog.io/@earthworm_o_o/LLM-RAG%EA%B0%80-%EB%AD%90%EC%95%BC-btahzblk</guid>
            <pubDate>Wed, 30 Oct 2024 09:53:28 GMT</pubDate>
            <description><![CDATA[<p>최근 프로젝트에서 LLM의 한계를 극복할 수 있는 RAG(Retrieval-Augmented Generation) 기술이 주목받고 있다는 사실을 알게되어 사용해 보았습니다.
이에 대한 간단한 글을 작성해 보려고 합니다.</p>
<br>

<blockquote>
<h3 id="rag-란">RAG 란?</h3>
</blockquote>
<p><em><strong>RAG(Retrieval-Augmented Generation / 검색-증강 생성)</strong>는 대규모 언어 모델의 출력을 최적화하여 응답을 생성하기 전에 학습 데이터 소스 외부의 신뢰할 수 있는 지식 베이스를 참조하도록 하는 프로세스입니다.</em></p>
<p>이에 대해 자세히 알아보기 전에 <strong>&#39;대규모 언어 모델&#39;</strong>이 무엇인지 부터 알아보겠습니다.</p>
<p><strong>LLM(Large Language Model / 대규모 언어 모델)</strong>은 은 지능형 챗봇이나 자연어 처리 애플리케이션을 지원하는 핵심 인공 지능 기술입니다. 
LLM은 굉장히 많은 양의 데이터 학습을 통해 높은 자연어 이해력을 지니고 있어, 언어의 구조와 의미를 이해하고 다양한 언어 관련 작업을 처리할 수 있습니다. 
<strong>대표적인 모델</strong>로는 OpenAI의 GPT,구글의 Gemini, 메타의 LLAMA 등이 있습니다.</p>
<p>하지만 LLM에는 다음과 같은 <strong>단점</strong>이 존재합니다.</p>
<ul>
<li>명확한 정보가 부족할 때, 부정확하거나 추정된 정보를 제공할 가능성이 있습니다.<blockquote>
</blockquote>
<img src="https://velog.velcdn.com/images/earthworm_o_o/post/077e9e10-d81c-4cf7-aa1a-2011bd0d6985/image.png" alt=""><em>예를 들어, 제가 개발한 게임의 NPC에 관련된 질문은 일반적인 LLM은 정확한 답변을 할 수 없어 추정된 정보를 제공합니다.</em></li>
</ul>
<ul>
<li>사용자가 구체적이고 최신 정보를 요청할 때, 오래되었거나 일반적인 내용을 응답하여 기대와 일치하지 않는 답변을 줄 수 있습니다.<blockquote>
</blockquote>
<img src="https://velog.velcdn.com/images/earthworm_o_o/post/12cca580-0c6f-425b-a1b4-385b990eabfd/image.png" alt=""><em>예를 들어, 노벨문학상을 수상한 &#39;한강&#39; 작가의 노벨문학상 수상 정보는 비교적 최근의 정보이기에 정확한 답변을 하지 못할 수 있습니다.</em></li>
</ul>
<p><strong>RAG</strong>는 이러한 한계를 극복하기 위해 LLM이 답변을 생성하기 전에 특정 도메인에 대한 지식과 같은 외부 데이터 소스를 참조하여 생성 텍스트 출력을 더 잘 제어하고 답변의 정확도를 높이도록 합니다.</p>
<br>

<blockquote>
<h3 id="rag의-동작-과정">RAG의 동작 과정</h3>
</blockquote>
<p><img src="https://velog.velcdn.com/images/earthworm_o_o/post/f3f922f7-f1d6-4a6e-891f-f20951324047/image.png" alt=""></p>
<p><strong>1. 입력 쿼리 작성</strong> </p>
<ul>
<li><p>RAG 기술은 입력쿼리로 시작됩니다.
사용자는 특정 답변을 위한 질문 또는 작업 요청 텍스트를 입력합니다.</p>
<blockquote>
<p>입력: </p>
</blockquote>
<ul>
<li>&quot;&#39;알렉산드로 춘봉&#39;의 나이는 몇살이야?&quot;</li>
</ul>
</li>
</ul>
<p><strong>2. 입력쿼리 벡터 임베딩</strong></p>
<ul>
<li>RAG 기술은 LLM의 원래 학습 데이터 세트 외부에 있는 새 데이터 소스를 참조합니다.
텍스트, 이미지 등과 같이 다양한 형식의 외부 데이터는 벡터표현으로 변환되어 벡터 데이터베이스에 저장되어 있습니다.
이러한 외부 데이터와의 매칭을 위해 사용자 입력쿼리 또한 임베딩을 통해 벡터표현으로 변환합니다.</li>
</ul>
<p>*
_벡터 데이터베이스란?
벡터 데이터베이스는 정보를 벡터(데이터 객체의 수치 표현)로 저장하는 데이터베이스입니다. _</p>
<ul>
<li><p><em>벡터 임베딩이란?
벡터 임베딩은 주제, 단어, 이미지 또는 기타 데이터를 숫자로 표현한 것입니다.</em></p>
<blockquote>
<p>벡터 데이터베이스에 저장된 정보:</p>
</blockquote>
<ul>
<li>&quot;게임 &#39;밥은 먹고 다니냐&#39;의 NPC 정보&quot;</li>
<li>NPC 알렉산드로 춘봉 <ul>
<li>나이 : 32</li>
<li>성별 : 남성</li>
<li>직업: 여행자 겸 음식 평론가</li>
<li>출신지: 남쪽의 바다 근처 작은 마을</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><strong>3. 관련 자료 검색 추출</strong></p>
<ul>
<li>벡터표현으로 변환된 사용자 입력쿼리를 활용하여 외부데이터와 매칭하고, 관련있는 데이터 소스를 추출합니다.
관련성은 수학적 벡터 계산 및 표현을 사용하여 계산되고 설정됩니다.<blockquote>
<p>추출된 정보 :</p>
</blockquote>
<ul>
<li>알렉산드로 춘봉, 나이 : 32</li>
</ul>
</li>
</ul>
<p>*<em>4. LLM 프롬프트 확장 통신 *</em></p>
<ul>
<li><p>검색된 관련 외부 데이터를 컨텍스트에 추가하여 사용자 입력쿼리를 보강합니다. 이렇게 보강되고 확장된 입력을 LLM과 통신하여 전달합니다. 이 단계에서는 신속한 엔지니어링 기술을 사용하여 LLM과 효과적으로 통신합니다. </p>
<blockquote>
<p>확장된 입력쿼리 :</p>
</blockquote>
<ul>
<li>[ 알렉산드로 춘봉, 나이 : 32 ] 라는 정보에서 알렉산드로 춘봉의 나이는 몇살이야?</li>
</ul>
</li>
</ul>
<p><strong>5. 텍스트 답변 생성</strong></p>
<ul>
<li>LLM은 전달받은 입력에 대해 답변을 생성하여 제공합니다.
확장된 프롬프트를 사용함으로 LLM은 사용자 압력쿼리에 대해 보다 정확하고 입력에 더 부합한 답변을 생성할 수 있습니다.<blockquote>
<p>생성된 답변 :</p>
</blockquote>
<ul>
<li>&quot;알렉산드로 춘봉의 나이는 32세입니다.&quot;</li>
</ul>
</li>
</ul>
<br>

<blockquote>
<h3 id="rag의-장점">RAG의 장점</h3>
</blockquote>
<p>*<em>1. 비용 효율적 구현 *</em></p>
<ul>
<li><p>기존의 LLM 학습 데이터 외부에 있는 데이터를 교육하기 위해 드는 계산 및 재정적 비용은 상당히 큽니다. </p>
</li>
<li><p>RAG는 LLM에 새 데이터를 도입하기 위한 비용 효율적인 접근 방식입니다. 
자체 LLM을 보유할 필요가 없어 필요한 컴퓨팅과 저장 공간이 더 적고, 모델을 미세 조정하는 데 시간과 비용을 들일 필요가 없습니다.</p>
</li>
</ul>
<p><strong>2. 보다 정확하고 입력에 부합한 정보 제공</strong></p>
<ul>
<li><p>위에서 언급했듯 기존의 LLM의 경우 훈련되지 않은 입력쿼리에 대해 부정확한 응답을 제공하는 경우가 있습니다.</p>
</li>
<li><p>RAG는 관련 데이터 소스의 추가 참조를 근거로 하여, 모호한 문의에 더 정확하게 응답할 수 있습니다. LLM이 특정 질문에 대해 잘못된 정보 소스를 참조하는 경우 문제를 해결하고 수정할 수도 있습니다.
이를 통해 LLM을 활용한 생성형 인공 지능 기술을 보다 폭넓게 접근하고 사용할 수 있습니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/earthworm_o_o/post/8369b98d-e5c1-40fe-a12e-ebdf1f34aa99/image.png" alt=""></p>
</blockquote>
</li>
</ul>
<p><strong>3. 최신 정보 제공</strong></p>
<ul>
<li>RAG는 외부 참조 데이터를 정기적으로 업데이트할 수 있으므로 모델이 가장 최근의 사실 및 관련 정보에 접근할 수 있습니다.
이렇게 하면 RAG가 생성하는 응답에는 사용자의 입력쿼리와 관련이 있는 최신 정보가 포함됩니다.<blockquote>
<p><img src="https://velog.velcdn.com/images/earthworm_o_o/post/12dedb55-4c28-4243-8ed9-2b77a08d4d1b/image.png" alt=""></p>
</blockquote>
</li>
</ul>
<p><strong>4. 사용자 신뢰 강화</strong></p>
<ul>
<li><p>RAG는 외부 데이터 소스를 인용하고 답변에 소스에 대한 인용 또는 참조를 포함하여 사용자에게 제공함으로 응답을 뒷받침할 수 있습니다.</p>
</li>
<li><p>사용자는 추가 설명이나 세부 정보가 필요한 경우 데이터 소스 문서를 직접 찾아볼 수도 있습니다. 이를 통해 답변에 대한 사용자의 신뢰와 확신을 높일 수 있습니다.</p>
</li>
</ul>
<br>

<blockquote>
<h3 id="rag의-한계">RAG의 한계</h3>
</blockquote>
<p><strong>1. 부정확한 정보의 가능성</strong>
RAG는 외부 데이터에 의존하여 동작니다. 
벡터 데이터베이스에 저장된 정보, 검색된 정보가 올바르지 않으면 부정확한 결과가 나올 수 있습니다.
이를 위해 정기적으로 참조하는 외부 데이터를 업데이트 해야할 필요가 있습니다.</p>
<p><strong>2. 비용적 문제</strong>
RAG에는 대규모 외부 데이터베이스를 검색하는 것이 포함됩니다. 
LLM에 새로운 데이터를 학습시키는 것보다 빠르고 비용적으로 효율적인 방법이지만, 여전히 컴퓨팅 측면에서 비용이 많이 들고 느립니다.</p>
<p><strong>3. 사실적 정확성 기반 답변</strong>
RAG는 사실적 정확성을 기반으로 합니다. 
기존의 LLM보다 상상력이 풍부하거나 허구적인 콘텐츠를 생성하는 능력은 떨어질 수 있습니다.
창의적인 콘텐츠 생성에는 사용이 제한되기 때문에 목적에 따른 사용 선택이 필요합니다.</p>
<blockquote>
<h3 id="정리">정리</h3>
</blockquote>
<p>지금까지 RAG 기술의 정의, 동작 과정, 장점과 한계를 알아보았습니다.
RAG 기술은 LLM의 한계를 보완해주는 창의적인 대안이고,
여러 분야에서 활용하기에 좋은 기술입니다.</p>
<p>하지만 최근 LLM 기술이 빠르게 발전하면서, 더 큰 컨텍스트를 처리할 수 있고 더 효율적인 LLM이 등장하고 있습니다.
이에 따라 RAG의 필요성은 점점 줄어들 것이라고 생각합니다.</p>
<blockquote>
<h3 id="참고">참고</h3>
</blockquote>
<p><a href="https://aws.amazon.com/ko/what-is/retrieval-augmented-generation/">https://aws.amazon.com/ko/what-is/retrieval-augmented-generation/</a>
<a href="https://www.elastic.co/kr/what-is/retrieval-augmented-generation">https://www.elastic.co/kr/what-is/retrieval-augmented-generation</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[DB] MySQL, MongoDB 비교]]></title>
            <link>https://velog.io/@earthworm_o_o/MySQL-MongoDB-%EB%B9%84%EA%B5%90</link>
            <guid>https://velog.io/@earthworm_o_o/MySQL-MongoDB-%EB%B9%84%EA%B5%90</guid>
            <pubDate>Sun, 15 Sep 2024 12:56:05 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/earthworm_o_o/post/3e3a871c-fc53-411d-a546-09ed23bfd33b/image.jpg" alt=""></p>
<blockquote>
<h3 id="개요"><strong>개요</strong></h3>
</blockquote>
<p><strong>데이터베이스(DB)</strong>는 서비스 개발에 있어 데이터를 저장, 관리하는 중요한 역할을 합니다. 
이러한 DB는 다양한 기준으로 구분되며 업무 요구사항에 맞는 DB를 잘 선택해야 합니다.
오늘은 새로 시작하는 프로젝트에서 사용하게 된 <strong>MongoDB</strong>와 <strong>MySQL</strong>을 비교해보려고 합니다.</p>
<br>

<blockquote>
<h3 id="각-db의-간단한-설명">각 DB의 간단한 설명</h3>
</blockquote>
<h4 id="mysql-이란">MySQL 이란?</h4>
<p><em>MySQL은 오픈소스 관계형 데이터베이스 관리 시스템입니다. 다른 관계형 데이터베이스와 마찬가지로 MySQL은 행과 열로 구성된 테이블에 데이터를 저장합니다. 사용자는 더 일반적으로 SQL이라고 하는 구조화된 쿼리 언어를 사용하여 데이터를 정의, 조작, 제어, 쿼리할 수 있습니다. MySQL은 오픈소스이므로 25년 넘게 사용자와 긴밀히 협력하여 개발한 다양한 기능이 포함되어 있습니다.</em></p>
<ul>
<li>데이터베이스 타입 : 관계형 데이터베이스(SQL 데이터베이스)</li>
<li>데이터 저장 형식 : 행, 열로 구성된 테이블</li>
</ul>
<h4 id="mongodb-란">MongoDB 란?</h4>
<p><em>MongoDB는 오픈소스 비관계형 데이터베이스 관리 시스템입니다. 테이블과 행 대신 유연한 문서를 활용해 다양한 데이터 형식을 처리하고 저장합니다. 사용자가 다변량 데이터 유형을 손쉽게 저장하고 쿼리할 수 있는 탄력적인 데이터 저장 모델을 제공합니다. 이는 개발자의 데이터베이스 관리를 간소화할 뿐 아니라, 뛰어난 확장성을 갖춘 크로스 플랫폼 애플리케이션 및 서비스 환경을 구축합니다.</em></p>
<ul>
<li>데이터베이스 타입 : 비관계형 데이터베이스(NoSQL 데이터베이스)</li>
<li>데이터 저장 형식 : BSON(Binary JSON) 형식의 컬렉션<br>

</li>
</ul>
<blockquote>
<h3 id="mysql-vs-mongodb">MySQL vs MongoDB</h3>
</blockquote>
<p>MySQL은 대표적인 관계형 데이터베이스이고 
MongoDB는 대표적인 비관계형 데이터베이스이기에,
두 데이터베이스의 차이점은 이런 테이터베이스 타입에 의한 차이점이 많습니다.</p>
<h4 id="주요용어-대응">주요용어 대응</h4>
<table>
<thead>
<tr>
<th align="left"><center>MySQL</center></th>
<th><center>MongoDB</center></th>
</tr>
</thead>
<tbody><tr>
<td align="left">Database</td>
<td>Database</td>
</tr>
<tr>
<td align="left">Table</td>
<td>Collection</td>
</tr>
<tr>
<td align="left">Row</td>
<td>Document</td>
</tr>
<tr>
<td align="left">Column</td>
<td>Field</td>
</tr>
</tbody></table>
<br>

<h4 id="차이점">차이점</h4>
<p><strong>1 . 데이터 저장 방식</strong></p>
<p>DB 설명에도 작성했듯 <strong>MySQL</strong>은 데이터를 고정된 행과 열 기반의 테이블에 저장합니다.
미리 데이터 타입, 제약조건 등의 정적스키마를 정의하고 정의에 맞게 데이터를 저장하는 것입니다.</p>
<pre><code>CREATE TABLE students (
    id INT PRIMARY KEY,
    age INT,
    name VARCHAR(50)
);

INSERT INTO students (id, age, name) VALUES
(1, 20, &#39;Bobae&#39;),
(2, 22, &#39;Momae&#39;),
(3, 21, &#39;Jojae&#39;);</code></pre><table>
<thead>
<tr>
<th align="left"><center>id</center></th>
<th><center>age</center></th>
<th><center>name</center></th>
</tr>
</thead>
<tbody><tr>
<td align="left"><center>1</center></td>
<td><center>20</center></td>
<td><center>Bobae</center></td>
</tr>
<tr>
<td align="left"><center>2</center></td>
<td><center>22</center></td>
<td><center>Momae</center></td>
</tr>
<tr>
<td align="left"><center>3</center></td>
<td><center>21</center></td>
<td><center>Jojae</center></td>
</tr>
</tbody></table>
<p>위는 MySQL에서 &#39;학생&#39; 데이터를 저장한 예시입니다.
만약 요구사항이 변경되어 학생의 &#39;성적&#39; 정보를 저장해야 한다면 어떻게 해야할까요?
스키마를 변경하여 &#39;grade&#39;컬럼을 추가해야 할 것입니다.
이처럼 유연성이 부족하여 MySQL은 요구사항이 변경될 때마다 스키마 자체를 변경해주어야 합니다.
이미 대량의 데이터가 존재하는 테이블의 스키마를 변경하게 되면 서버에 부담이 갈 수도 있을 것입니다.</p>
<p><strong>MongoDB</strong>는 데이터를 BSON 형식의 컬렉션에 저장합니다.
(BSON은 JSON 형식처럼 보이지만 디스크 사용량을 줄이기 위해 바이너리로 직렬화한 것.)
동적 스키마를 가지기 때문에 다양한 타입과 구조를 갖는 데이터를 저장할 수 있습니다.</p>
<pre><code>{
    &quot;_id&quot;: 1,
    &quot;age&quot;: 20,
    &quot;grade&quot;: &quot;A&quot;,
    &quot;name&quot;: &quot;Bobae&quot;
},
{
    &quot;_id&quot;: 2,
    &quot;age&quot;: 22,
    &quot;name&quot;: &quot;Momae&quot;
},
{
    &quot;_id&quot;: 3,
    &quot;age&quot;: 21,
    &quot;grade&quot;: &quot;B&quot;,
    &quot;name&quot;: &quot;Jojae&quot;
    &quot;major&quot;: &quot;Computer Science&quot;
}
</code></pre><p>위와 같이 같은 &quot;Students&quot; 컬렉션이더라도 각 Document의 Field가 다양합니다.
MySQL에 비해 유연성이 좋아서 특정 Document에 새로운 Field를 추가하는 것 또한 가능합니다.</p>
<br>

<p><strong>2 . 중복</strong></p>
<p><strong>MySQL</strong>은 관계형 데이터베이스이기 때문에 데이터의 중복을 최소화하는 방향으로 정규화를 진행합니다. </p>
<p><img src="https://velog.velcdn.com/images/earthworm_o_o/post/fe884bb5-eccd-4168-b097-25adf8fa61ae/image.png" alt=""></p>
<p>중복이 줄어들고 일관성을 유지하기 좋다는 장점은 있지만, 이로 인해 테이블 간의 Join이 증가하게 되고 cpu사용량, 응답시간이 늘어나게 됩니다. 
복잡한 Join이 Read 성능을 하락시키는 것입니다.</p>
<br>

<p><strong>MongoDB</strong>는 비관계형 데이터베이스로 중복을 허용합니다. 
관계형 데이터베이스처럼 외래키를 사용하지 않고, 중첩 JSON을 사용해서 데이터를 그대로 나타냅니다. 
(Document 생성 시 자동으로 생성되는 기본키, Object ID를 사용하기도 합니다.)</p>
<pre><code>{
    &quot;_id&quot;: 1,
    &quot;age&quot;: 20,
    &quot;name&quot;: &quot;Bobae&quot;,
    &quot;class&quot;: {
        &quot;name&quot;: &quot;A&quot;,
        &quot;teacher&quot;: &quot;Tom&quot;
    }
},
{
    &quot;_id&quot;: 2,
    &quot;age&quot;: 22,
    &quot;name&quot;: &quot;Momae&quot;,
    &quot;class&quot;: {
        &quot;name&quot;: &quot;B&quot;,
        &quot;teacher&quot;: &quot;John&quot;
    }
},
{
    &quot;_id&quot;: 3,
    &quot;age&quot;: 21,
    &quot;name&quot;: &quot;Jojae&quot;,
    &quot;class&quot;: {
        &quot;name&quot;: &quot;A&quot;,
        &quot;teacher&quot;: &quot;Tom&quot;
    }
}</code></pre><p>이때, 데이터 값이 변경되면 중복된 데이터들이 모두 최신 데이터를 유지할 수 있도록 업데이트, 관리해줘야 합니다. 일관성 측면에서 좀 더 신경써야한다는 것입니다.</p>
<br>

<p><strong>3 . 확장성</strong></p>
<p>데이터베이스에 Read, Write 요청이 증가하여 데이터베이스 서버의 확장이 필요한 경우가 생길 수 있습니다.</p>
<p><img src="https://velog.velcdn.com/images/earthworm_o_o/post/8d4764b1-c1f2-4e37-b7b3-0bd4c5d54560/image.png" alt=""></p>
<p>이때 <strong>MySQL</strong>은 Scale-Up으로 수직적 확장을 합니다.
데이터베이스 서버에 더 많은 리소스를 추가하여 성능을 향상시키는 것입니다.
이는 성능 향상에 따른 비용 증가의 폭이 큰 편이고, 하나의 서버에 부하가 집중되어 장애가 발생하면 그 영향이 크다는 단점이 있습니다.</p>
<p>다른 방법으로는 Replication 이 있습니다.
말 그대로 DB의 복제본을 만드는 것으로 복제본은 Read-Only(읽기전용)이 됩니다.
이는 Write 요청에 의한 부하를 해결할 수 없으며, 복제본이 원본보다 뒤쳐지는 문제가 발생할 수 있습니다.</p>
<p><img src="https://velog.velcdn.com/images/earthworm_o_o/post/317b2b1c-80ea-4962-a4c6-a8b9dfea083c/image.png" alt=""></p>
<p><strong>MongoDB</strong>는 Scale-Out으로 수평적 확장을 합니다.
서버를 추가하여 기존 서버의 부하를 분담하는 방법입니다.
데이터가 여러 서버로 분산되어 Read, Write 성능을 최적화할 수 있습니다.</p>
<br>

<p><strong>4 . 성능</strong></p>
<p><strong>MySQL</strong>은 여러 테이블간의 고성능 조인을 수행하도록 설계되어 많은 수의 데이터를 READ할 때 좋은 성능을 냅니다.
다만 데이터를 한 행씩 삽입하기에 Write 성능은 떨어집니다.</p>
<p><strong>MongoDB</strong>는 많은 수의 데이터를 삽입하고 업데이트할 때 좋은 성능을 냅니다.</p>
<br>

<blockquote>
<h3 id="정리">정리</h3>
</blockquote>
<p>두 데이터베이스는 각각의 장단점이 있고, 필요에 따라 사용해야 합니다.
<strong>MySQL</strong>은 금융 시스템처럼 데이터의 일관성과 신뢰성이 중요한 경우 적합하고,  <strong>MongoDB</strong>는 소셜 서비스처럼 비정형 데이터를 다룰 때, 또는 요구사항이 자주 바뀌거나 까다로울 때, 확장성이 중요한 경우 적합합니다.</p>
<p><img src="https://velog.velcdn.com/images/earthworm_o_o/post/0cf13fd8-096b-41ea-b287-878f099a6084/image.png" alt=""></p>
<p>두 데이터베이스 모두 널리 사용되고 있는 만큼 꼭 사용해보았으면 좋겠습니다.</p>
<blockquote>
<h3 id="참고">참고</h3>
</blockquote>
<p><a href="https://aws.amazon.com/ko/compare/the-difference-between-mongodb-vs-mysql/">https://aws.amazon.com/ko/compare/the-difference-between-mongodb-vs-mysql/</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Django] 장고 기본요소 익히기]]></title>
            <link>https://velog.io/@earthworm_o_o/Django-%EC%9E%A5%EA%B3%A0-%EA%B8%B0%EB%B3%B8%EC%9A%94%EC%86%8C-%EC%9D%B5%ED%9E%88%EA%B8%B0</link>
            <guid>https://velog.io/@earthworm_o_o/Django-%EC%9E%A5%EA%B3%A0-%EA%B8%B0%EB%B3%B8%EC%9A%94%EC%86%8C-%EC%9D%B5%ED%9E%88%EA%B8%B0</guid>
            <pubDate>Wed, 26 Jun 2024 16:05:06 GMT</pubDate>
            <description><![CDATA[<h4 id="장고-기초-공부를-위해-점프-투-장고-위키독스를-활용한다">&lt;장고 기초 공부를 위해 &quot;점프 투 장고&quot; 위키독스를 활용한다.&gt;</h4>
<p><a href="https://wikidocs.net/book/4223">https://wikidocs.net/book/4223</a></p>
<p>간단하게 핵심 내용이라고 생각한 부분만을 작성했다.</p>
<h3 id="-1장-">[ 1장 ]</h3>
<ul>
<li><p>&lt;1-03&gt; <strong>가상환경</strong> 만들기 → C:\venvs&gt; python -m venv {가상환경 이름}</p>
</li>
<li><p>&lt;1-04&gt; 쉽게 가상환경 이동하기 → “mysite.cmd” 생성</p>
</li>
<li><p>&lt;1-05&gt; <strong>장고 프로젝트</strong> 만들기(mysite) C:\projects{이름}&gt;django-admin startproject config .</p>
</li>
<li><p>&lt;1-05&gt; 인터프리터 가상환경 위치로 변경</p>
</li>
<li><p><strong>서버실행</strong> → (mysite) C:\projects\mysite&gt;python <strong><a href="http://manage.py/">manage.py</a></strong> runserver</p>
</li>
<li><p><a href="http://setting.py">setting.py</a> 에 언어설정, 시간설치 (시크릿 키 확인)</p>
</li>
<li><p>프로젝트 생성시 기본파일</p>
<ul>
<li><strong>manage.py</strong>: 프로젝트 관리 명령어를 실행하는 스크립트.</li>
<li><strong>settings.py</strong>: 프로젝트 설정을 정의하는 파일.</li>
<li><strong>urls.py</strong>: URL 패턴을 정의하는 파일.</li>
<li><strong>wsgi.py</strong>: WSGI 호환 웹 서버를 위한 진입점 파일.</li>
<li><strong>asgi.py</strong>: ASGI 호환 웹 서버를 위한 진입점 파일.</li>
</ul>
</li>
</ul>
<br>
<br>


<h3 id="-2장-">[ 2장 ]</h3>
<h4 id="2-01">&lt;2-01&gt;</h4>
<ul>
<li><p><strong>앱생성</strong> → (mysite) C:\projects\mysite&gt;django-admin startapp {앱이름}
이건  <a href="http://localhost:8000/pybo">http://localhost:8000/</a>{앱이름} 요청시 응답</p>
<ul>
<li>앱 생성시 기본 파일<ul>
<li><code>admin.py</code>: Django 관리자 사이트와 관련된 설정을 정의하는 파일.</li>
<li><code>apps.py</code>: 앱의 설정을 정의하는 파일.</li>
<li><code>models.py</code>: 데이터베이스 모델을 정의하는 파일.</li>
<li><code>tests.py</code>: 테스트 케이스를 작성하는 파일.</li>
<li><code>views.py</code>: 뷰를 정의하는 파일.</li>
<li><code>migrations/</code>: 데이터베이스 마이그레이션 파일을 저장하는 디렉토리.</li>
<li>기타 초기화 파일(<code>__init__.py</code> 등).</li>
</ul>
</li>
</ul>
</li>
<li><p>프로젝트의 <a href="http://urls.py">urls.py</a> → <strong>URL과 앱의 뷰 함수간의 매핑</strong> 정의 </p>
<pre><code>                                   페이지 요청시 가장 먼저 호출</code></pre><p>즉, <strong>1. URL 요청(웹 → 서버) / 2. urls.py 매핑확인 / 3. 매칭함수 결과(서버 → 웹)</strong></p>
</li>
</ul>
<pre><code class="language-python">**[urls.py]
from {앱} import views
urlpatterns = [
    path(&#39;{앱}/&#39;, views.{함수}),
]

----------------------------------
[views.py]
from django.http import HttpResponse

def index(request):
    return HttpResponse(&quot;ㅎㅇ.&quot;)</code></pre>
<ul>
<li><a href="http://urls.py">urls.py</a> - 프로젝트 성격 / <a href="http://views.py">views.py</a> - 앱 성격 → 앱 바뀔때마다 프로젝트 파일 바꾸는 것 좋지X</li>
<li><strong>앱 만의 URL 매핑 파일 생성 필요</strong></li>
</ul>
<pre><code class="language-python">[프로젝트의 urls.py]
from django.urls import path, include

urlpatterns = [
    path(&#39;{앱}/&#39;, include(&#39;{앱}.urls&#39;)), 
]
------------------------------------------
[앱의 urls.py]

from django.urls import path

from . import views

urlpatterns = [
    path(&#39;&#39;, views.{함수}),
]</code></pre>
<ul>
<li>이때 프로젝트의 <a href="http://urls.py">urls.py</a> 에서  {앱이름/} 매핑, 
앱의 urls.py 에서 나머지 매핑되어 <strong>더해진 URL이 최종 URL</strong></li>
</ul>
<br>

<h4 id="2-02">&lt;2-02&gt;</h4>
<ul>
<li><p>마이그레이션이란? DB데이터를 시스템에서 다른 시스템으로 이전하는 과정</p>
</li>
<li><p><a href="http://setting.py">setting.py</a> 에 데베에 관한 내용도 나오네</p>
<p>  우리 프로젝트의 BASE_DIR은 <code>C:\projects\mysite</code></p>
<p>  SQLite는 소규모 프로젝트에서 사용되는 가벼운 파일 기반의 데베</p>
</li>
</ul>
<pre><code class="language-python">DATABASES = {
    &#39;default&#39;: {
        &#39;ENGINE&#39;: &#39;django.db.backends.sqlite3&#39;,
        &#39;NAME&#39;: BASE_DIR / &#39;db.sqlite3&#39;,
    }
}</code></pre>
<p>데이터베이스가 필요한 앱만 migrate가 필요하다.</p>
<ul>
<li><p>모델 (테이블을 모델)</p>
<p>  장고 db models 를 가져와서</p>
<p>  각 모델을 클래스로 만들고? 이름 / 속성 작성</p>
<p>  여러가지 속성타입<br>  • <a href="https://docs.djangoproject.com/en/4.0/ref/models/fields/#field-types">https://docs.djangoproject.com/en/4.0/ref/models/fields/#field-types</a></p>
</li>
</ul>
<ul>
<li><strong>테이블 가져오려면</strong>
프로젝트 setting.py에 앱의 apps파일을 <strong>INSTALLED APPS</strong> 로 설정해줘야 함.</li>
</ul>
<pre><code class="language-python">INSTALLED_APPS = [
    &#39;pybo.apps.PyboConfig&#39;,</code></pre>
<ul>
<li>python <a href="http://manage.py/">manage.py</a> <strong>migrate</strong> 하기 전에 
모델 변경, 생성 시 python <a href="http://manage.py/">manage.py</a> <strong>makemigrations 해줘야 한다.</strong></li>
<li><strong>장고 쉘</strong> 실행 → python <a href="http://manage.py/">manage.py</a> shell</li>
</ul>
<p><strong>from</strong> pybo.models <strong>import</strong> Question, Answer -  모델 가져오기
<strong>from</strong> django.utils <strong>import</strong> timezone - 시간 라이브러리? 가져오기
<strong>테이블 데이터(튜플) 생성</strong>
q = Question(subject=&#39;<del>&#39;, content=&#39;</del>&#39;, create_date=timezone.now())<br><strong>생성된 데이터 저장</strong>
q.save()</p>
<p><a href="http://q.id/">q.id</a>  - 값 조회
Question.objects.all() - 데이터 <strong>조회</strong>
Question.objects.filter(id=1) subject__contains=&#39;장고’ 등등 <strong>조건 확인</strong>
• <a href="https://docs.djangoproject.com/en/4.0/topics/db/queries/">https://docs.djangoproject.com/en/4.0/topics/db/queries/</a></p>
<ul>
<li><p>모델에 특정 애트리뷰트 값을 데이터 조회 시 보이도록</p>
</li>
<li><p><em>def*</em> <strong><strong>str</strong></strong>(self):
   <strong>return</strong> self.subject</p>
</li>
<li><p>모델 <strong>수정 / 삭제</strong>
q = Question.objects.get(id=2) - 변수에 저장
q.subject = &#39;Django Model Question’
q.save()
q.delete()</p>
</li>
<li><ul>
<li>외래키 존재 시 연결 객체 이용
a = Answer(question=q, content=&#39;~&#39;, create_date=timezone.now())</li>
</ul>
</li>
<li><p>*</p>
</li>
<li><p><em>연결 테이블 찾으려면*</em> 
q.answer_set.all()
a.question</p>
</li>
</ul>
<br>

<h4 id="2-03-admin">&lt;2-03&gt; Admin</h4>
<ul>
<li><strong>관리자 생성</strong> → python <a href="http://manage.py/">manage.py</a> createsuperuser
<a href="http://localhost:8000/admin/">http://localhost:8000/admin/</a> 접속</li>
<li>앱의 <a href="http://admin.py">admin.py</a> 파일</li>
<li><em>모델 등록*</em></li>
<li><em>from*</em> .models <strong>import</strong> Question
admin.site.register(Question)<br></li>
<li><em>검색 클래스
class*</em> <strong>QuestionAdmin</strong>(admin.ModelAdmin):
search_fields = [&#39;subject&#39;]<br></li>
<li><em>당연히 해당 클래스도 추가해야함*</em>
admin.site.register(Question, QuestionAdmin) <br>
<br>

</li>
</ul>
<h4 id="2-045">&lt;2-04,5&gt;</h4>
<ul>
<li><strong>모델 사용 view 함수</strong>
이때 모델 값을 반환할 때는 딕셔너리 형태(아래코드의 context)로 넘겨줘야 한다.</li>
</ul>
<pre><code class="language-python">from django.shortcuts import render, get_object_or_404

from .models import Question

def index(request):
    question_list = Question.objects.order_by(&#39;-create_date&#39;) // - 는 역순
    context = {&#39;question_list&#39; : question_list}
    return render(request, &#39;pybo/question_list.html&#39;, context)</code></pre>
<ul>
<li>urls.py에서 <strong>값을 url에</strong> 주고 싶다면 &lt;타입:변수명&gt; 
→ 이때 <strong>변수명은 views 함수의 인자명과 동일</strong></li>
</ul>
<pre><code class="language-python">urlpatterns = [
    path(&#39;&#39;, views.index, name = &#39;index&#39;), -&gt; 별칭은 view, 템플릿에서 사용
    path(&#39;&lt;int:question_id&gt;/&#39;, views.detail),
]</code></pre>
<ul>
<li><p><a href="http://urls.py">urls.py</a>에 네임스페이스 설정 가능 → view, 템플릿에서 사용 </p>
</li>
<li><p>프로젝트의 urls.py 
path(&#39;pybo/&#39;, include(&#39;pybo.urls&#39;, namespace=&#39;pybo&#39;)),</p>
</li>
<li><p>앱의 urls.py
app_name = &#39;pybo’</p>
</li>
<li><p>사용예시
&lt;<strong>li</strong>&gt;&lt;<strong>a</strong> href=&quot;{% url &#39;pybo:detail&#39; question.id %}&quot;&gt;{{ question.subject }}&lt;/<strong>a</strong>&gt;&lt;/<strong>li</strong>&gt;</p>
<br>
<br>
#### <2-06>
</li>
<li><p>POST기능의 함수</p>
</li>
</ul>
<pre><code class="language-python">def answer_create(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    question.answer_set.create(content=request.POST.get(&#39;content&#39;), create_date=timezone.now())
    return redirect(&#39;pybo:detail&#39;, question_id=question.id)</code></pre>
<p>request.POST.get(&#39;content&#39;) 이부분을 잘보면 
템플릿의 post 타입 폼 답변 중 content 라는 데이터 값을 가져오는 것이다.</p>
<h4 id="2-10">&lt;2-10&gt;</h4>
<ul>
<li><p><strong>폼(Form) 이란?</strong></p>
<ul>
<li>쉽게 말해 페이지 요청시 전달되는 파라미터들을 쉽게 관리하기 위해 사용하는 클래스</li>
<li>필수 파라미터의 값이 <strong>누락</strong>되지 않았는지, 파라미터의 <strong>형식</strong>은 적절한지 등을 <strong>검증할 목적</strong>으로 사용한다.</li>
<li>(약간 모델에서 전달 부분만 가져 복제본 같은 느낌인가..?)</li>
</ul>
</li>
<li><p>앱에 <a href="http://form.py">form.py</a> 파일을 따로 만들어줘야 한다.
모델을 import하고 Meta로 필드지정</p>
</li>
</ul>
<pre><code class="language-python">from django import forms
from pybo.models import Question

class QuestionForm(forms.ModelForm):
    class Meta:
        model = Question  # 사용할 모델
        fields = [&#39;subject&#39;, &#39;content&#39;]</code></pre>
<ul>
<li>view에서 해당 Form 클래스를 가져와서 사용한다.
이때도 마찬가지로 템플릿으로 넘겨줄 땐 딕셔너리 형태
이렇게 넘겨주면 템플릿에서 해당 필드의 html 코드를 자동으로 생성</li>
</ul>
<pre><code class="language-python">from .forms import QuestionForm

def question_create(request):
    form = QuestionForm()
    return render(request, &#39;pybo/question_form.html&#39;, {&#39;form&#39;: form})</code></pre>
<ul>
<li>템플릿의 form 태그는 ‘GET’, ‘POST’ 요청방식(method) 중 하나로 action URL에 요청을 보낸다.<ul>
<li>이때 action을 지정하지 않는다면? 현재 페이지로 요청을 보내게 된다.</li>
<li>즉, 같은 view 함수에 대해 GET, POST 요청방식의 URL 요청을 받을 수 있고,</li>
<li>요청방식에 따라 다르게 동작해야 할 수 있다.</li>
<li>(GET -처음 링크요청 /  POST - 템플릿 form 의 submit)</li>
</ul>
</li>
</ul>
<pre><code class="language-python">def question_create(request):
    if request.method == &#39;POST&#39;:
        form = QuestionForm(request.POST)
        if form.is_valid():
            question = form.save(commit=False)
            question.create_date = timezone.now()
            question.save()
            return redirect(&#39;pybo:index&#39;)
    else:
        form = QuestionForm()
    context = {&#39;form&#39;: form}
    return render(request, &#39;pybo/question_form.html&#39;, context)</code></pre>
<ul>
<li><p>is_valid : form의 값이 유효한지 검사</p>
</li>
<li><p>commit = False : 임시저장, 즉 DB에 저장X → form에는 전체 속성이 있는 것이 아니기 때</p>
</li>
<li><p>Form의 위젯(부트스트랩 사용) / 레이블(속성 이름 설정) 도 있다.
필요할 때 코드를 찾아보기.</p>
</li>
</ul>
<br>
<br>


<h3 id="🪱-여기까지가-장고-기초--🪱">🪱 여기까지가 장고 기초 : 🪱</h3>
<h3 id="🪱-개념적으로-헷갈리는-부분이-많았다🪱">🪱 개념적으로 헷갈리는 부분이 많았다.🪱</h3>
]]></description>
        </item>
    </channel>
</rss>