<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>mathengi</title>
    <link>https://hwansci.tistory.com/</link>
    <description>공부한 내용들, 트러블 슈팅 용 블로그</description>
    <language>ko</language>
    <pubDate>Wed, 15 Apr 2026 01:21:54 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>worldint</managingEditor>
    <image>
      <title>mathengi</title>
      <url>https://tistory1.daumcdn.net/tistory/4673153/attach/dbfda16add6e470ebecca196d2279bc3</url>
      <link>https://hwansci.tistory.com</link>
    </image>
    <item>
      <title>redis 위치정보 처리(GeosPatial 자료구조)</title>
      <link>https://hwansci.tistory.com/171</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Redis는 Geospatial 데이터를 사용하면 위치정보를 저장할 사용할 수 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Geospatial 자료구조는 sorted set의 확장이다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sorted set 형태로 데이터를 저장하는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 내부적으로는 위도,경도를 geohash로 인코딩한 값을 저장하게 된다&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;Geohash란?&lt;br /&gt;아래 사진 처럼 특정 위치(위,경도)를 문자열로 인코딩 하는 방식&lt;br /&gt;지구를 평면 지도로 만들고 그것을&amp;nbsp;&lt;br /&gt;지구를 평면 지도로 만들고 그것을 나누어서 문자를 하나씩 맵핑해놓은것이다&lt;br /&gt;중국부근이 w에 대응되고 그 w안에서 또 사각형으로 나누어서 문자들을 맵핑하고&lt;br /&gt;이런식으로 쭉 나가는 것이다&lt;br /&gt;그래서 서울은 wydm9가된다&lt;br /&gt;https://geohash.softeng.co/ 여기서 확인 가능&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;987&quot; data-origin-height=&quot;848&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Q5xnS/btsLriBhCM8/7GGBMd4gGVrnLglQNpDZkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Q5xnS/btsLriBhCM8/7GGBMd4gGVrnLglQNpDZkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Q5xnS/btsLriBhCM8/7GGBMd4gGVrnLglQNpDZkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQ5xnS%2FbtsLriBhCM8%2F7GGBMd4gGVrnLglQNpDZkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;430&quot; data-origin-width=&quot;987&quot; data-origin-height=&quot;848&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;저장&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위치정보를 저장하게 되면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 geohash가 sorted set의 score부분에 들어가게된다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Redis Cli에서는 GEOADD 명령어를 사용하여 key를 지정하고 경도, 위도, 이름을 저장할 수 있다&lt;/p&gt;
&lt;pre class=&quot;crmsh&quot; style=&quot;color: #000000; text-align: left;&quot;&gt;&lt;code&gt;GEOADD location 126.823162 35.191378 &quot;Vino Cafe&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 이런식으로 추가하게 되면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키는 'location' score는 위,경도데이터, member는 &quot;Vino&amp;nbsp; Cafe&quot; 가 들어간다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;저 위경도가 `wssdf7as` 이런 `geohash` 문자열로 바뀌고&amp;nbsp;&lt;br /&gt;이것이 정수형태로 또 변경되어서 `score`부분에 들어감&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;범위 검색&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`GeoPatial`의 범위 검색하는 명령어는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`georadiusbymember`와 `georadius`가 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;georadiusbymember&lt;/b&gt; : member를 기준으로 반경내의 다른 member검색&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;georadius&lt;/b&gt; : 입력된 위경도를 기준점으로 반경내의 다른 member검색&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;i&gt;*이렇게 두개로 쓰던것 redis 6.2.0부터 `GEOSEARCH`로 통합되고 위의 것들은 deprecated되었다고 한다.&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;GEOSEARCH&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;georadiusbymember는&amp;nbsp;&lt;/b&gt;`FROMMEMBER`와 `BYRADIUS` 옵션을 통해서 사용가능&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1734756303874&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;GEOSEARCH KEY FROMMEMBER &quot;member&quot; BYRADIUS 100 m  [ASC | DESC]
GEOSEARCH location FROMMEMBER &quot;Vino Cafe&quot; BYRADIUS 100 m ASC&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;georadius는 `BYLONLAT`과 `BYRADIUS`옵션을 통해 사용 가능&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1734756009560&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;GEOSEARCH locations BYLONLAT 127.0 37.5 BYRADIUS 100 km&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;spring에서의 사용&lt;/h3&gt;
&lt;pre id=&quot;code_1734756377652&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;	public List&amp;lt;String&amp;gt; findDriversWithLocation(Double latitude, Double longitude) {
		String key = RedisKey.DRIVER_LOCATIONS;
		Distance radius = new Distance(5, Metrics.KILOMETERS);
		Circle circle = new Circle(new Point(longitude, latitude), radius);

		GeoResults&amp;lt;RedisGeoCommands.GeoLocation&amp;lt;Object&amp;gt;&amp;gt; results = redisTemplate.opsForGeo()
			.radius(key, circle);

		List&amp;lt;String&amp;gt; driverIds = results.getContent().stream()
			.map(result -&amp;gt; (String)result.getContent().getName())
			.collect(Collectors.toList());

		return driverIds;
	}&lt;/code&gt;&lt;/pre&gt;</description>
      <author>worldint</author>
      <guid isPermaLink="true">https://hwansci.tistory.com/171</guid>
      <comments>https://hwansci.tistory.com/171#entry171comment</comments>
      <pubDate>Sat, 21 Dec 2024 12:38:05 +0900</pubDate>
    </item>
    <item>
      <title>[spring] 캐시 추상화</title>
      <link>https://hwansci.tistory.com/170</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;캐시란&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애플리케이션 개발시 자주 사용되는 데이터들을 '캐시 저장소'라는 곳에 넣어두고&lt;br /&gt;다음에 또 동일한 데이터를 요청시에 그 캐시 저장소에서 꺼내서 주는것&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;spring의 캐시 추상화&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;spring에서는 이런 캐시 기능을&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AOP 패러다임에 따라서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추상화하여 사용하기 쉽게 해놓음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;사용 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원하는 메서드위에 어노테이션을 붙임으로 캐시기능을 사용할 수 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스나 인터페이스 단위로도 캐시를 적용 할 수 있지만 드물다고 한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스프링에서는 아래와 같은 캐싱을 위한 메서드 레벨 어노테이션이 존재한다(공식문서에 몇개 더 있음)&lt;/p&gt;
&lt;pre id=&quot;code_1733386497185&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Cacheable
@CachePut
@CacheEvict&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;@Cacheable&lt;/h4&gt;
&lt;pre id=&quot;code_1733386670835&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Cacheable(&quot;books&quot;)
public Book findBook(ISBN isbn) {...}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;* isbn은 책의 고유 번호 같은것&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;findBook 메소드는 'books'라는 이름의 캐시에 연결되어있다&lt;/li&gt;
&lt;li&gt;처음 요청시에는 책의 정보를 디비에서 받아오고&amp;nbsp;&lt;/li&gt;
&lt;li&gt;그 정보를 &quot;books&quot;라는 이름의 캐시에 `isbn` 매개변수를 key로 두고 디비에서 가져온 책정보를 `value`로 저장한다&lt;/li&gt;
&lt;li&gt;두번째에 동일한 `isbn`으로 요청이 들어오면 캐시에서 `isbn`과 동일한 키가 있어면 그 데이터를주고 해당 메서드는 실행되지않는다&lt;/li&gt;
&lt;li&gt;@Cacheable을 사용하는 방식으로는
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1.위와 같이 키를 명시적으로 지정하지 않는 방법 : 그럼 매개변수가 키가된다&amp;nbsp;&lt;/li&gt;
&lt;li&gt;2. 고정된 스트링 키를 사용하는방식 `@Cacheable(value = &quot;books&quot;, key = &quot;'all'&quot;)`&lt;/li&gt;
&lt;li&gt;3. 객체를 키로 사용하는 방식`@Cacheable(value = &quot;books&quot;, key = &quot;#isbn&quot;)`&lt;/li&gt;
&lt;li&gt;4. 객체의 특정 필드를 키로 사용하는방식`@Cacheable(value = &quot;books&quot;, key = &quot;#isbn.bookNumber&quot;)`&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;@CachePut&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CachePut은 Cachealbe과 비슷하지만 조회시에 캐시저장소에 저장은 하지만 해당 메소드를 스킵하지는 않는다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;@CacheEvict&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;캐시를 제거하는 어노테이션&lt;/li&gt;
&lt;li&gt;allEntries=true로 해놓으면 books라는 이름의 캐시 전체 삭제&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733552244257&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@CacheEvict(cacheNames=&quot;books&quot;, allEntries=true) 
public void loadBooks(InputStream batch)&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 키의 캐시만 삭제하는 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733552336590&quot; class=&quot;reasonml&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;@CacheEvict(value = &quot;book&quot;, key = &quot;#book.bookNo&quot;)
public void updateBook(Book book) {
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;위의 캐쉬 기능을 사용하기 위해서는 config 클래스에 @EnableCaching 어노테이션을 적용해야 사용가능&lt;/h3&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;@EnableCaching
@Configuration 
public class CacheConfig {
    ... 
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;</description>
      <category>programming/java</category>
      <author>worldint</author>
      <guid isPermaLink="true">https://hwansci.tistory.com/170</guid>
      <comments>https://hwansci.tistory.com/170#entry170comment</comments>
      <pubDate>Thu, 5 Dec 2024 17:05:16 +0900</pubDate>
    </item>
    <item>
      <title>데이터베이스 옵티마이저</title>
      <link>https://hwansci.tistory.com/169</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;옵티마이저란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;데이터베이스 옵티마이저(Database Optimizer)는&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;데이터베이스에서 SQL 쿼리를 빠르고 효율적으로 실행하기 위해 최적의 실행 계획을 만들어준다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;옵티마이저의 목적은 쿼리 실행에 필요한 비용을 최소화하여 성능을 극대화하는 것이다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 비용에는 디스크 I/O, CPU 사용량, 네트워크 트래픽 등이 포함된다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;467&quot; data-origin-height=&quot;369&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFEd2W/btsK325pLbM/pkrnuMIYfmRGZIyPImLJD0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFEd2W/btsK325pLbM/pkrnuMIYfmRGZIyPImLJD0/img.png&quot; data-alt=&quot;https://coding-factory.tistory.com/743&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFEd2W/btsK325pLbM/pkrnuMIYfmRGZIyPImLJD0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFEd2W%2FbtsK325pLbM%2FpkrnuMIYfmRGZIyPImLJD0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;467&quot; height=&quot;369&quot; data-origin-width=&quot;467&quot; data-origin-height=&quot;369&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://coding-factory.tistory.com/743&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;옵티마이저의 종류&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-pm-slice=&quot;3 1 []&quot; data-spread=&quot;true&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;규칙 기반 옵티마이저(Rule-Based Optimizer, RBO)&lt;/b&gt;&lt;/span&gt;&lt;span&gt;: &lt;br /&gt;이 옵티마이저는 사전 정의된 규칙에 따라 쿼리를 최적화한다&lt;br /&gt;예를 들어, 특정한 형태의 쿼리에서는 항상 인덱스를 사용하는 방식으로 최적화하는 식&lt;br /&gt;이 방식은 상대적으로 간단하지만 최신 데이터베이스에서는 사용하지 않는다&lt;br /&gt;&lt;br /&gt;특정 우선순위&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;비용 기반 옵티마이저(Cost-Based Optimizer, CBO)&lt;/b&gt;&lt;/span&gt;&lt;span&gt;: &lt;br /&gt;대부분의 현대적인 데이터베이스 관리 시스템(DBMS)에서 사용되는 방법&lt;br /&gt;CBO는 테이블의 통계 정보와 실행 비용을 바탕으로 가장 효율적인 실행 계획을 선택한다&lt;br /&gt;테이블의 데이터 분포나 인덱스의 효율성 등을 고려하여 더 정교한 실행 계획을 수립&lt;br /&gt;통계정보는 &lt;b&gt;딕셔너리&lt;/b&gt;라는곳에 저장,업데이트한다&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;옵티마이저 동작 방식&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;470&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NPItu/btsK2DZSGXn/biAYeoQpKFmiHEMCs5mxN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NPItu/btsK2DZSGXn/biAYeoQpKFmiHEMCs5mxN1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NPItu/btsK2DZSGXn/biAYeoQpKFmiHEMCs5mxN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNPItu%2FbtsK2DZSGXn%2FbiAYeoQpKFmiHEMCs5mxN1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;470&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;470&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Parser&lt;/b&gt; : SQL문장의 문법, 구조를 분석하여 쿼리 트리 생성&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;쿼리트리란&lt;br /&gt;```&lt;br /&gt;&lt;span style=&quot;text-align: left;&quot;&gt;SELECT&amp;nbsp;name&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;text-align: left;&quot;&gt;FROM&amp;nbsp;employees&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;text-align: left;&quot;&gt;WHERE department = 'IT';&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;//위와 같은 쿼리가 들어오면 아래의 트리구조로 변경이됨&lt;/span&gt;&lt;span style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SELECT&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;FILTER&amp;nbsp;(department&amp;nbsp;=&amp;nbsp;'IT')&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TABLE SCAN (employees)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #222222; text-align: left;&quot;&gt;```&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Optimization&lt;/b&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Query Trasformer&lt;/b&gt; : 파싱된 SQL을 보고, 동일한 결과를 도출하는 더 좋은 쿼리가 있으면 그것으로 바꿈&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Estimator&lt;/b&gt;: 시스템 통계정보를 딕셔너리로부터(통계정보 저장하는 저장소)&lt;br /&gt;수집하여 SQL을 실행할 때 소요되는 총비용을 계산한다&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Plan Generator&lt;/b&gt; : Estimator를 통해 계산된 값들을 토대로 후보군이 되는 실행계획을 도출한다&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Row-Source Genarator :&amp;nbsp;&lt;/b&gt;옵티마이저가 생성된 실행계획을 SQL 엔진이 실제 실행할 수 있는 코드나 프로시저 형태로 포맷팅 한다&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;postgresql을 예로들면 row-source genarator에 의해서 c언어로 된 함수가 생성되고, 그것을 엔진이 실행하는 형태라고 한다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;SQL Engine&lt;/b&gt; : sql을 실행합니다&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;통계정보&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비용기반 옵티마이저에서 실행계획을 짜기 위해서 사용되는 정보이다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 주기를 설정하여 디비가 자동으로 통계정보를 갱신하도록 할 수 도 있고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자가 직접 만든 통계정보를 사용하도록 할 수도 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;통계정보요소&lt;/b&gt;&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 140px;&quot; border=&quot;1&quot; data-pm-slice=&quot;3 3 []&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 13.8372%; height: 20px;&quot;&gt;&lt;span&gt;&lt;b&gt;테이블 크기&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 86.0465%; height: 20px;&quot;&gt;&lt;span&gt;테이블에 저장된 총 레코드 수로, 테이블의 규모를 파악하여 최적의 접근 방식을 결정하는 데 사용된다&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 13.8372%; height: 20px;&quot;&gt;&lt;span&gt;&lt;b&gt;데이터 분포&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 86.0465%; height: 20px;&quot;&gt;&lt;span&gt;특정 열의 값들이 어떻게 분포되어 있는지를 나타내며, 선택도를 예측하여 최적의 인덱스 사용 여부를 결정한다&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 13.8372%; height: 20px;&quot;&gt;&lt;span&gt;&lt;b&gt;인덱스 정보&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 86.0465%; height: 20px;&quot;&gt;&lt;span&gt;인덱스가 어떤 열에 적용되었는지, 그리고 그 인덱스의 효율성을 평가하여 실행 계획을 수립하는 데 사용됨&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;width: 13.8372%; height: 40px;&quot;&gt;&lt;span&gt;&lt;b&gt;널 값 비율&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 86.0465%; height: 40px;&quot;&gt;&lt;span&gt;특정 열에 널(null) 값이 얼마나 있는지를 나타내며, 옵티마이저가 조인이나 필터링 조건을 더 효율적으로 처리하도록 도움&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 13.8372%; height: 20px;&quot;&gt;&lt;span&gt;&lt;b&gt;데이터 블록 수&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 86.0465%; height: 20px;&quot;&gt;&lt;span&gt;테이블이나 인덱스를 저장하는 데 필요한 데이터 블록의 수로, I/O 비용을 예측하는 데 중요한 요소&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 13.8372%; height: 20px;&quot;&gt;&lt;span&gt;&lt;b&gt;클러스터링 팩터&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 86.0465%; height: 20px;&quot;&gt;&lt;span&gt;인덱스의 순서와 테이블의 실제 데이터 순서 간의 관계를 나타내며, 테이블에 대한 접근 비용을 추정하는 데 사용&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</description>
      <category>programming/database</category>
      <author>worldint</author>
      <guid isPermaLink="true">https://hwansci.tistory.com/169</guid>
      <comments>https://hwansci.tistory.com/169#entry169comment</comments>
      <pubDate>Sun, 1 Dec 2024 10:20:51 +0900</pubDate>
    </item>
    <item>
      <title>B+트리, B트리 비교</title>
      <link>https://hwansci.tistory.com/168</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;B+트리란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a title=&quot;B트리&quot; href=&quot;https://hwansci.tistory.com/163&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;B트리&lt;/a&gt;에서 확장된 개념으로, 리프 노드에만 실제 데이터를 담는다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;B+트리는 &lt;b&gt;리프 노드에만 데이터를 저장&lt;/b&gt;하고, 내부 노드에는 데이터가 아닌 키만을 저장한다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt; 키는 데이터를 찾기 위한 인덱스 역할을 하며, 실제 데이터는 리프 노드에서만 접근 가능&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이로 인해 모든 데이터 접근이 리프 노드에서 이루어지며, 데이터가 정렬된 형태로 연결되어 있다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;br /&gt;B+트리는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;리프 노드를 순차적으로 연결하는 포인터 집합&lt;/b&gt;을 가지고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;인덱스된 순차 파일 처리시,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;포인터를 이용하여, `키 : 값`을 일일이 비교하지 않고&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;다음 데이터에 접근해서 빠르게 처리&lt;/b&gt;할 수 있다.&lt;br /&gt;(이부분 무슨 말인지 이해가 안된다, 다시 알아보자)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1117&quot; data-origin-height=&quot;515&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DYxOo/btsK3RJFrcn/ZJHoaR3uTpXgoWRnm70beK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DYxOo/btsK3RJFrcn/ZJHoaR3uTpXgoWRnm70beK/img.png&quot; data-alt=&quot;https://en.wikipedia.org/wiki/B%2B_tree#/media/File:Bplustree.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DYxOo/btsK3RJFrcn/ZJHoaR3uTpXgoWRnm70beK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDYxOo%2FbtsK3RJFrcn%2FZJHoaR3uTpXgoWRnm70beK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;231&quot; data-origin-width=&quot;1117&quot; data-origin-height=&quot;515&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://en.wikipedia.org/wiki/B%2B_tree#/media/File:Bplustree.png&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #555555; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;데이터 삽입&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음 1,2가 노드에 들어있을때&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;227&quot; data-origin-height=&quot;75&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xVRRh/btsK2ooqBN6/8TdtJK3BUNT0KSR1z8zPfK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xVRRh/btsK2ooqBN6/8TdtJK3BUNT0KSR1z8zPfK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xVRRh/btsK2ooqBN6/8TdtJK3BUNT0KSR1z8zPfK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxVRRh%2FbtsK2ooqBN6%2F8TdtJK3BUNT0KSR1z8zPfK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;132&quot; data-origin-width=&quot;227&quot; data-origin-height=&quot;75&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3을 추가하면&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;178&quot; data-origin-height=&quot;108&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/y7U4k/btsK3wr77wA/Q9oKtOkSus3qAocapruke0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/y7U4k/btsK3wr77wA/Q9oKtOkSus3qAocapruke0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/y7U4k/btsK3wr77wA/Q9oKtOkSus3qAocapruke0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fy7U4k%2FbtsK3wr77wA%2FQ9oKtOkSus3qAocapruke0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;178&quot; height=&quot;108&quot; data-origin-width=&quot;178&quot; data-origin-height=&quot;108&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;노드의 최대 키을 초과하여( 3차이기 때문에 키는 2개가 최대이다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중간에 있는값 2 를 부모노드로 승격시킨다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 이때 b트리와 다른점은 데이터는 리프에서만 접근하기 때문에&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;부모노드로 2를 올려도 리프에 2가 계속 남아있어야한다&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;부모노드의 2는 탐색키 역활이다.(3을 찾고 싶을때 이것이 2보다 큰지 작은지 따지는 용도)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;217&quot; data-origin-height=&quot;101&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cBwMez/btsK2WZgO9t/xNMvVCbQywCD4MRsoWDKvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cBwMez/btsK2WZgO9t/xNMvVCbQywCD4MRsoWDKvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cBwMez/btsK2WZgO9t/xNMvVCbQywCD4MRsoWDKvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcBwMez%2FbtsK2WZgO9t%2FxNMvVCbQywCD4MRsoWDKvK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;217&quot; height=&quot;101&quot; data-origin-width=&quot;217&quot; data-origin-height=&quot;101&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 5를 추가하면&amp;nbsp;&lt;br /&gt;2보다 크기 때문에 [2,3]이 있는 노드에 5를 추가하고&lt;br /&gt;[2,3,5]가 되기 때문에 중간의 3을 부모노드에 추가하고 [2],[3,5]로 리프노드를 분할 하게된다&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #555555; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;데이터 삭제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*경우의 수가 다양하다고한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;217&quot; data-origin-height=&quot;101&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cBwMez/btsK2WZgO9t/xNMvVCbQywCD4MRsoWDKvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cBwMez/btsK2WZgO9t/xNMvVCbQywCD4MRsoWDKvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cBwMez/btsK2WZgO9t/xNMvVCbQywCD4MRsoWDKvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcBwMez%2FbtsK2WZgO9t%2FxNMvVCbQywCD4MRsoWDKvK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;217&quot; height=&quot;101&quot; data-origin-width=&quot;217&quot; data-origin-height=&quot;101&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 2를 삭제한다고 하면&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;206&quot; data-origin-height=&quot;100&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ch3In/btsK3sccVGP/KkK4bDhGvwrNUwYF6Z9nDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ch3In/btsK3sccVGP/KkK4bDhGvwrNUwYF6Z9nDk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ch3In/btsK3sccVGP/KkK4bDhGvwrNUwYF6Z9nDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCh3In%2FbtsK3sccVGP%2FKkK4bDhGvwrNUwYF6Z9nDk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;206&quot; height=&quot;100&quot; data-origin-width=&quot;206&quot; data-origin-height=&quot;100&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리프노드에서 2를 제거하고&lt;br /&gt;근데 노드의&amp;nbsp; 최소 키보다 작아지기 때문에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;형제 노드에서 3을 빌려온다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 부모노드를 알맞게 정리한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;B트리 vs B+트리&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 98px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;특성&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;B-트리&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;B+트리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;데이터 저장 위치&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;키와 데이터를 같은 노드에 저장&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;데이터는 리프 노드에만 저장&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;범위검색&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;상대적으로 비효율적&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;매우 효율적&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;단일 키 검색&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;더 빠를 수 있음&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;약간 느릴 수 있음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;삽입/삭제&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;간단&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;리프 노드에서 주로 작업, 포인터 조정 필요&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;b+트리가 범위 검색에 좋은 이유&lt;/b&gt; : &lt;b&gt;연속적 접근이 가능&amp;nbsp;&lt;/b&gt;하기 때문에,&lt;br /&gt;리프 노드의 시작점만 찾으면 나머지는 연결된 노드를 따라가며 데이터를 빠르게 읽을 수 있습니다.&lt;br /&gt;(예: id BETWEEN 10 AND 50)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 삽입 삭제 해볼 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html&lt;/a&gt;&lt;/p&gt;</description>
      <category>programming/algorithm_datastructure</category>
      <author>worldint</author>
      <guid isPermaLink="true">https://hwansci.tistory.com/168</guid>
      <comments>https://hwansci.tistory.com/168#entry168comment</comments>
      <pubDate>Sun, 1 Dec 2024 09:15:05 +0900</pubDate>
    </item>
    <item>
      <title>데이터베이스 Cluster</title>
      <link>https://hwansci.tistory.com/167</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;클러스터란?&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스 클러스터링은 여러 대의 데이터베이스 서버(노드)를 하나의 논리적인 데이터베이스처럼 동작하게 만드는것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 통해 &lt;code&gt;병렬처리&lt;/code&gt;, &lt;code&gt;고가용성&lt;/code&gt; ,&lt;code&gt;성능 향상&lt;/code&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;을 구현할 수 있다&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;고가용성&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 베이스에서 가용성이란&lt;br /&gt;&lt;b&gt;1년 동안 몇 분이 정지했음을 비율로 나타낸 것&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;고가용성&lt;/b&gt;이란 &lt;b&gt;데이터베이스 장비(서버나 스토리지 등)를 각 2대 이상으로 구성&lt;/b&gt;하여&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;한쪽에 장애가 발생하면 동일한 데이터를 가진 복제 데이터베이스(이중화된 데이터베이스)로&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;빠른 시간내에서비스를 재개할 수 있도록 하는 것&lt;/b&gt;을 의미&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;병렬처리&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터가 많거나, 복잡한 SQL을 실행하게 될 경우 많은 시간이 걸리게 된다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 동일한 데이터를 가지고 있는 여러 데이터베이스가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;복잡한 SQL을 나누어서 작업한뒤&lt;br /&gt;결과를 통합하여 넘겨준다면 훨씬 빠르게 결과를 얻을 수 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;병렬처리가 될 수 있는 작업들을 디비들에게 잘 나누어 주어야한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;성능 향상&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조회같은경우 사용자가 많아졌을 때, 어차피 같은 데이터를 가지고 있기 때문에&amp;nbsp;&lt;br /&gt;여러개의 디비에 부하를 분산 시켜 성능 향상을 시킬 수 있다&lt;/p&gt;</description>
      <category>programming/database</category>
      <author>worldint</author>
      <guid isPermaLink="true">https://hwansci.tistory.com/167</guid>
      <comments>https://hwansci.tistory.com/167#entry167comment</comments>
      <pubDate>Sat, 23 Nov 2024 12:04:43 +0900</pubDate>
    </item>
    <item>
      <title>데이터베이스 트랜잭션</title>
      <link>https://hwansci.tistory.com/166</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;트랜잭션이란 무엇인가?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트랜잭션은 데이터베이스에서 하나의 논리적 작업 단위로 간주되는 일련의 연산&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 은행 이체 작업을 예로 들어 설명한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;은행 계좌 이체 작업은 한쪽의 출금과 반대쪽의 입금 두 가지 연산이 함께 이루어져야만 올바른 결과를 가져온다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트랜잭션은 이러한 일련의 작업들이 모두 성공하거나 모두 실패하도록 보장하여 데이터의 일관성을 유지합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;ACID&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관계형 데이터 베이스에서 하나의 트랜잭션(transaction)의 안전성을 보장하기 위해 필요한 성질&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트랜잭션은 &lt;b&gt;ACID&lt;/b&gt;라는 네 가지 기본 특성을 준수해야 한다&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;원자성(Atomicity):&lt;/b&gt; 트랜잭션 내의 모든 연산은 하나의 단위로 처리되어야 함&lt;br /&gt;일부만 실행되거나 취소되는 일이 없어야 하며, 모두 성공하거나 모두 실패해야 함&lt;br /&gt;예)디비에서 A테이블에 insert를하고, 그것과 연관된 B테이블을 수정하는 작업이 하나의 트랜잭션일때,&lt;br /&gt;B테이블 수정에서 에러가 났을때 A테이블 insert 작업도 다시 원복되어야한다&lt;/li&gt;
&lt;li&gt;&lt;b&gt;일관성(Consistency):&lt;/b&gt; 트랜잭션 실행 전후에 데이터베이스는 일관된 상태를 유지해야 한다&lt;br /&gt;이는 모든 데이터 무결성 제약 조건이 항상 만족됨을 의미&lt;br /&gt;예) &lt;code&gt;학생&lt;/code&gt;테이블과 &lt;code&gt;수강기록&lt;/code&gt;테이블이 있을때, 학생 한명이 삭제되었는데 그 학생의 수강기록은 남아있으면 안된다&lt;/li&gt;
&lt;li&gt;&lt;b&gt;격리성(Isolation):&lt;/b&gt; 동시에 실행되는 트랜잭션들은 서로 간섭하지 않아야 한다&lt;br /&gt;하나의 트랜잭션이 완료되기 전까지는 다른 트랜잭션이 그 변경 내용을 볼 수 없다&lt;/li&gt;
&lt;li&gt;&lt;b&gt;지속성(Durability):&lt;/b&gt; 트랜잭션이 성공적으로 커밋되면 그 결과는 영구적으로 저장되어야 함&lt;br /&gt;시스템 오류가 발생하더라도 데이터는 손실되지 않아야 한다&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;ACID는 완벽히 지켜지는게 아니고&lt;br /&gt;상황에 따라(아래의 격리 수준에 따라) 다른 강도로 지켜진다&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;격리 수준(Isolation Levels)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트랜잭션 간의 격리성을 제어하기 위해 다양한 격리 수준이 존재한다&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Read Uncommitted:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;특징&lt;/b&gt; : 가장 낮은 수준으로, 커밋되지 않은 데이터도 읽을 수 있다&lt;/li&gt;
&lt;li&gt;&lt;b&gt;문제점 : &lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;더티 리드 (Dirty Read):
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;하나의 트랜잭션에서 변경된 데이터가 커밋되지 않았는데, 다른 트랜잭션이 이를 읽음.&lt;/li&gt;
&lt;li&gt;이후 원래 트랜잭션이 롤백하면 잘못된 데이터를 읽은 상태가 됨.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;데이터 일관성이 전혀 보장되지 않아 &lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;RDBMS 표준에는 격리수준으로 인정하지 않는다고 한다&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Read Committed:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;특징:&lt;/b&gt; 커밋된 데이터만 읽을 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;문제점&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;비반복 읽기 (Non-Repeatable Read):
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;동일한 트랜잭션에서 같은 데이터를 두 번 조회할 때, 다른 트랜잭션이 데이터를 수정하고 커밋하면 결과가 달라질 수 있음.&lt;/li&gt;
&lt;li&gt;데이터가 일관되지 않게 보이는 문제를 초래.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Repeatable Read(반복 가능 읽기):&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;특징&lt;/b&gt; : 동일한 트랜잭션 내에서는 같은 데이터를 읽을 때 항상 동일한 결과를 반환한다&lt;/li&gt;
&lt;li&gt;문제점 :&amp;nbsp;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;팬텀 리드 (Phantom Read)&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;트랜잭션이 실행 중일 때, 다른 트랜잭션이 새로운 데이터를 삽입하면 동일한 조건으로 데이터를 조회했을 때 결과가 달라짐.&lt;/li&gt;
&lt;li&gt;예를 들어, 동일 트랜잭션에서 SELECT COUNT(*) FROM table이 10을 반환했는데, 다른 트랜잭션이 새 데이터를 삽입하면 그다음 작업에서 재조회 시 11로 반환됨.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Serializable:&lt;/b&gt;&amp;nbsp;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;특징&lt;/b&gt;: 가장 높은 수준으로, 트랜잭션을 순차적으로 실행한 것과 동일한 결과를 보장.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;문제점&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;동시성 문제가 거의 발생하지 않지만, &lt;b&gt;성능 저하&lt;/b&gt;가 심각.&lt;/li&gt;
&lt;li&gt;트랜잭션 간의 락(lock)이 많이 발생하여 &lt;b&gt;병목현상&lt;/b&gt;이 생길 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;격리 수준이 높아 질 수록 성능은 낮아진다&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;동시성 제어와 잠금(Locking)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동시에 여러 트랜잭션이 실행될 때 데이터의 일관성을 유지하기 위해 동시성 제어가 필요하다&lt;br /&gt;이를 위해 잠금 메커니즘이 사용되며, 데이터에 대한 읽기 및 쓰기 잠금을 통해 트랜잭션 간의 충돌을 방지한다&lt;br /&gt;락의 종류 : &lt;a href=&quot;https://hwansci.tistory.com/160&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://hwansci.tistory.com/160&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트랜잭션에서 각각의 격리수준에 따라 발생할 수 있는 문제점 추가&lt;/p&gt;</description>
      <category>programming/database</category>
      <author>worldint</author>
      <guid isPermaLink="true">https://hwansci.tistory.com/166</guid>
      <comments>https://hwansci.tistory.com/166#entry166comment</comments>
      <pubDate>Sat, 23 Nov 2024 11:26:37 +0900</pubDate>
    </item>
    <item>
      <title>이진트리, 이진탐색트리</title>
      <link>https://hwansci.tistory.com/164</link>
      <description>&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이진 트리 (Binary Tree):&amp;nbsp;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;이진 트리는 각 노드가 최대 두 개의 자식 노드를 가지는 트리 구조&lt;/li&gt;
&lt;li&gt;단순히 각 노드가 자식노드를 2개 이하로 가질 수 있다는 조건만 만족하면 그것은 이진트리라 할 수 있다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot 2024-11-11 at 1.15.30 PM.png&quot; data-origin-width=&quot;452&quot; data-origin-height=&quot;326&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9AKkQ/btsKESa7nLm/dy8K28ByEHtOtnm8wY96Qk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9AKkQ/btsKESa7nLm/dy8K28ByEHtOtnm8wY96Qk/img.png&quot; data-alt=&quot;이진트리&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9AKkQ/btsKESa7nLm/dy8K28ByEHtOtnm8wY96Qk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9AKkQ%2FbtsKESa7nLm%2Fdy8K28ByEHtOtnm8wY96Qk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;452&quot; height=&quot;326&quot; data-filename=&quot;Screenshot 2024-11-11 at 1.15.30 PM.png&quot; data-origin-width=&quot;452&quot; data-origin-height=&quot;326&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이진트리&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;이진 탐색 트리 (Binary Search Tree, BST)&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이진 탐색 트리는 이진 트리의 한 종류이지만, 추가적인&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;정렬 조건&lt;/b&gt;을 만족해야 한다&lt;/li&gt;
&lt;li&gt;각 노드의 왼쪽 자식에는 해당 노드보다 작은 값이, 오른쪽 자식에는 더 큰 값이 위치해야 한다&lt;/li&gt;
&lt;li&gt;이런 조건을 만족함으로써 탐색 속도를 빠르게 할 수 있습니다. 왼쪽으로 가면 항상 더 작은 값을 찾고, 오른쪽으로 가면 더 큰 값을 찾을 수 있어 탐색 과정이 효율적입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>programming/algorithm_datastructure</category>
      <author>worldint</author>
      <guid isPermaLink="true">https://hwansci.tistory.com/164</guid>
      <comments>https://hwansci.tistory.com/164#entry164comment</comments>
      <pubDate>Mon, 11 Nov 2024 13:11:03 +0900</pubDate>
    </item>
    <item>
      <title>B-tree</title>
      <link>https://hwansci.tistory.com/163</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;binary search tree&lt;/code&gt; 에서 파생된것으로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;BST&lt;/code&gt;에서 자식노드의 갯수에 제한을 없앤 것이 &lt;code&gt;b-tree&lt;/code&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자식노드의 갯수가 3개 이상이려면&lt;br /&gt;부모노드의 key도 하나 이상 이어야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자식노드의 갯수에 따라 n차 b-tree로 불리는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시는 자식노드가 3개이므로 3차 B-tree이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부모노드의 key들은 오름차순으로 정렬된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;B-트리에서 각 자식 노드는 부모 노드의 키 값들에 의해 포함할 수 있는 키 값의 범위가 결정된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;710&quot; data-origin-height=&quot;256&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c0NRYm/dJMcagDN7kJ/6HCDJ2FxC4eJI8aYpEk0KK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c0NRYm/dJMcagDN7kJ/6HCDJ2FxC4eJI8aYpEk0KK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c0NRYm/dJMcagDN7kJ/6HCDJ2FxC4eJI8aYpEk0KK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc0NRYm%2FdJMcagDN7kJ%2F6HCDJ2FxC4eJI8aYpEk0KK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;710&quot; height=&quot;256&quot; data-origin-width=&quot;710&quot; data-origin-height=&quot;256&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;root 노드 아랫 줄을 보면&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왼쪽 노드에는 20보다 작은 값의 키 들이 들어갈 수 있고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가운데에는 20보다 크고 40보다 작은 키,&lt;br /&gt;오른쪽은 40보다 큰 키값이 들어가게 된다&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;B-tree의 중요한 파라미터들로는&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;최대로 가질 수 있는 자식노드의 수 (M) :&amp;nbsp; &amp;nbsp;M에 따라 M차 B-tree로 불린다. 위의 예시에서는 3&lt;/li&gt;
&lt;li&gt;각 노드의 최대 key의 수 (M-1) :&amp;nbsp; 노드에 들어있는 숫자의 갯수를 말함, 3차 b-tree는 최대 2개까지 들어있을 수 있다&lt;/li&gt;
&lt;li&gt;각 노드의 최소 자녀 노드 수 (⎡M/2⎤): M/2의 올림, M이 3일때 2&lt;br /&gt;(&lt;i&gt;leef, root노드는 제외&lt;/i&gt;)&lt;/li&gt;
&lt;li&gt;각 노드의 최소 key 수 (⎡M/2⎤- 1 ) : 예시에서는 1&lt;br /&gt;(root node제외)&lt;/li&gt;
&lt;li&gt;b-tree에서 internal node의 key가 x라면 자식노드의 수는 x+1&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;데이터 삽입 과정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;데이터 삽입 할 때 시간복잡도&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;데이터 삭제 과정&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;데이터 삭제 할 때 시간복잡도&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;데이터 조회 과정&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;데이터 조회시의 시간복잡도&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;O(logN)의 시간 복잡도를 가짐&lt;br /&gt;N은 테이터의 갯수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 데이터가 100개일 때, 3차 B-tree라면 $\log_3 100$&lt;br /&gt;으로 4~5의 값이 나오고&lt;br /&gt;그럼 높이가 4개에서 5개정도가 나오고 시간 복잡도도 그정도 나온다&lt;/p&gt;</description>
      <category>programming/algorithm_datastructure</category>
      <author>worldint</author>
      <guid isPermaLink="true">https://hwansci.tistory.com/163</guid>
      <comments>https://hwansci.tistory.com/163#entry163comment</comments>
      <pubDate>Mon, 11 Nov 2024 13:10:31 +0900</pubDate>
    </item>
    <item>
      <title>데이터베이스 파티셔닝</title>
      <link>https://hwansci.tistory.com/162</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;디비 파티셔닝이란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;큰 테이블을 파티션이라는 작은 단위로 나누어 관리하는것&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;사용 이유&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 DBMS에 너무 큰 table이 들어가면서 용량과 성능 측면에서 많은 이슈가 발생하게 되었고,&lt;br /&gt;이런 이슈를 해결하기 위한 방법으로 table을 &amp;lsquo;파티션(partition)&amp;rsquo;이라는 작은 단위로 나누어 관리하는 &amp;lsquo;파티셔닝(Partitioning)&amp;rsquo;기법 이 나타나게 되었다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;파티션이라는 단위는 무엇인가?&lt;/b&gt;&lt;br /&gt;하나의 파티션은 데이터베이스 내에서 데이터가 물리적으로 분리되어 저장되는 단위를 말하며,&lt;br /&gt;주로 특정 조건에 따라 분리된다&lt;br /&gt;&lt;br /&gt;아래는 그 조건들의 예시&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;범위 단위 (Range)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 값의 범위를 기준으로 데이터를 분리&lt;/li&gt;
&lt;li&gt;예를 들어, 날짜가 &quot;2024-01-01&quot;부터 &quot;2024-12-31&quot;까지인 데이터를 하나의 파티션으로 저장하고, 다른 연도의 데이터는 별도의 파티션에 저장하는 것&lt;/li&gt;
&lt;li&gt;&lt;b&gt;장점&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;데이터 검색 속도 향상&lt;/b&gt;: 특정 범위에 대해 쿼리할 때 성능이 향상됨. 예를 들어 날짜별 로그 데이터를 자주 조회한다면, 날짜별로 분리하여 조회 성능을 크게 개선할 수 있음.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;직관적인 관리&lt;/b&gt;: 파티션 구간이 명확하여 관리가 쉬움. 특정 범위의 데이터가 증가하거나 줄어드는 패턴을 쉽게 파악 가능.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;단점&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;데이터 불균형 가능성&lt;/b&gt;: 데이터 분포가 고르지 않을 경우 특정 파티션에 데이터가 집중되어 파티션 간의 부하가 균형을 이루지 못할 수 있음.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;파티션 관리&lt;/b&gt;: 새로운 구간의 데이터가 들어올 경우 파티션을 수동으로 추가해야 하며, 관리가 번거로울 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;해시 단위 (Hash)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;해시 함수를 사용해 고르게 데이터를 분산하는 방식&lt;/li&gt;
&lt;li&gt;예를 들어, 고객 ID의 해시 값을 기준으로 데이터를 나누어, 특정 파티션에 데이터가 몰리지 않도록 합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;장점&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;균일한 분포&lt;/b&gt;: 데이터를 해시를 통해 분산하므로 파티션 간 데이터 분포가 균일하여 특정 파티션에 데이터가 몰리는 현상을 방지할 수 있음.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;확장성&lt;/b&gt;: 대규모 데이터를 다룰 때 파티션이 균등하게 분산되므로 확장성이 좋음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;단점&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;범위 조회 어려움&lt;/b&gt;: 범위를 기준으로 데이터를 조회하는 경우 비효율적임. 데이터를 특정 범위로 쿼리할 때 여러 파티션에 분산되어 있어 조회 비용이 커질 수 있음.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;관리의 어려움&lt;/b&gt;: 해시 분포가 변하면 모든 데이터를 재분산해야 하므로 파티션 키 변경이나 확장이 어려움.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;리스트 단위 (List)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 값 리스트에 따라 데이터를 분리합니다. 예를 들어, &amp;lsquo;서울&amp;rsquo;, &amp;lsquo;부산&amp;rsquo;, &amp;lsquo;인천&amp;rsquo; 등과 같이 특정 도시에 따라 데이터를 나누는 것이 가능합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;장점&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;명확한 파티션 전략&lt;/b&gt;: 특정 값에 따라 파티션을 지정할 수 있어 직관적이고 명확하게 분류 가능. 예를 들어 국가 코드나 카테고리별로 데이터를 구분할 때 유리함.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;필터링 성능 향상&lt;/b&gt;: 각 파티션에 대해 명확히 정의된 값을 사용하여 필터링할 경우 성능이 향상됨.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;단점&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;리스트 변경의 복잡성&lt;/b&gt;: 새로운 값이 추가되거나 삭제되는 경우 파티션 전략을 재정의해야 하며, 관리가 복잡해질 수 있음.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;데이터 불균형 가능성&lt;/b&gt;: 특정 리스트 값에 데이터가 집중될 경우 특정 파티션에 데이터가 몰리게 되어 성능 문제가 발생할 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: none;&quot;&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 파티션은 데이터를 저장하는 &lt;b&gt;파일&lt;/b&gt;로 존재하거나,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;데이터 블록&lt;/b&gt;이나 &lt;b&gt;데이터 페이지&lt;/b&gt; 등과 같은 하위 단위로 구성될 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;논리적으로는 하나의 테이블의 일부로서 취급되지만,&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;물리적으로는 분리된 공간에 저장되어, 필요한 데이터에만 빠르게 접근할 수 있게 해준다&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>programming/database</category>
      <author>worldint</author>
      <guid isPermaLink="true">https://hwansci.tistory.com/162</guid>
      <comments>https://hwansci.tistory.com/162#entry162comment</comments>
      <pubDate>Thu, 7 Nov 2024 19:19:46 +0900</pubDate>
    </item>
    <item>
      <title>데이터베이스 인덱스</title>
      <link>https://hwansci.tistory.com/161</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;b&gt;데이터베이스 인덱스란?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;데이터베이스 인덱스는 책의 목차와 비슷한 역할이다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt; 데이터베이스에서 원하는 데이터를 더 빠르게 찾을 수 있도록 도와주는 도구&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;인덱스를 사용하면 검색 속도를 크게 향상시킬 수 있으며, 이는 특히 대량의 데이터를 다룰 때 중요함&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;b&gt;왜 인덱스를 사용하는가?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;만약 인덱스가 없다면, 특정 레코드를 찾기 위해 모든 레코드를 하나씩 확인해야 함&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 인덱스를 사용하면 특정 컬럼의 값을 기준으로 데이터를 빠르게 찾아낼 수 있다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;사전에서 특정 단어를 찾을 때,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;앞에서 부터 한장씩 넘기는것이 아닌&lt;br /&gt;'사과' 면 'ㅅ' 부분으로 바로 넘어가서 찾는것과 비슷한 이치&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;b&gt;인덱스의 종류&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-spread=&quot;true&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;B-Tree 인덱스&lt;/b&gt;&lt;/span&gt;&lt;span&gt;: 가장 일반적으로 사용되는 인덱스 타입&lt;br /&gt;데이터를 트리 구조로 관리하여 빠르게 검색, 삽입, 삭제가 가능하다 대부분의 관계형 데이터베이스에서 기본 인덱스 타입으로 사용됨&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt; B-Tree는 트리 구조로 데이터를 저장하여 검색 속도를 빠르게 함&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;책의 목차처럼 분기점을 따라가며 원하는 데이터를 효율적으로 찾을 수 있다&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;해시 인덱스&lt;/b&gt;&lt;/span&gt;&lt;span&gt;: 해시 함수로 데이터를 빠르게 찾을 수 있도록 한다 특정 키에 대해 빠른 조회가 가능하지만 범위 검색은 지원하지 않음&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt; 해시 인덱스는 데이터를 특정 키에 대해 해시 값으로 매핑하여 빠르게 접근할 수 있게 한다&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;이는 &lt;b&gt;특정 값을 정확히 찾는 데 유리&lt;/b&gt;하지만, 범위 검색에는 적합하지 않음&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;텍스트 인덱스&lt;/b&gt;&lt;/span&gt;&lt;span&gt;: 대량의 텍스트 데이터를 검색할 때 유용&lt;br /&gt;예를 들어 블로그나 뉴스 기사에서 특정 키워드를 검색할 때 사용됨&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt; 텍스트 인덱스는 텍스트 데이터의 빠른 검색을 위해 최적화되어 있다&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;블로그나 뉴스 사이트와 같은 대량의 텍스트 기반 콘텐츠에서 특정 키워드를 쉽게 찾을 수 있게 해줌&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;인덱스의 단점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;인덱스는 데이터를 빠르게 찾을 수 있도록 도와주지만, &lt;br /&gt;&lt;/span&gt;&lt;span&gt;인덱스를 추가하면 데이터 삽입, 수정, 삭제 작업의 성능이 저하될 수 있댜&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;인덱스를 유지하기 위해 데이터가 변경될 때마다 추가적인 작업이 필요하기 때문에&lt;br /&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;모든 컬럼에 인덱스를 만드는 것은 오히려 역효과를 낳는다&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;자주 사용되는 검색 조건이나 정렬 기준으로 인덱스를 설정하는 것이 좋음&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>programming/database</category>
      <author>worldint</author>
      <guid isPermaLink="true">https://hwansci.tistory.com/161</guid>
      <comments>https://hwansci.tistory.com/161#entry161comment</comments>
      <pubDate>Sat, 26 Oct 2024 16:09:51 +0900</pubDate>
    </item>
  </channel>
</rss>