<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>JJ_blog</title>
    <link>https://hj39-develop.tistory.com/</link>
    <description>도전!</description>
    <language>ko</language>
    <pubDate>Wed, 8 Apr 2026 00:37:20 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>HJ39</managingEditor>
    <image>
      <title>JJ_blog</title>
      <url>https://tistory1.daumcdn.net/tistory/4804432/attach/f07555153f9646a4a32659c7d43a61d4</url>
      <link>https://hj39-develop.tistory.com</link>
    </image>
    <item>
      <title>Semaphore Vs Mutex</title>
      <link>https://hj39-develop.tistory.com/204</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Mutex&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Mutual Exclusion의 합성어로 공유된 자원의 데이터나 임계영역(critical Section) 같은 곳에 스레드들의 서로 겹치지 않거나 하나의 프로세스나 스레드가 접근하는 것을 막는다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;동기화 대상이 1개&lt;/li&gt;
&lt;li&gt;다른 스레드들은 뮤텍스의 lock을 가지기 위해 대기하고 락을 해제하는 스레드가 있을 때까지 접근하지 못한다.&lt;/li&gt;
&lt;li&gt;Key 기반으로 한 상호배제 기법이다.&lt;/li&gt;
&lt;li&gt;다중 프로세스들의 공유 리소스에 접근을 조율하기 위해 동기화(Sync) 또는 락(Lock)을 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림을 보면 쉽게 이해할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;912&quot; data-origin-height=&quot;726&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ceiTQe/btsC9zdDxQl/K3WtAhtRwYGhxr6Kk1Q4k1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ceiTQe/btsC9zdDxQl/K3WtAhtRwYGhxr6Kk1Q4k1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ceiTQe/btsC9zdDxQl/K3WtAhtRwYGhxr6Kk1Q4k1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FceiTQe%2FbtsC9zdDxQl%2FK3WtAhtRwYGhxr6Kk1Q4k1%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;600&quot; height=&quot;726&quot; data-origin-width=&quot;912&quot; data-origin-height=&quot;726&quot;/&gt;&lt;/span&gt;&lt;/figure&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;하지만 이용을 마친 누군가가 Key를 카운터에 다시 가져다 놓으면 다른 사람들이 화장실을 이용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 방법이 Mutex이다.&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;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Semaphore&lt;/b&gt;&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;공유 자원에 접근할 수 있는 프로세스의 최대 허용치만큼 동시에 접근할 수 있다.&lt;/li&gt;
&lt;li&gt;다른 프로세스들이 모두 사용 중인 경우 기다려야 한다.&lt;/li&gt;
&lt;/ul&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;993&quot; data-origin-height=&quot;427&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qbaUS/btsDhVTyTqw/Ls6Fr05Yai9DPKPw49oV0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qbaUS/btsDhVTyTqw/Ls6Fr05Yai9DPKPw49oV0K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qbaUS/btsDhVTyTqw/Ls6Fr05Yai9DPKPw49oV0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqbaUS%2FbtsDhVTyTqw%2FLs6Fr05Yai9DPKPw49oV0K%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;600&quot; height=&quot;427&quot; data-origin-width=&quot;993&quot; data-origin-height=&quot;427&quot;/&gt;&lt;/span&gt;&lt;/figure&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;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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;차이점&lt;/b&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 77.0921%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style14&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.8944%; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 31.184%; text-align: center;&quot;&gt;&lt;b&gt;Mutex&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 29.7144%; text-align: center;&quot;&gt;&lt;b&gt;Semaphore&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.8944%; text-align: center;&quot;&gt;&lt;b&gt;동기화 개수&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 31.184%; text-align: center;&quot;&gt;1개&lt;/td&gt;
&lt;td style=&quot;width: 29.7144%; text-align: center;&quot;&gt;1개 이상&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.8944%; text-align: center;&quot;&gt;&lt;b&gt;자원 소유&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 31.184%; text-align: center;&quot;&gt;자원 소유가 가능&lt;br /&gt;+&lt;br /&gt;책임&lt;/td&gt;
&lt;td style=&quot;width: 29.7144%; text-align: center;&quot;&gt;자원 소유 불가&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.8944%; text-align: center;&quot;&gt;&lt;b&gt;해제&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 31.184%; text-align: center;&quot;&gt;소유하고 있는 스레드만이 해제가능하다.&lt;/td&gt;
&lt;td style=&quot;width: 29.7144%; text-align: center;&quot;&gt;소유하지 않는 스레드도 해제할 수 있다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.8944%; text-align: center;&quot;&gt;&lt;b&gt;범위&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 31.184%; text-align: center;&quot;&gt;프로세스의 범위를 가지고&lt;br /&gt;종료될때 자동으로 사라진다.&lt;/td&gt;
&lt;td style=&quot;width: 29.7144%; text-align: center;&quot;&gt;시스템 범위에 걸쳐있고&lt;br /&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;/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;
&lt;p data-ke-size=&quot;size16&quot;&gt;# 참고한 사이트&lt;/p&gt;
&lt;figure id=&quot;og_1704785282317&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[OS] 뮤텍스(Mutex)와 세마포어(Semaphore)란?&quot; data-og-description=&quot;프로세스 간 메시지를 전송하거나, 공유메모리를 통해 공유된 자원에 여러 개의 프로세스가 동시에 접근하면 Critical Section 문제가 발생할 수 있다. 이를 해결하기 위해 데이터를 한 번에 하나의 &quot; data-og-host=&quot;chelseashin.tistory.com&quot; data-og-source-url=&quot;https://chelseashin.tistory.com/40&quot; data-og-url=&quot;https://chelseashin.tistory.com/40&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/iBVNR/hyU2nk7oD1/MkkXz8HWPIduqOCKGUwIg1/img.png?width=468&amp;amp;height=204&amp;amp;face=0_0_468_204,https://scrap.kakaocdn.net/dn/fuEse/hyU2fACkKl/BBLwZznEIrSFEQVE2SyPq0/img.png?width=468&amp;amp;height=204&amp;amp;face=0_0_468_204,https://scrap.kakaocdn.net/dn/cKewbz/hyU2rnwc09/dkAGr51dSRiEu56BjAVDjK/img.png?width=438&amp;amp;height=245&amp;amp;face=0_0_438_245&quot;&gt;&lt;a href=&quot;https://chelseashin.tistory.com/40&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://chelseashin.tistory.com/40&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/iBVNR/hyU2nk7oD1/MkkXz8HWPIduqOCKGUwIg1/img.png?width=468&amp;amp;height=204&amp;amp;face=0_0_468_204,https://scrap.kakaocdn.net/dn/fuEse/hyU2fACkKl/BBLwZznEIrSFEQVE2SyPq0/img.png?width=468&amp;amp;height=204&amp;amp;face=0_0_468_204,https://scrap.kakaocdn.net/dn/cKewbz/hyU2rnwc09/dkAGr51dSRiEu56BjAVDjK/img.png?width=438&amp;amp;height=245&amp;amp;face=0_0_438_245');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[OS] 뮤텍스(Mutex)와 세마포어(Semaphore)란?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;프로세스 간 메시지를 전송하거나, 공유메모리를 통해 공유된 자원에 여러 개의 프로세스가 동시에 접근하면 Critical Section 문제가 발생할 수 있다. 이를 해결하기 위해 데이터를 한 번에 하나의&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;chelseashin.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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;
&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>CS/OS</category>
      <category>OS</category>
      <author>HJ39</author>
      <guid isPermaLink="true">https://hj39-develop.tistory.com/204</guid>
      <comments>https://hj39-develop.tistory.com/204#entry204comment</comments>
      <pubDate>Tue, 9 Jan 2024 17:11:54 +0900</pubDate>
    </item>
    <item>
      <title>Component Scan</title>
      <link>https://hj39-develop.tistory.com/203</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;의존 관계 자동 주입&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;설정정보가 없어도 자동으로 스프링 빈을 등록해 준다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;@Autowired 기능도 제공해 준다.&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;&lt;b&gt;사용방법&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;□ Config파일에 &lt;b&gt;&lt;span style=&quot;background-color: #ee2323; color: #ffffff;&quot;&gt;@ComponentScan&lt;/span&gt;&lt;/b&gt; Annotation 붙이기&lt;/p&gt;
&lt;pre id=&quot;code_1704727797451&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Configuration
@ComponentScan
public class AutoAppConfig {

}&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;□ 스프링 빈에 등록할 클래스들에 &lt;b&gt;&lt;span style=&quot;background-color: #ee2323; color: #ffffff;&quot;&gt;@Component&lt;/span&gt;&lt;/b&gt; Annotation을 붙인다.&lt;/p&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #ffffff;&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;@Component
public class MemoryMemberRepository implements MemberRepository {}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #ffffff;&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;@Component
public class RateDiscountPolicy implements DiscountPolicy {}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1704728114559&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Component
 public class MemberServiceImpl implements MemberService {
     private final MemberRepository memberRepository;
     
     @Autowired
     public MemberServiceImpl(MemberRepository memberRepository) {
         this.memberRepository = memberRepository;
     }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성자에 &lt;b&gt;&lt;span style=&quot;background-color: #ee2323; color: #ffffff;&quot;&gt;@Autowired&lt;/span&gt;&lt;/b&gt; Annotation을 붙이면 자동으로 객체를 주입시켜 준다.&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;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;b&gt;&lt;span style=&quot;background-color: #ee2323; color: #ffffff;&quot;&gt;@ComponentScan&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-09 00.36.57.png&quot; data-origin-width=&quot;1646&quot; data-origin-height=&quot;736&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dH6PSe/btsDfU8bbCG/JhKImhZBr5gceOsXxA52kK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dH6PSe/btsDfU8bbCG/JhKImhZBr5gceOsXxA52kK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dH6PSe/btsDfU8bbCG/JhKImhZBr5gceOsXxA52kK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdH6PSe%2FbtsDfU8bbCG%2FJhKImhZBr5gceOsXxA52kK%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;600&quot; height=&quot;736&quot; data-filename=&quot;스크린샷 2024-01-09 00.36.57.png&quot; data-origin-width=&quot;1646&quot; data-origin-height=&quot;736&quot;/&gt;&lt;/span&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;&lt;span style=&quot;background-color: #ee2323; color: #ffffff;&quot;&gt;@ComponentScan&lt;/span&gt;&lt;/b&gt;은 &lt;b&gt;&lt;span style=&quot;background-color: #ee2323; color: #ffffff;&quot;&gt;@Component&lt;/span&gt;&lt;/b&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;□ &lt;b&gt;&lt;span style=&quot;background-color: #ee2323; color: #ffffff;&quot;&gt;@Autowired &lt;/span&gt;&lt;/b&gt;의존관계 자동 주입&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-09 00.39.07.png&quot; data-origin-width=&quot;1646&quot; data-origin-height=&quot;714&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/96KGU/btsC51hfFxy/xKe1Ipo7nSikVK0v3cORgk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/96KGU/btsC51hfFxy/xKe1Ipo7nSikVK0v3cORgk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/96KGU/btsC51hfFxy/xKe1Ipo7nSikVK0v3cORgk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F96KGU%2FbtsC51hfFxy%2FxKe1Ipo7nSikVK0v3cORgk%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;600&quot; height=&quot;714&quot; data-filename=&quot;스크린샷 2024-01-09 00.39.07.png&quot; data-origin-width=&quot;1646&quot; data-origin-height=&quot;714&quot;/&gt;&lt;/span&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;&lt;span style=&quot;background-color: #ee2323; color: #ffffff;&quot;&gt;@Autowired&lt;/span&gt;&lt;/b&gt;를 지정하면 스프링 컨테이너가 자동으로 해당 스프링 빈을 찾아서 주입한다.&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;&lt;b&gt;탐색 위치와 기본 스캔 대상&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 자바 클래스들을 스캔하면 너무 오래 걸린다. 따라서 꼭 필요한 위치부터 탐색하도록 시작 위치를 지정할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1704728470877&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@ComponentScan(
         basePackages = &quot;hello.core&quot;,
}&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;package를 &quot;hello.core&quot;로 시작위치를 정할 수 있다. 해당 패키지 하위 패키지를 모두 탐색한다.&lt;/li&gt;
&lt;li&gt;지정하지 않은 경우 &lt;b&gt;&lt;span style=&quot;background-color: #ee2323; color: #ffffff;&quot;&gt;@ComponentScan&lt;/span&gt;&lt;/b&gt;이 붙은 설정 정보 클래스의 패키지가 시작 위치가 된다.&lt;/li&gt;
&lt;li&gt;설정 정보 클래스의 위치를 프로젝트 최상단에 두는 것을 권장한다.&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;&lt;b&gt;컴포넌트 스캔 대상&lt;/b&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 53.3721%; height: 181px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 36.4924%; text-align: center;&quot;&gt;&lt;b&gt;종류&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 63.5076%; text-align: center;&quot;&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 36.4924%;&quot;&gt;&lt;b&gt;@Component&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 63.5076%;&quot;&gt;- 컴포넌트 스캔에서 사용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 36.4924%;&quot;&gt;&lt;b&gt;@Controller&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 63.5076%;&quot;&gt;- 스프링 MVC 컨트롤러에서 사용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 36.4924%;&quot;&gt;&lt;b&gt;@Service&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 63.5076%;&quot;&gt;- 스프링 비즈니스 로직에서 사용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 36.4924%;&quot;&gt;&lt;b&gt;@Repository&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 63.5076%;&quot;&gt;- 스프링 데이터 접근 계층에서 사용&lt;br /&gt;- 데이터 계층의 예외를 스프링 예외로 변환&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 36.4924%;&quot;&gt;&lt;b&gt;@Configuration&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 63.5076%;&quot;&gt;- 스프링 설정 정보에서 사용&lt;br /&gt;- 스프링 빈이 싱글톤을 유지하도록 추가 처리&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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;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;b&gt;□ 자동 빈 등록 vs 자동 빈 등록&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #ffffff;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컴포넌트 스캔에 의해 자동으로 스프링 빈이 등록되는데, 이름이 같은 경우 스프링은 오류를 발생시킨다.
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;ConflictingBeanDefinitionException 예외 발생&lt;/li&gt;
&lt;/ul&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;&lt;b&gt;□ 수동 빈 등록 vs 자동 빈 등록&lt;/b&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&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_1704729019394&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true`&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;하지만 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;spring.main.allow-bean-definition-overriding=true&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;/p&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;</description>
      <category>Backend/Spring</category>
      <category>spring</category>
      <author>HJ39</author>
      <guid isPermaLink="true">https://hj39-develop.tistory.com/203</guid>
      <comments>https://hj39-develop.tistory.com/203#entry203comment</comments>
      <pubDate>Tue, 9 Jan 2024 00:52:18 +0900</pubDate>
    </item>
    <item>
      <title>Singleton Container</title>
      <link>https://hj39-develop.tistory.com/202</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;□ 스프링 없는 DI 컨테이너로 구성된 경우&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-08 23.45.41.png&quot; data-origin-width=&quot;1646&quot; data-origin-height=&quot;822&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bm2jJy/btsDfOUvNIU/Pjm9sXIBz2LuCTY7g2pzMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bm2jJy/btsDfOUvNIU/Pjm9sXIBz2LuCTY7g2pzMk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bm2jJy/btsDfOUvNIU/Pjm9sXIBz2LuCTY7g2pzMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbm2jJy%2FbtsDfOUvNIU%2FPjm9sXIBz2LuCTY7g2pzMk%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;600&quot; height=&quot;822&quot; data-filename=&quot;스크린샷 2024-01-08 23.45.41.png&quot; data-origin-width=&quot;1646&quot; data-origin-height=&quot;822&quot;/&gt;&lt;/span&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;스프링 없는 순수한 DI 컨테이너인 AppConfig를 요청할 때마다 새로 생성한다.
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;ex) 트래픽이 초당 100인 경우 초당 100개 객체가 생성되고 소멸된다.&amp;nbsp;&amp;rarr; 메모리 낭비가 심하다.&lt;/li&gt;
&lt;li&gt;싱글톤 패턴으로 해결 가능&lt;/li&gt;
&lt;/ul&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;&lt;b&gt;□ 싱글톤 컨테이너를 적용 후&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-09 00.03.52.png&quot; data-origin-width=&quot;1646&quot; data-origin-height=&quot;822&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HVVgB/btsDdHO20SR/PhsmzIWNRwK6qfKW2YE4Z0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HVVgB/btsDdHO20SR/PhsmzIWNRwK6qfKW2YE4Z0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HVVgB/btsDdHO20SR/PhsmzIWNRwK6qfKW2YE4Z0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHVVgB%2FbtsDdHO20SR%2FPhsmzIWNRwK6qfKW2YE4Z0%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;600&quot; height=&quot;300&quot; data-filename=&quot;스크린샷 2024-01-09 00.03.52.png&quot; data-origin-width=&quot;1646&quot; data-origin-height=&quot;822&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;싱글톤 패턴&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;private&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;생성자를 사용해서 외부에서 임의로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;new&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;키워드를 사용하지 못하도록 막아야 한다&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;객체 인스턴스를 2개 이상 생성하지 못하게 막아야 한다.&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;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;□ 싱글톤 예제 코드&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1704725656754&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; public class SingletonService {
    //1. static 영역에 객체를 딱 1개만 생성해둔다.
    private static final SingletonService instance = new SingletonService();
    
    //2. public으로 열어서 객체 인스턴스가 필요하면 이 static 메서드를 통해서만 조회하도록 허용한다.
    public static SingletonService getInstance() {
         return instance;
    }
    
    //3. 생성자를 private으로 선언해서 외부에서 new 키워드를 사용한 객체 생성을 못하게 막는다. 
    private SingletonService() { }
    
    public void logic() { 
    	System.out.println(&quot;싱글톤 객체 로직 호출&quot;);
    } 
}&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #ffffff;&quot;&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_1704726034212&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Test
@DisplayName(&quot;싱글톤 패턴을 적용한 객체 사용&quot;) 
public void singletonServiceTest() {
    //private으로 생성자를 막아두었다. 컴파일 오류가 발생한다.
    //new SingletonService();
    
    //1. 조회: 호출할 때 마다 같은 객체를 반환
    SingletonService singletonService1 = SingletonService.getInstance(); 
    
    //2. 조회: 호출할 때 마다 같은 객체를 반환
    SingletonService singletonService2 = SingletonService.getInstance();
    
    //참조값이 같은 것을 확인
    System.out.println(&quot;singletonService1 = &quot; + singletonService1); 
    System.out.println(&quot;singletonService2 = &quot; + singletonService2);
    
    // singletonService1 == singletonService2
    assertThat(singletonService1).isSameAs(singletonService2);
    singletonService1.logic();
}&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;/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;b&gt;□ 문제점&lt;/b&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&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;의존관계상 클라이언트 객체가 구체 클래스에 의존한다.&amp;nbsp;&amp;rarr; DIP를 위반한다.&lt;/li&gt;
&lt;li&gt;클라이언트가 구체 클래스에 의존해서 OCP 원칙을 위반할 가능성이 높다.&lt;/li&gt;
&lt;li&gt;테스트하기 어렵다.&lt;/li&gt;
&lt;li&gt;내부 속성을 변경하거나 초기화하기 어렵다.&lt;/li&gt;
&lt;li&gt;private 생성자로 자식 클래스를 만들기 어렵다.&lt;/li&gt;
&lt;li&gt;유연성이 떨어진다.&lt;/li&gt;
&lt;li&gt;안티패턴으로 불린다.&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;&lt;b&gt;싱글톤 컨테이너&lt;/b&gt;&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;스프링 컨테이너는 싱글톤 컨테이너 역할을 한다.
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;싱글톤 객체를 생성하고 관리하는 기능을 싱글톤 레지스트리라고 한다.&lt;/li&gt;
&lt;/ul&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;□ 스프링 컨테이너를 사용한 테스트 코드&lt;/p&gt;
&lt;pre id=&quot;code_1704726180292&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Test
@DisplayName(&quot;스프링 컨테이너와 싱글톤&quot;) 
void springContainer() {
    ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

    //1. 조회: 호출할 때 마다 같은 객체를 반환
    MemberService memberService1 = ac.getBean(&quot;memberService&quot;, MemberService.class);

    //2. 조회: 호출할 때 마다 같은 객체를 반환
    MemberService memberService2 = ac.getBean(&quot;memberService&quot;, MemberService.class);

    //참조값이 같은 것을 확인
    System.out.println(&quot;memberService1 = &quot; + memberService1); 
    System.out.println(&quot;memberService2 = &quot; + memberService2);
    
    //memberService1 == memberService2
    assertThat(memberService1).isSameAs(memberService2);
}&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;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;DIP, OCP, 테스트, private 생성자로부터 자유롭게 싱글톤을 사용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&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;&lt;b&gt;주의점&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;stateless(무상태)로 설계해야 한다.
&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;li&gt;가급적 읽기만 가능해야 한다.&lt;/li&gt;
&lt;li&gt;필드 대신 자바에서 공유되지 않는 &lt;span style=&quot;background-color: #f3c000;&quot;&gt;지역변수&lt;/span&gt;, &lt;span style=&quot;background-color: #f3c000;&quot;&gt;파라미터&lt;/span&gt;, &lt;span style=&quot;background-color: #f3c000;&quot;&gt;ThreadLocal&lt;/span&gt; 등을 사용해야 한다.&lt;/li&gt;
&lt;/ul&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;□ 자바 코드 설정 파일&lt;/p&gt;
&lt;pre id=&quot;code_1704726460271&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Configuration
public class AppConfig {
    @Bean
    public MemberService memberService() {
         return new MemberServiceImpl(memberRepository());
    }
    
    @Bean
    public OrderService orderService() {
         return new OrderServiceImpl(
                 memberRepository(),
                 discountPolicy());
    }
    
    @Bean
    public MemberRepository memberRepository() {
         return new MemoryMemberRepository();
    }
	... 
}&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;memberService()&lt;/span&gt;를 호출하는 경우 &lt;span style=&quot;color: #ee2323;&quot;&gt;memberRepository()&lt;/span&gt;를 호출하여 &lt;span style=&quot;color: #ee2323;&quot;&gt;MemoryMemberRepository&lt;/span&gt;객체가 생성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;orderService()&lt;/span&gt;를 호출하는 경우 &lt;span style=&quot;color: #ee2323;&quot;&gt;memberRepository()&lt;/span&gt;를 호출하여 &lt;span style=&quot;color: #ee2323;&quot;&gt;MemoryMemberRepository&lt;/span&gt;객체가 생성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 경우 각각 2개의 &lt;span style=&quot;color: #ee2323;&quot;&gt;MemoryMemberRepository&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;/p&gt;
&lt;pre id=&quot;code_1704726865141&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class ConfigurationSingletonTest {
    @Test
    void configurationTest() {
        ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
        MemberServiceImpl memberService = ac.getBean(&quot;memberService&quot;, MemberServiceImpl.class);
        OrderServiceImpl orderService = ac.getBean(&quot;orderService&quot;, OrderServiceImpl.class);
        MemberRepository memberRepository = ac.getBean(&quot;memberRepository&quot;, MemberRepository.class);

        //모두 같은 인스턴스를 참고하고 있다.
        System.out.println(&quot;memberService -&amp;gt; memberRepository = &quot; + memberService.getMemberRepository());
        System.out.println(&quot;orderService -&amp;gt; memberRepository  = &quot; + orderService.getMemberRepository());
        System.out.println(&quot;memberRepository = &quot; + memberRepository);
        
        //모두 같은 인스턴스를 참고하고 있다.
        assertThat(memberService.getMemberRepository()).isSameAs(memberRepository);
        assertThat(orderService.getMemberRepository()).isSameAs(memberRepository);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 결과를 보면 &lt;span style=&quot;color: #ee2323; text-align: start;&quot;&gt;MemoryMemberRepository &lt;/span&gt;객체가 2번 생성되는 것이 아닌 1개의 객체를 생성하는 것을 알 수 있다.&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;p data-ke-size=&quot;size16&quot;&gt;Configuration 살펴보면 알 수 있다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;@Configuration&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;□ 스프링 빈에 등록된 클래스 정보를 알아보는 코드&lt;/p&gt;
&lt;pre id=&quot;code_1704727071505&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Test
void configurationDeep() {
    ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
    
    //AppConfig도 스프링 빈으로 등록된다.
    AppConfig bean = ac.getBean(AppConfig.class);
    System.out.println(&quot;bean = &quot; + bean.getClass());
	//출력: bean = class hello.core.AppConfig$$EnhancerBySpringCGLIB$$bd479d70 
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력 결과를 보면 AppConfig$$xxxxxxxCGLIBxxxxx 이러한 형태로 출력되어 있다.&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-filename=&quot;스크린샷 2024-01-09 00.20.20.png&quot; data-origin-width=&quot;1646&quot; data-origin-height=&quot;844&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mUXnM/btsDdHIhQ2K/wmWDj25b5khZAN3d9hKzn0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mUXnM/btsDdHIhQ2K/wmWDj25b5khZAN3d9hKzn0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mUXnM/btsDdHIhQ2K/wmWDj25b5khZAN3d9hKzn0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmUXnM%2FbtsDdHIhQ2K%2FwmWDj25b5khZAN3d9hKzn0%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;844&quot; data-filename=&quot;스크린샷 2024-01-09 00.20.20.png&quot; data-origin-width=&quot;1646&quot; data-origin-height=&quot;844&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스프링 빈에 등록할 때 CGLIB라는 바이트 코드 조작 라이브러리를 사용해서 AppConfig 클래스를 상속받은 임의의 다른 클래스를 만들어 스프링 빈에 등록한 것이다! (@Configuration 내부에 CGLIB 라이브러리가 있다.)&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;
&lt;p data-ke-size=&quot;size16&quot;&gt;CGLIB 내부 코드에서 &lt;span style=&quot;color: #ee2323; text-align: start;&quot;&gt;MemoryMemberRepository &lt;/span&gt;객체가 스프링 컨테이너에 생성되어 있다면 찾아서 return 하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;없다면 &lt;span style=&quot;color: #ee2323; text-align: start;&quot;&gt;MemoryMemberRepository &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;/p&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;</description>
      <category>Backend/Spring</category>
      <category>spring</category>
      <author>HJ39</author>
      <guid isPermaLink="true">https://hj39-develop.tistory.com/202</guid>
      <comments>https://hj39-develop.tistory.com/202#entry202comment</comments>
      <pubDate>Tue, 9 Jan 2024 00:24:52 +0900</pubDate>
    </item>
    <item>
      <title>Container와 Bean</title>
      <link>https://hj39-develop.tistory.com/201</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;□ 스프링 컨테이너 생성&lt;/p&gt;
&lt;pre id=&quot;code_1704717829046&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #ffffff;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: left;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;ApplicationContext&lt;/span&gt;는 스프링 컨테이너이다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: left;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: left;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;ApplicationContext&lt;/span&gt;는 인터페이스이다.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: left;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: left;&quot;&gt;Annotation 기반의 자바 설정 클래스, 스프링 컨테이너는 XML을 기반으로 만들 수 있다.&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;스프링 컨테이너 생성 과정&lt;/b&gt;&lt;/h4&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff;&quot;&gt;&lt;b&gt;□ 스프링 컨테이너 생성&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff;&quot;&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-08 21.52.18.png&quot; data-origin-width=&quot;1466&quot; data-origin-height=&quot;702&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d3ImGM/btsDbe0JySq/kbsL0yOukMvTFkFakG4oh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d3ImGM/btsDbe0JySq/kbsL0yOukMvTFkFakG4oh0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d3ImGM/btsDbe0JySq/kbsL0yOukMvTFkFakG4oh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd3ImGM%2FbtsDbe0JySq%2FkbsL0yOukMvTFkFakG4oh0%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;600&quot; height=&quot;702&quot; data-filename=&quot;스크린샷 2024-01-08 21.52.18.png&quot; data-origin-width=&quot;1466&quot; data-origin-height=&quot;702&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff;&quot;&gt;
&lt;pre id=&quot;code_1704718371830&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;new AnnotationConfigApplicationContext(AppConfig.class);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&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;해당 사진에서는 &lt;span style=&quot;color: #ee2323;&quot;&gt;AppConfig.class&lt;/span&gt; 구성 정보로 지정했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff;&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;□ 스프링 빈 등록&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff;&quot;&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-08 21.54.45.png&quot; data-origin-width=&quot;1474&quot; data-origin-height=&quot;672&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bivWGA/btsC7srPyWQ/vV1b7gKFUANWaerN152ex1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bivWGA/btsC7srPyWQ/vV1b7gKFUANWaerN152ex1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bivWGA/btsC7srPyWQ/vV1b7gKFUANWaerN152ex1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbivWGA%2FbtsC7srPyWQ%2FvV1b7gKFUANWaerN152ex1%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;600&quot; height=&quot;672&quot; data-filename=&quot;스크린샷 2024-01-08 21.54.45.png&quot; data-origin-width=&quot;1474&quot; data-origin-height=&quot;672&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;▷ 빈 이름 특징&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;/li&gt;
&lt;li&gt;빈 이름을 직접 부여할 수 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #ffffff;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff;&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;□ 스프링 빈 의존 관계 설정 - 준비&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff;&quot;&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-08 21.58.08.png&quot; data-origin-width=&quot;1474&quot; data-origin-height=&quot;672&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b3VRo7/btsC9BWb8lR/dNXvzs2pENXub4ZeL9QJ61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b3VRo7/btsC9BWb8lR/dNXvzs2pENXub4ZeL9QJ61/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b3VRo7/btsC9BWb8lR/dNXvzs2pENXub4ZeL9QJ61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3VRo7%2FbtsC9BWb8lR%2FdNXvzs2pENXub4ZeL9QJ61%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;600&quot; height=&quot;672&quot; data-filename=&quot;스크린샷 2024-01-08 21.58.08.png&quot; data-origin-width=&quot;1474&quot; data-origin-height=&quot;672&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&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;div style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff;&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;□ 스프링 빈 &lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;의존 관계 설정 - 완료&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff;&quot;&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-08 21.58.26.png&quot; data-origin-width=&quot;1474&quot; data-origin-height=&quot;672&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DtcPq/btsC84K4xqT/QQc1TgV2r1NSG3Llq3l8eK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DtcPq/btsC84K4xqT/QQc1TgV2r1NSG3Llq3l8eK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DtcPq/btsC84K4xqT/QQc1TgV2r1NSG3Llq3l8eK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDtcPq%2FbtsC84K4xqT%2FQQc1TgV2r1NSG3Llq3l8eK%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;600&quot; height=&quot;672&quot; data-filename=&quot;스크린샷 2024-01-08 21.58.26.png&quot; data-origin-width=&quot;1474&quot; data-origin-height=&quot;672&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;스프링 컨테이너는 설정 정보를 참고해서 의존관계를 주입(DI)한다.&lt;span style=&quot;background-color: #ffffff;&quot;&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;&lt;b&gt;※ 스프링 빈을 조회할 때 조회 대상이 없는 경우&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1704719141171&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;NoSuchBeanDefinitionException: No bean named 'xxxxx' available&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;&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;스프링 빈 조회 - 상속 관계&amp;nbsp;&lt;/b&gt;&lt;/h4&gt;
&lt;div style=&quot;background-color: #ffffff;&quot;&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-08 22.06.49.png&quot; data-origin-width=&quot;1474&quot; data-origin-height=&quot;672&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/boLdug/btsC9nDwsjm/5gsPO9Oa4DIHEg1X0gIFFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/boLdug/btsC9nDwsjm/5gsPO9Oa4DIHEg1X0gIFFK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/boLdug/btsC9nDwsjm/5gsPO9Oa4DIHEg1X0gIFFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FboLdug%2FbtsC9nDwsjm%2F5gsPO9Oa4DIHEg1X0gIFFK%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;600&quot; height=&quot;672&quot; data-filename=&quot;스크린샷 2024-01-08 22.06.49.png&quot; data-origin-width=&quot;1474&quot; data-origin-height=&quot;672&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&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;Object타입으로 조회하면, 모든 스프링 빈을 조회한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;BeanFactory와 ApplicationContext&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-08 22.14.22.png&quot; data-origin-width=&quot;592&quot; data-origin-height=&quot;896&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvtWCB/btsC9yd4D21/KB5SEKx6uCA0rrW8Ur8lz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvtWCB/btsC9yd4D21/KB5SEKx6uCA0rrW8Ur8lz1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvtWCB/btsC9yd4D21/KB5SEKx6uCA0rrW8Ur8lz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcvtWCB%2FbtsC9yd4D21%2FKB5SEKx6uCA0rrW8Ur8lz1%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;300&quot; height=&quot;454&quot; data-filename=&quot;스크린샷 2024-01-08 22.14.22.png&quot; data-origin-width=&quot;592&quot; data-origin-height=&quot;896&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;BeanFactory&lt;/b&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;div&gt;
&lt;div style=&quot;background-color: #ffffff;&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;스프링 컨테이너의 최상위 인터페이스&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;스프링 빈을 관리하고 조회하는 역할을 담당&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #ee2323; text-align: start;&quot;&gt;getBean()&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;&amp;nbsp;제공&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ApplicationContext&lt;/b&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;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;BeanFactory&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;기능을 모두 상속받아서 제공&lt;/span&gt;&lt;/li&gt;
&lt;li&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;ApplicationContext 제공하는 부가기능&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-08 22.19.28.png&quot; data-origin-width=&quot;1466&quot; data-origin-height=&quot;524&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/D08X2/btsC8S4XwtU/ExrGKM1hxyZHHKFTaeiJx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/D08X2/btsC8S4XwtU/ExrGKM1hxyZHHKFTaeiJx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/D08X2/btsC8S4XwtU/ExrGKM1hxyZHHKFTaeiJx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FD08X2%2FbtsC8S4XwtU%2FExrGKM1hxyZHHKFTaeiJx1%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;179&quot; data-filename=&quot;스크린샷 2024-01-08 22.19.28.png&quot; data-origin-width=&quot;1466&quot; data-origin-height=&quot;524&quot;/&gt;&lt;/span&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;메시지소스를 활용한 국제화 기능&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&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&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;로컬, 개발, 운영 등을 구분해서 처리&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: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&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;/li&gt;
&lt;/ul&gt;
&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;&lt;b&gt;다양한 설정 형식 지원 - 자바코드, XML&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-08 22.26.50.png&quot; data-origin-width=&quot;1466&quot; data-origin-height=&quot;874&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dNXfsy/btsC836vh2B/nkG2LISCuTpa2mZcRUJ5sK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dNXfsy/btsC836vh2B/nkG2LISCuTpa2mZcRUJ5sK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dNXfsy/btsC836vh2B/nkG2LISCuTpa2mZcRUJ5sK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdNXfsy%2FbtsC836vh2B%2FnkG2LISCuTpa2mZcRUJ5sK%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;874&quot; data-filename=&quot;스크린샷 2024-01-08 22.26.50.png&quot; data-origin-width=&quot;1466&quot; data-origin-height=&quot;874&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&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-08 23.24.17.png&quot; data-origin-width=&quot;1466&quot; data-origin-height=&quot;874&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKOdw3/btsC6wVwMMh/wCYJV4Wy8aG40DrZRkRrsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKOdw3/btsC6wVwMMh/wCYJV4Wy8aG40DrZRkRrsK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKOdw3/btsC6wVwMMh/wCYJV4Wy8aG40DrZRkRrsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKOdw3%2FbtsC6wVwMMh%2FwCYJV4Wy8aG40DrZRkRrsK%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;874&quot; data-filename=&quot;스크린샷 2024-01-08 23.24.17.png&quot; data-origin-width=&quot;1466&quot; data-origin-height=&quot;874&quot;/&gt;&lt;/span&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;/li&gt;
&lt;li&gt;역할과 구현을 개념적으로 나누어서 설계되어 있다.
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;XML 파일인지 자바 코드인지 상관없이 BeanDefinition만 알면 잘 작동한다.&lt;/li&gt;
&lt;/ul&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;# 참고한 자료&lt;/p&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;</description>
      <category>Backend/Spring</category>
      <category>spring</category>
      <author>HJ39</author>
      <guid isPermaLink="true">https://hj39-develop.tistory.com/201</guid>
      <comments>https://hj39-develop.tistory.com/201#entry201comment</comments>
      <pubDate>Mon, 8 Jan 2024 23:43:51 +0900</pubDate>
    </item>
    <item>
      <title>객체지향원칙 5가지</title>
      <link>https://hj39-develop.tistory.com/200</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;SRP (Single Responsibility Principle) 단일 책임의 원칙&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;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&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;/ul&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;ORP (Open-Closed Principle) 개방&amp;nbsp;폐쇄&amp;nbsp;원칙&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;확장에&amp;nbsp;대해&amp;nbsp;열려있고&amp;nbsp;수정에&amp;nbsp;대해서는&amp;nbsp;닫혀있어야&amp;nbsp;한다는&amp;nbsp;원칙&lt;/li&gt;
&lt;/ul&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;&amp;rarr; 추상화에 의존하면 문제 해결 가능&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;ISP (Interface Segregation Principle) 인터페이스 분리 원칙&lt;/b&gt;&lt;/b&gt;&lt;/h3&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;모든 클라이언트가 자신의 관심에 맞는 public interface만 접근하여 불필요한 간섭을 최소화할 수 있다.&lt;/li&gt;
&lt;li&gt;클라이언트에 따라 인터페이스를 분리하면 변경에 대한 영향을 더욱 세밀하게 제어할 수 있다.&lt;/li&gt;
&lt;/ul&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;LSP (Liskov Substitution Principle) 리스코프 치환 원칙&lt;/b&gt;&lt;/h3&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;자식 클래스가 부모 클래스를 대체하기 위해 부모 클래스에 대한 클라이언트의 가정을 준수해야 한다.&lt;/li&gt;
&lt;li&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;□ LSP를 위반할 수 있는 상황&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-04 10.58.03.png&quot; data-origin-width=&quot;919&quot; data-origin-height=&quot;425&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dZWMYh/btsC00aQoLs/Vl86FC9bhacmoLJWyFG71k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dZWMYh/btsC00aQoLs/Vl86FC9bhacmoLJWyFG71k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dZWMYh/btsC00aQoLs/Vl86FC9bhacmoLJWyFG71k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdZWMYh%2FbtsC00aQoLs%2FVl86FC9bhacmoLJWyFG71k%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;700&quot; height=&quot;425&quot; data-filename=&quot;스크린샷 2024-01-04 10.58.03.png&quot; data-origin-width=&quot;919&quot; data-origin-height=&quot;425&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;DIP (Dependency Inversion Principle) 의존 역전 원칙&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;고수준 모듈은 저수준 모듈의 구현에 의존해서는 안되며, 저수준 모듈이 고수준 모듈이 의존해야 한다
&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;저수준 모듈: 입력과 출력으로부터 가까운(HTTP, DB, 캐시등) 구현 모듈&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&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;의존 역전 원칙이 위배되는 경우 개방 폐쇄 원칙 역시 위배될 가능성이 높다.&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;p data-ke-size=&quot;size16&quot;&gt;# 참고한 사이트&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1704333812078&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[OOP] 객체지향 프로그래밍의 5가지 설계 원칙, 실무 코드로 살펴보는 SOLID&quot; data-og-description=&quot;이번에는 객체 지향 프로그래밍의 5가지 핵심 원칙인 SOLID에 대해 알아보고자 합니다. 실제로 애플리케이션을 개발할 때 어떻게 적용할 수 있을지 구체적인 예시를 들어 살펴보고자 합니다. 아&quot; data-og-host=&quot;mangkyu.tistory.com&quot; data-og-source-url=&quot;https://mangkyu.tistory.com/194&quot; data-og-url=&quot;https://mangkyu.tistory.com/194&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/mN0l8/hyUXRUA3ou/sHC9vbxJmwEmdTx2eTKHZ0/img.png?width=800&amp;amp;height=270&amp;amp;face=0_0_800_270,https://scrap.kakaocdn.net/dn/cacSr0/hyUXTSoZWM/7krJftMHgbHpbmIk62WPfK/img.png?width=800&amp;amp;height=270&amp;amp;face=0_0_800_270,https://scrap.kakaocdn.net/dn/Zq6rk/hyUXLfNwFG/dlfKYkkbWrWmZKYI1jjr70/img.png?width=1258&amp;amp;height=426&amp;amp;face=0_0_1258_426&quot;&gt;&lt;a href=&quot;https://mangkyu.tistory.com/194&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://mangkyu.tistory.com/194&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/mN0l8/hyUXRUA3ou/sHC9vbxJmwEmdTx2eTKHZ0/img.png?width=800&amp;amp;height=270&amp;amp;face=0_0_800_270,https://scrap.kakaocdn.net/dn/cacSr0/hyUXTSoZWM/7krJftMHgbHpbmIk62WPfK/img.png?width=800&amp;amp;height=270&amp;amp;face=0_0_800_270,https://scrap.kakaocdn.net/dn/Zq6rk/hyUXLfNwFG/dlfKYkkbWrWmZKYI1jjr70/img.png?width=1258&amp;amp;height=426&amp;amp;face=0_0_1258_426');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[OOP] 객체지향 프로그래밍의 5가지 설계 원칙, 실무 코드로 살펴보는 SOLID&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이번에는 객체 지향 프로그래밍의 5가지 핵심 원칙인 SOLID에 대해 알아보고자 합니다. 실제로 애플리케이션을 개발할 때 어떻게 적용할 수 있을지 구체적인 예시를 들어 살펴보고자 합니다. 아&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;mangkyu.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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>Backend/Spring</category>
      <category>solid</category>
      <author>HJ39</author>
      <guid isPermaLink="true">https://hj39-develop.tistory.com/200</guid>
      <comments>https://hj39-develop.tistory.com/200#entry200comment</comments>
      <pubDate>Thu, 4 Jan 2024 00:50:30 +0900</pubDate>
    </item>
    <item>
      <title>스프링 핵심 원리 이해 1, 2</title>
      <link>https://hj39-develop.tistory.com/199</link>
      <description>&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_1704292759665&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class OrderServiceImpl implements OrderService {
 //    private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
     private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 코드의 경우 &lt;span style=&quot;color: #ee2323;&quot;&gt;OrderServiceImpl&lt;/span&gt; 는 Interface인 &lt;span style=&quot;color: #ee2323;&quot;&gt;OrderService&lt;/span&gt; 에 의존하고 있다. (설계된 의도)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;FixDiscountPolicy()&lt;/span&gt;, &lt;span style=&quot;color: #ee2323;&quot;&gt;RateDiscountPolicy()&lt;/span&gt;를 직접적으로 객체를 생성하므로 두 클래스에도 의존을 하게된다. &amp;rarr; DIP를 지키지 못했다.&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 alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-03 23.41.57.png&quot; data-origin-width=&quot;489&quot; data-origin-height=&quot;217&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRhPEf/btsCTX0vjzt/xPKpn8WOQe6GLhXQaYTFv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRhPEf/btsCTX0vjzt/xPKpn8WOQe6GLhXQaYTFv1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRhPEf/btsCTX0vjzt/xPKpn8WOQe6GLhXQaYTFv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRhPEf%2FbtsCTX0vjzt%2FxPKpn8WOQe6GLhXQaYTFv1%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;489&quot; height=&quot;217&quot; data-filename=&quot;스크린샷 2024-01-03 23.41.57.png&quot; data-origin-width=&quot;489&quot; data-origin-height=&quot;217&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;□ 잘못된 의도&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-03 23.43.00.png&quot; data-origin-width=&quot;489&quot; data-origin-height=&quot;217&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvy2hX/btsC33LlHT7/wxXzWwfMrUXs6y6wkMWBv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvy2hX/btsC33LlHT7/wxXzWwfMrUXs6y6wkMWBv0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvy2hX/btsC33LlHT7/wxXzWwfMrUXs6y6wkMWBv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcvy2hX%2FbtsC33LlHT7%2FwxXzWwfMrUXs6y6wkMWBv0%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;489&quot; height=&quot;217&quot; data-filename=&quot;스크린샷 2024-01-03 23.43.00.png&quot; data-origin-width=&quot;489&quot; data-origin-height=&quot;217&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;□ 요구사항이 변경된 경우 클라이언트 코드를 직접 수정해야함&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-04 00.14.22.png&quot; data-origin-width=&quot;489&quot; data-origin-height=&quot;268&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/v3GhA/btsC2Bhglhu/hUcatPKva5vMo3TuRkn7bK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/v3GhA/btsC2Bhglhu/hUcatPKva5vMo3TuRkn7bK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/v3GhA/btsC2Bhglhu/hUcatPKva5vMo3TuRkn7bK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fv3GhA%2FbtsC2Bhglhu%2FhUcatPKva5vMo3TuRkn7bK%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;489&quot; height=&quot;268&quot; data-filename=&quot;스크린샷 2024-01-04 00.14.22.png&quot; data-origin-width=&quot;489&quot; data-origin-height=&quot;268&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라이언트 코드를 수정하여 OCP를 위반한다.&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;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Interface에 의존하게끔 변경한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1704295000549&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class OrderServiceImpl implements OrderService {
     //private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
     private DiscountPolicy discountPolicy;
}&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;&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;외부 클래스를(AppConfig) 생성하여 객체를 주입시켜 준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1704295066427&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class AppConfig {
     public MemberService memberService() {
         return new MemberServiceImpl(new MemoryMemberRepository());
     }

     public OrderService orderService() {
         return new OrderServiceImpl(
                        new MemoryMemberRepository(),
                        new FixDiscountPolicy());
     }
}&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;&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;OrderServiceImpl에 생성자 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1704295098734&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class OrderServiceImpl implements OrderService {
     private final MemberRepository memberRepository;
     private final DiscountPolicy discountPolicy;
     public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
         this.memberRepository = memberRepository;
         this.discountPolicy = discountPolicy;
     }
}&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;/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;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-04 00.19.20.png&quot; data-origin-width=&quot;496&quot; data-origin-height=&quot;308&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Fiolt/btsCZiip0Ag/XL30KaLlg6z8QAK2VVl4AK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Fiolt/btsCZiip0Ag/XL30KaLlg6z8QAK2VVl4AK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Fiolt/btsCZiip0Ag/XL30KaLlg6z8QAK2VVl4AK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFiolt%2FbtsCZiip0Ag%2FXL30KaLlg6z8QAK2VVl4AK%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;496&quot; height=&quot;308&quot; data-filename=&quot;스크린샷 2024-01-04 00.19.20.png&quot; data-origin-width=&quot;496&quot; data-origin-height=&quot;308&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;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;□ 리팩토링한 AppConfig&lt;/p&gt;
&lt;pre id=&quot;code_1704295247959&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class AppConfig {

     public MemberService memberService() {
         return new MemberServiceImpl(memberRepository());
	 }
        
     public OrderService orderService() {
         return new OrderServiceImpl(memberRepository(), discountPolicy());
	 }
        
     public MemberRepository memberRepository() {
         return new MemoryMemberRepository();
	 }
     
     public DiscountPolicy discountPolicy() {
         return new FixDiscountPolicy();
     }
}&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;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;결론&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-04 00.22.40.png&quot; data-origin-width=&quot;496&quot; data-origin-height=&quot;336&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CQA43/btsC4elJvH9/KeyEoiCQ6V3ljfilUtEOJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CQA43/btsC4elJvH9/KeyEoiCQ6V3ljfilUtEOJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CQA43/btsC4elJvH9/KeyEoiCQ6V3ljfilUtEOJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCQA43%2FbtsC4elJvH9%2FKeyEoiCQ6V3ljfilUtEOJ1%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;496&quot; height=&quot;336&quot; data-filename=&quot;스크린샷 2024-01-04 00.22.40.png&quot; data-origin-width=&quot;496&quot; data-origin-height=&quot;336&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇듯 interface로 역할을 나눈 뒤 class가 역할을 수행하도록만 구현하면 요구사항이 변해도 손쉽게 갈아끼울 수 있다.&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;rarr; 사용 영역 코드가 변한다면 잘못 설계한 것!  &lt;/p&gt;</description>
      <category>Backend/Spring</category>
      <category>spring</category>
      <author>HJ39</author>
      <guid isPermaLink="true">https://hj39-develop.tistory.com/199</guid>
      <comments>https://hj39-develop.tistory.com/199#entry199comment</comments>
      <pubDate>Thu, 4 Jan 2024 00:32:50 +0900</pubDate>
    </item>
    <item>
      <title>JOIN</title>
      <link>https://hj39-develop.tistory.com/198</link>
      <description>&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;□ JOIN 예시&lt;/p&gt;
&lt;pre id=&quot;code_1704186470243&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT ...
FROM R, S
WHERE R.A &amp;lt;비교연산자&amp;gt; S.B;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같은 SELECT문은 릴레이션 R의 Attribute A와 릴레이션 S의 Attribute B를 비교연산자를 통해 조건을 만족하는 튜플들의 집합을 구한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;R.A &amp;lt;비교연산자&amp;gt; S.B;&lt;/span&gt; &lt;/b&gt;인 경우 R.A와 S.B는 주로 기본 키와 외래 키의 관계를 갖는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 55.6977%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;- N개의 릴레이션을 연관시키기 위해서는 N-1개의 JOIN 조건이 필요하다.&lt;br /&gt;- JOIN 조건을 생략하거나 틀리게 표현한 경우 &lt;b&gt;카티션 곱&lt;/b&gt;이 생성된다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;사용할 예제&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1704187048927&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT * FROM Company.EMPLOYEE;&lt;/code&gt;&lt;/pre&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-02 18.15.06.png&quot; data-origin-width=&quot;450&quot; data-origin-height=&quot;133&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zz4tM/btsCQ1V9FTy/pBkxHndKVoUKOUseTvuMU1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zz4tM/btsCQ1V9FTy/pBkxHndKVoUKOUseTvuMU1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zz4tM/btsCQ1V9FTy/pBkxHndKVoUKOUseTvuMU1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fzz4tM%2FbtsCQ1V9FTy%2FpBkxHndKVoUKOUseTvuMU1%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;450&quot; height=&quot;133&quot; data-filename=&quot;스크린샷 2024-01-02 18.15.06.png&quot; data-origin-width=&quot;450&quot; data-origin-height=&quot;133&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;pre id=&quot;code_1704187066290&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT * FROM Company.DEPARTMENT;&lt;/code&gt;&lt;/pre&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-02 18.15.51.png&quot; data-origin-width=&quot;177&quot; data-origin-height=&quot;90&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mHGui/btsCUZXjWv3/VtpvNNsB7Kav4aevEABibk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mHGui/btsCUZXjWv3/VtpvNNsB7Kav4aevEABibk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mHGui/btsCUZXjWv3/VtpvNNsB7Kav4aevEABibk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmHGui%2FbtsCUZXjWv3%2FVtpvNNsB7Kav4aevEABibk%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;177&quot; height=&quot;90&quot; data-filename=&quot;스크린샷 2024-01-02 18.15.51.png&quot; data-origin-width=&quot;177&quot; data-origin-height=&quot;90&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&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;셀프 조인&lt;/b&gt;&lt;/li&gt;
&lt;/ul&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_1704187340888&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT E.EMPNAME as MENTEE, E.SALARY, M.EMPNAME as MENTO
from Company.EMPLOYEE E, Company.EMPLOYEE M
where E.MANAGER = M.EMPNO
order by E.SALARY DESC;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-02 18.23.32.png&quot; data-origin-width=&quot;301&quot; data-origin-height=&quot;120&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7dJCt/btsCSaeef3t/yiao5Jlu8ovG9N8b5eVYX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7dJCt/btsCSaeef3t/yiao5Jlu8ovG9N8b5eVYX1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7dJCt/btsCSaeef3t/yiao5Jlu8ovG9N8b5eVYX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7dJCt%2FbtsCSaeef3t%2Fyiao5Jlu8ovG9N8b5eVYX1%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;301&quot; height=&quot;120&quot; data-filename=&quot;스크린샷 2024-01-02 18.23.32.png&quot; data-origin-width=&quot;301&quot; data-origin-height=&quot;120&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;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;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;390&quot; data-origin-height=&quot;129&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WU8Kt/btsCRglfaFA/JK49XQ8zDco1RyJKARbohk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WU8Kt/btsCRglfaFA/JK49XQ8zDco1RyJKARbohk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WU8Kt/btsCRglfaFA/JK49XQ8zDco1RyJKARbohk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWU8Kt%2FbtsCRglfaFA%2FJK49XQ8zDco1RyJKARbohk%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;390&quot; height=&quot;129&quot; data-origin-width=&quot;390&quot; data-origin-height=&quot;129&quot;/&gt;&lt;/span&gt;&lt;/figure&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;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;한 개의 스칼라 값이 반환되는 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1704187938579&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select EMPNAME, TITLE
from Company.EMPLOYEE
where TITLE = (select TITLE from Company.EMPLOYEE where EMPNAME = &quot;박영권&quot;);
-- EMPLOYEE 릴레이션에서 EMPNAME이 &quot;박영권&quot;인 사람의 직급과 같은 사람들을 EMPLOYEE 릴레이션에서 조회한다.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-02 18.32.28.png&quot; data-origin-width=&quot;170&quot; data-origin-height=&quot;62&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mS7oW/btsC1ImLg04/9QtEqx1QUClknEDp1mpxWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mS7oW/btsC1ImLg04/9QtEqx1QUClknEDp1mpxWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mS7oW/btsC1ImLg04/9QtEqx1QUClknEDp1mpxWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmS7oW%2FbtsC1ImLg04%2F9QtEqx1QUClknEDp1mpxWk%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;170&quot; height=&quot;62&quot; data-filename=&quot;스크린샷 2024-01-02 18.32.28.png&quot; data-origin-width=&quot;170&quot; data-origin-height=&quot;62&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;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;한 개의 Attribute로 이루어진 릴레이션이 반환된 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외부 질의의 WHERE절에서 IN, ANY(SOME), ALL, EXISTS 같은 연산자를 사용한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 74.0747%; height: 99px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style14&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 11.8005%; text-align: center;&quot;&gt;&lt;b&gt;연산자&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 253.922%; text-align: center;&quot;&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 11.8005%; text-align: center;&quot;&gt;&lt;b&gt;IN&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 253.922%;&quot;&gt;한 Attribute가 값들의 집합에 속하는지 테스트할 때 사용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 11.8005%; text-align: center;&quot;&gt;&lt;b&gt;ANY&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 253.922%;&quot;&gt;하나 이상의 값들과 어떤 관계를 갖는지 테스트할 때 사용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 11.8005%; text-align: center;&quot;&gt;&lt;b&gt;EXISTS&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 253.922%;&quot;&gt;여러 Attribute로 이루어진 릴레이션이 반환되는 경우에 사용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 11.8005%; text-align: center;&quot;&gt;&lt;b&gt;ALL&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 253.922%;&quot;&gt;한 Attribute가 값들의 집합에 속하는 모든 값들과 어떤 관계를 갖는지 테스트할 때 사용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 265.723%; text-align: left;&quot; colspan=&quot;2&quot;&gt;&lt;b&gt;=, &amp;lt;&amp;gt;, &amp;lt;=, &amp;lt;&amp;gt;, &amp;gt;=, &amp;gt;의 비교연산자도 같이 사용&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1704188095809&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select EMPNAME, TITLE, DNO
from Company.EMPLOYEE
where DNO in (select DEPTNO from Company.DEPARTMENT where DEPTNAME = &quot;영업&quot; OR DEPTNAME = &quot;개발&quot;);
-- 영업부나 개발부에 근무하는 사람들의 이름과 직급을 조회한다.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-02 18.35.07.png&quot; data-origin-width=&quot;240&quot; data-origin-height=&quot;89&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n8Tcl/btsCX6IpAoh/EKLFu7IkbiB9MeTlhCIsU1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n8Tcl/btsCX6IpAoh/EKLFu7IkbiB9MeTlhCIsU1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n8Tcl/btsCX6IpAoh/EKLFu7IkbiB9MeTlhCIsU1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn8Tcl%2FbtsCX6IpAoh%2FEKLFu7IkbiB9MeTlhCIsU1%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;240&quot; height=&quot;89&quot; data-filename=&quot;스크린샷 2024-01-02 18.35.07.png&quot; data-origin-width=&quot;240&quot; data-origin-height=&quot;89&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;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;여러 Attribute들로 이루어진 릴레이션이 반환되는 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1704189042786&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select EMPNAME
from Company.EMPLOYEE E
where EXISTS
        (select * 
         from Company.DEPARTMENT D 
         where E.DNO = D.DEPTNO 
         	AND (DEPTNAME = &quot;영업&quot; OR DEPTNAME = &quot;개발&quot;));
-- 영업부나 개발부에서 근무하는 사원들의 이름을 조회&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-02 18.52.16.png&quot; data-origin-width=&quot;85&quot; data-origin-height=&quot;89&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ebOh3G/btsCZiIRoSS/Dy4ea2HiBFfnDkG1C7ykP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ebOh3G/btsCZiIRoSS/Dy4ea2HiBFfnDkG1C7ykP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ebOh3G/btsCZiIRoSS/Dy4ea2HiBFfnDkG1C7ykP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FebOh3G%2FbtsCZiIRoSS%2FDy4ea2HiBFfnDkG1C7ykP1%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;85&quot; height=&quot;89&quot; data-filename=&quot;스크린샷 2024-01-02 18.52.16.png&quot; data-origin-width=&quot;85&quot; data-origin-height=&quot;89&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;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;상관 중첩 질의&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 EXISTS를 사용한 예시에서 외부 질의 from에서 명시된 EMPLOYEE릴레이션을 중첩 질의 WHERE에서 사용되므로 상관 중첩 질의가 적용된다.&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;내부 조인(INNER JOIN)&lt;/b&gt;&lt;/li&gt;
&lt;/ul&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&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-02 19.54.11.png&quot; data-origin-width=&quot;397&quot; data-origin-height=&quot;408&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c6H7cA/btsCTwVEtmV/Sj1MdMMNs9BHTWOgHPImI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c6H7cA/btsCTwVEtmV/Sj1MdMMNs9BHTWOgHPImI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c6H7cA/btsCTwVEtmV/Sj1MdMMNs9BHTWOgHPImI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc6H7cA%2FbtsCTwVEtmV%2FSj1MdMMNs9BHTWOgHPImI0%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;397&quot; height=&quot;408&quot; data-filename=&quot;스크린샷 2024-01-02 19.54.11.png&quot; data-origin-width=&quot;397&quot; data-origin-height=&quot;408&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1704192785455&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 중첩 질의
select EMPNAME, TITLE, DNO
from Company.EMPLOYEE
where DNO in (select DEPTNO from Company.DEPARTMENT where DEPTNAME = &quot;영업&quot; OR DEPTNAME = &quot;개발&quot;);

-- INNER JOIN
select EMPNAME, TITLE, DNO
from Company.EMPLOYEE as E
inner join Company.DEPARTMENT as D
	on (E.DNO = D.DEPTNO) AND (D.DEPTNAME = &quot;영업&quot; OR D.DEPTNAME = &quot;개발&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 쿼리문의 결과 값은 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-02 19.56.29.png&quot; data-origin-width=&quot;256&quot; data-origin-height=&quot;89&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dLXlE8/btsCQrHlFnH/TWn5KdmRUA5nvWsYljSif0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dLXlE8/btsCQrHlFnH/TWn5KdmRUA5nvWsYljSif0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dLXlE8/btsCQrHlFnH/TWn5KdmRUA5nvWsYljSif0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdLXlE8%2FbtsCQrHlFnH%2FTWn5KdmRUA5nvWsYljSif0%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;256&quot; height=&quot;89&quot; data-filename=&quot;스크린샷 2024-01-02 19.56.29.png&quot; data-origin-width=&quot;256&quot; data-origin-height=&quot;89&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;외부 조인(OUTER JOIN)&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내부 조인은 두 테이블에 모두 데이터가 있어야만 결과가 나오지만, 외부 조인은 한쪽에만 데이터가 있어도 결과가 조회된다.&lt;/p&gt;
&lt;pre id=&quot;code_1704192945920&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT &amp;lt;열 목록&amp;gt;
FROM &amp;lt;첫 번째 테이블(LEFT 테이블)&amp;gt;
    &amp;lt;LEFT | RIGHT | FULL&amp;gt; OUTER JOIN &amp;lt;두 번째 테이블(RIGHT 테이블)&amp;gt;
     ON &amp;lt;조인 조건&amp;gt;
[WHERE 검색 조건]&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;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;LEFT OUTER JOIN&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;스크린샷 2024-01-02 20.00.27.png&quot; data-origin-width=&quot;198&quot; data-origin-height=&quot;422&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qVuAf/btsC2wzB6HH/RGM4zIF9KEZ6NVvfnpgqvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qVuAf/btsC2wzB6HH/RGM4zIF9KEZ6NVvfnpgqvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qVuAf/btsC2wzB6HH/RGM4zIF9KEZ6NVvfnpgqvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqVuAf%2FbtsC2wzB6HH%2FRGM4zIF9KEZ6NVvfnpgqvK%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;198&quot; height=&quot;422&quot; data-filename=&quot;스크린샷 2024-01-02 20.00.27.png&quot; data-origin-width=&quot;198&quot; data-origin-height=&quot;422&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;□ 교집합을 포함하는 경우&lt;/p&gt;
&lt;pre id=&quot;code_1704193371523&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select EMPNAME, TITLE, DNO, DEPTNAME
from Company.EMPLOYEE as E
	left outer join Company.DEPARTMENT as D
		on (E.DNO = D.DEPTNO) AND (D.DEPTNAME = &quot;영업&quot; OR D.DEPTNAME = &quot;개발&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-02 20.03.55.png&quot; data-origin-width=&quot;325&quot; data-origin-height=&quot;134&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XaDWM/btsCTvJeCz0/lpxbU5Ri934muT47W9Y5Ok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XaDWM/btsCTvJeCz0/lpxbU5Ri934muT47W9Y5Ok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XaDWM/btsCTvJeCz0/lpxbU5Ri934muT47W9Y5Ok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXaDWM%2FbtsCTvJeCz0%2FlpxbU5Ri934muT47W9Y5Ok%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;325&quot; height=&quot;134&quot; data-filename=&quot;스크린샷 2024-01-02 20.03.55.png&quot; data-origin-width=&quot;325&quot; data-origin-height=&quot;134&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;□ 교집합을 포함하지 않는 경우 (DEPTNAME이 NULL인 경우를 제외)&lt;/p&gt;
&lt;pre id=&quot;code_1704193480632&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select EMPNAME, TITLE, DNO, DEPTNAME
from Company.EMPLOYEE as E
	left outer join Company.DEPARTMENT as D
		on (E.DNO = D.DEPTNO) AND (D.DEPTNAME = &quot;영업&quot; OR D.DEPTNAME = &quot;개발&quot;)
where D.DEPTNAME is NOT NULL&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-02 20.10.09.png&quot; data-origin-width=&quot;325&quot; data-origin-height=&quot;71&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SZHer/btsCReAZbOL/kfp1KyGxmTWC4PgJkbXhJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SZHer/btsCReAZbOL/kfp1KyGxmTWC4PgJkbXhJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SZHer/btsCReAZbOL/kfp1KyGxmTWC4PgJkbXhJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSZHer%2FbtsCReAZbOL%2Fkfp1KyGxmTWC4PgJkbXhJk%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;325&quot; height=&quot;71&quot; data-filename=&quot;스크린샷 2024-01-02 20.10.09.png&quot; data-origin-width=&quot;325&quot; data-origin-height=&quot;71&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;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;RIGHT OUTER JOIN&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;스크린샷 2024-01-02 20.05.40.png&quot; data-origin-width=&quot;189&quot; data-origin-height=&quot;415&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/daPt3d/btsC00gSKmb/1oXYkYKnEhySb4dTrbbSqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/daPt3d/btsC00gSKmb/1oXYkYKnEhySb4dTrbbSqk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/daPt3d/btsC00gSKmb/1oXYkYKnEhySb4dTrbbSqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdaPt3d%2FbtsC00gSKmb%2F1oXYkYKnEhySb4dTrbbSqk%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;189&quot; height=&quot;415&quot; data-filename=&quot;스크린샷 2024-01-02 20.05.40.png&quot; data-origin-width=&quot;189&quot; data-origin-height=&quot;415&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1704193627521&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select EMPNAME, TITLE, DNO, DEPTNAME
from Company.EMPLOYEE as E
	right outer join Company.DEPARTMENT as D
		on (E.DNO = D.DEPTNO) AND (D.DEPTNAME = &quot;영업&quot; OR D.DEPTNAME = &quot;개발&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-02 20.07.21.png&quot; data-origin-width=&quot;325&quot; data-origin-height=&quot;118&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IgiZ7/btsC0X5xabZ/9w8XfNAKk6BoKhqvOAUkKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IgiZ7/btsC0X5xabZ/9w8XfNAKk6BoKhqvOAUkKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IgiZ7/btsC0X5xabZ/9w8XfNAKk6BoKhqvOAUkKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIgiZ7%2FbtsC0X5xabZ%2F9w8XfNAKk6BoKhqvOAUkKk%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;325&quot; height=&quot;118&quot; data-filename=&quot;스크린샷 2024-01-02 20.07.21.png&quot; data-origin-width=&quot;325&quot; data-origin-height=&quot;118&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;pre id=&quot;code_1704193692307&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select EMPNAME, TITLE, DNO, DEPTNAME
from Company.EMPLOYEE as E
	right outer join Company.DEPARTMENT as D
		on (E.DNO = D.DEPTNO) AND (D.DEPTNAME = &quot;영업&quot; OR D.DEPTNAME = &quot;개발&quot;)
where E.DNO is NULL&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-02 20.09.34.png&quot; data-origin-width=&quot;325&quot; data-origin-height=&quot;62&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bENomf/btsCUXZwgFJ/KCoNm7vQC3DNpMZS9z1Xrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bENomf/btsCUXZwgFJ/KCoNm7vQC3DNpMZS9z1Xrk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bENomf/btsCUXZwgFJ/KCoNm7vQC3DNpMZS9z1Xrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbENomf%2FbtsCUXZwgFJ%2FKCoNm7vQC3DNpMZS9z1Xrk%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;325&quot; height=&quot;62&quot; data-filename=&quot;스크린샷 2024-01-02 20.09.34.png&quot; data-origin-width=&quot;325&quot; data-origin-height=&quot;62&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;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;FULL OUTER JOIN&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;스크린샷 2024-01-02 20.06.34.png&quot; data-origin-width=&quot;189&quot; data-origin-height=&quot;425&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RJXiB/btsC1Hajxtn/yKt5QNJmjHuWKkGDMtkQrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RJXiB/btsC1Hajxtn/yKt5QNJmjHuWKkGDMtkQrk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RJXiB/btsC1Hajxtn/yKt5QNJmjHuWKkGDMtkQrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRJXiB%2FbtsC1Hajxtn%2FyKt5QNJmjHuWKkGDMtkQrk%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;189&quot; height=&quot;425&quot; data-filename=&quot;스크린샷 2024-01-02 20.06.34.png&quot; data-origin-width=&quot;189&quot; data-origin-height=&quot;425&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;MySQL에서는 FULL OUTER JOIN을 지원하지 않는다고 한다.. 머쓱..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LEFT, RIGHT OUTER JOIN의 결과값 모두 출력된다고 생각하면 된다.&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;상호 조인 (CROSS JOIN)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;한쪽 테이블의 모든 행과 다른 쪽 테이블의 모든 행을 조인시키는 기능&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt; 상호 조인 결과의 전체 행 개수는 두 테이블의 각 행의 개수를 곱한 수만큼 생성된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;카티션 곱&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&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 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;□ 양식&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1704194519190&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT *
FROM &amp;lt;첫 번째 테이블&amp;gt;
    CROSS JOIN &amp;lt;두 번째 테이블&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-02 20.18.58.png&quot; data-origin-width=&quot;566&quot; data-origin-height=&quot;509&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nUvwC/btsCTBh9Aq9/wMpcyFkvxkef3HFv1HLahk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nUvwC/btsCTBh9Aq9/wMpcyFkvxkef3HFv1HLahk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nUvwC/btsCTBh9Aq9/wMpcyFkvxkef3HFv1HLahk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnUvwC%2FbtsCTBh9Aq9%2FwMpcyFkvxkef3HFv1HLahk%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;450&quot; data-filename=&quot;스크린샷 2024-01-02 20.18.58.png&quot; data-origin-width=&quot;566&quot; data-origin-height=&quot;509&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;pre id=&quot;code_1704194496727&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select EMPNAME, TITLE, DNO, DEPTNAME
from Company.EMPLOYEE as E
	cross join Company.DEPARTMENT D&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-02 20.22.35.png&quot; data-origin-width=&quot;327&quot; data-origin-height=&quot;455&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7iaRE/btsC2DMfVEV/ZKVNOcAUFA2Y3KoVfheLB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7iaRE/btsC2DMfVEV/ZKVNOcAUFA2Y3KoVfheLB1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7iaRE/btsC2DMfVEV/ZKVNOcAUFA2Y3KoVfheLB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7iaRE%2FbtsC2DMfVEV%2FZKVNOcAUFA2Y3KoVfheLB1%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;327&quot; height=&quot;455&quot; data-filename=&quot;스크린샷 2024-01-02 20.22.35.png&quot; data-origin-width=&quot;327&quot; data-origin-height=&quot;455&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;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;p data-ke-size=&quot;size16&quot;&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;a href=&quot;https://github.com/Songwonseok/CS-Study/blob/main/Database/JOIN.md&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/Songwonseok/CS-Study/blob/main/Database/JOIN.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;MS SQL 서버 기반 데이터베이스 배움터 책&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hongong.hanbit.co.kr/sql-%EA%B8%B0%EB%B3%B8-%EB%AC%B8%EB%B2%95-joininner-outer-cross-self-join/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://hongong.hanbit.co.kr/sql-%EA%B8%B0%EB%B3%B8-%EB%AC%B8%EB%B2%95-joininner-outer-cross-self-join/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gent.tistory.com/376&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://gent.tistory.com/376&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>CS/DataBase</category>
      <category>Database</category>
      <author>HJ39</author>
      <guid isPermaLink="true">https://hj39-develop.tistory.com/198</guid>
      <comments>https://hj39-develop.tistory.com/198#entry198comment</comments>
      <pubDate>Tue, 2 Jan 2024 18:19:53 +0900</pubDate>
    </item>
    <item>
      <title>Key</title>
      <link>https://hj39-develop.tistory.com/197</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;데이터베이스에서 조건에 만족하는 튜플을 찾거나 순서대로 정렬할 때 다른 튜플들과 구별할 수 있는 유일한 기준이 되는 Attribute(속성)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #555555;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #555555;&quot; data-ke-size=&quot;size16&quot;&gt;최악의 경우 모든 Attribute들을 사용하면 튜플을 고유하게 식별할 수 있는데 다음과 같은 이유로 최소한의 Attribute로 이루어진 키에 관심을 갖게 된다.&lt;/p&gt;
&lt;p style=&quot;color: #555555;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #555555;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 불필요하게 중복되는 Attribute가 많아지면 데이터 저장 공간이 낭비되고, 쿼리 성능이 저하될 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #555555;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;릴레이션 A&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 65.1163%; height: 56px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style14&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 25%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;신용카드번호&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;이름&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;주민등록번호&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;주소&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 25%; text-align: center; height: 18px;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center; height: 18px;&quot;&gt;A&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center; height: 18px;&quot;&gt;XXXX-XXXX&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center; height: 18px;&quot;&gt;서울특별시...&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 25%; text-align: center; height: 18px;&quot;&gt;2&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center; height: 18px;&quot;&gt;B&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center; height: 18px;&quot;&gt;YYYY-YYYY&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center; height: 18px;&quot;&gt;인천광역시...&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #555555;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #555555;&quot; data-ke-size=&quot;size16&quot;&gt;릴레이션 B&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 91.2791%; height: 112px;&quot; border=&quot;1&quot; data-ke-style=&quot;style14&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #008300; color: #ffffff; text-align: center; width: 18.5004%;&quot;&gt;&lt;b&gt;신용카드번호&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #008300; color: #ffffff; text-align: center; width: 17.6287%;&quot;&gt;&lt;b&gt;이름&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #008300; color: #ffffff; text-align: center; width: 24.6967%;&quot;&gt;&lt;b&gt;주민등록번호&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #008300; color: #ffffff; text-align: center; width: 22.3777%;&quot;&gt;&lt;b&gt;주소&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #008300; color: #ffffff; text-align: center; width: 30.5466%;&quot;&gt;&lt;b&gt;사용금액&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #efefef; text-align: center; width: 18.5004%;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 17.6287%;&quot;&gt;A&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 24.6967%;&quot;&gt;XXXX-XXXX&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 22.3777%;&quot;&gt;서울특별시...&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 30.5466%;&quot;&gt;1,000,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #efefef; text-align: center; width: 18.5004%;&quot;&gt;2&lt;/td&gt;
&lt;td style=&quot;background-color: #f9f9f9; text-align: center; width: 17.6287%;&quot;&gt;B&lt;/td&gt;
&lt;td style=&quot;background-color: #f9f9f9; text-align: center; width: 24.6967%;&quot;&gt;YYYY-YYYY&lt;/td&gt;
&lt;td style=&quot;background-color: #f9f9f9; text-align: center; width: 22.3777%;&quot;&gt;인천광역시...&lt;/td&gt;
&lt;td style=&quot;background-color: #f9f9f9; text-align: center; width: 30.5466%;&quot;&gt;600,000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #555555;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #555555;&quot; data-ke-size=&quot;size16&quot;&gt;릴레이션 A, B에 키를 (신용카드번호, 이름, 주민등록번호, 주소)라고 했을 때, 연관된 릴레이션마다 &lt;span style=&quot;color: #555555; text-align: start;&quot;&gt;(신용카드번호, 이름, 주민등록번호, 주소)이 키값들이 릴레이션에 중복되서 들어가게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #555555;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555; text-align: start;&quot;&gt;불필요하게 중복되므로 데이터베이스 저장공간이 낭비되고, 많은 양의 키 값을 처리해야 하므로 쿼리 성능이 저하될 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #555555;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #555555;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #555555; text-align: start;&quot;&gt;2. 키가 작을수록 인덱스의 크기가 줄어들고 인덱스 검색하는 시간이 단축된다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #555555;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555; text-align: start;&quot;&gt;릴레이션의 튜플들에 접근하기 위해 키에 인덱스들을 만드는데, 키가 작을 수록 인덱스의 크기가 줄어들어 시간이 단축된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #555555;&quot; data-ke-size=&quot;size16&quot;&gt;인덱스에 대한 설명은 다음에..&lt;/p&gt;
&lt;p style=&quot;color: #555555;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #555555;&quot; 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;수퍼키(SuperKey)&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 릴레이션 내의 특정 튜플을 고유하게 식별하는 하나의 Attribute 또는 Attribute들의 집합이다.&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;릴레이션 A&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 65.1163%; height: 56px;&quot; border=&quot;1&quot; data-ke-style=&quot;style14&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #008300; color: #ffffff; text-align: center;&quot;&gt;&lt;b&gt;신용카드번호&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #008300; color: #ffffff; text-align: center;&quot;&gt;&lt;b&gt;이름&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #008300; color: #ffffff; text-align: center;&quot;&gt;&lt;b&gt;주민등록번호&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #008300; color: #ffffff; text-align: center;&quot;&gt;&lt;b&gt;주소&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #efefef; text-align: center;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;A&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;XXXX-XXXX&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;서울특별시...&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #efefef; text-align: center;&quot;&gt;2&lt;/td&gt;
&lt;td style=&quot;background-color: #f9f9f9; text-align: center;&quot;&gt;B&lt;/td&gt;
&lt;td style=&quot;background-color: #f9f9f9; text-align: center;&quot;&gt;YYYY-YYYY&lt;/td&gt;
&lt;td style=&quot;background-color: #f9f9f9; text-align: center;&quot;&gt;인천광역시...&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;릴레이션 A에서 수퍼키는 (신용카드번호, 주소), (주민등록번호, 이름), (주민등록번호)등이 수퍼키가 될 수 있다.&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;br /&gt;튜플들을 고유하게 식별하는데 필요하지 않은 Attribute들을 포함할 수 있다. (주의)&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;후보키 (Candidate Key)&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 튜플을 고유하게 식별하는 최소한의 Attribute들의 모임&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;후보키의 Attribute들 중 한 개의 Attribute를 빼면 고유하게 식별하는 능력을 잃어버린다.&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;모든 릴레이션에는 한 개 이상의 후보키가 존재한다. (최악의 경우 모든 Attribute를 사용해야 한다)&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;후보키가 두 개 이상의 Attribute로 구성되어 있는 것을 &lt;b&gt;복합 키(Composite Key)&lt;/b&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;&lt;b&gt;기본키 (Primary Key)&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 개의 릴레이션에서 두 개 이상의 후보키가 있으면 DB설계자가 이들 중 한 개를 기본 키로 설정한다.&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;p data-ke-size=&quot;size16&quot;&gt;자연스러운 기본 키가 없는 경우 인위적인 키를 Attribute를 릴레이션에 추가할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가된 키를 &lt;b&gt;대리키(Surrogate Key)&lt;/b&gt;라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) 신용카드 회사의 고객 릴레이션에서 신용카드번호와 주민등록번호가 후보키가 된다.&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;table style=&quot;border-collapse: collapse; width: 58.7191%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;&lt;b&gt;기본키 설정시 고려사항&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;- 모든 튜플을 고유하게 식별해야하므로 null값이나 중복된 값을 가질 수 없다.&lt;br /&gt;- Attribute값이 변경될 가능성이 높은 Attribute는 기본키로 설정하지 않는다.&lt;br /&gt;- 가능하면 작은 정수 값이나 짧은 문자열을 갖는 Attribute&lt;br /&gt;- 복합 기본키를 가능하면 피하는 것이 좋다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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;대체 키(Alternate Key)&lt;/b&gt;&lt;/li&gt;
&lt;/ul&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;릴레이션 A&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 65.1163%; height: 56px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style14&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #008300; color: #ffffff; text-align: center;&quot;&gt;&lt;b&gt;신용카드번호&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #008300; color: #ffffff; text-align: center;&quot;&gt;&lt;b&gt;이름&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #008300; color: #ffffff; text-align: center;&quot;&gt;&lt;b&gt;주민등록번호&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #008300; color: #ffffff; text-align: center;&quot;&gt;&lt;b&gt;주소&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #efefef; text-align: center;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;A&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;XXXX-XXXX&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;서울특별시...&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #efefef; text-align: center;&quot;&gt;2&lt;/td&gt;
&lt;td style=&quot;background-color: #f9f9f9; text-align: center;&quot;&gt;B&lt;/td&gt;
&lt;td style=&quot;background-color: #f9f9f9; text-align: center;&quot;&gt;YYYY-YYYY&lt;/td&gt;
&lt;td style=&quot;background-color: #f9f9f9; text-align: center;&quot;&gt;인천광역시...&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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;&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 alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;287&quot; data-origin-height=&quot;176&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbqdZN/btsCMxnptnV/P4J4bJgmdYHnPu7k6zq2X0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbqdZN/btsCMxnptnV/P4J4bJgmdYHnPu7k6zq2X0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbqdZN/btsCMxnptnV/P4J4bJgmdYHnPu7k6zq2X0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbqdZN%2FbtsCMxnptnV%2FP4J4bJgmdYHnPu7k6zq2X0%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;328&quot; height=&quot;201&quot; data-origin-width=&quot;287&quot; data-origin-height=&quot;176&quot;/&gt;&lt;/span&gt;&lt;/figure&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;&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;외래키 (Foreign Key)&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 릴레이션의 기본키를 참조하는 Attribute&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;R-DBMS에서 릴레이션들 간의 관계를 나타내기 위해 사용&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;/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;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1623&quot; data-origin-height=&quot;1000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l5dGQ/btsCTWl7FkM/8ya5ov6dllWKkvnD8iKeBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l5dGQ/btsCTWl7FkM/8ya5ov6dllWKkvnD8iKeBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l5dGQ/btsCTWl7FkM/8ya5ov6dllWKkvnD8iKeBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl5dGQ%2FbtsCTWl7FkM%2F8ya5ov6dllWKkvnD8iKeBk%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;600&quot; height=&quot;1000&quot; data-origin-width=&quot;1623&quot; data-origin-height=&quot;1000&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;□ 자체 릴레이션의 기본 키를 참조하는 외래 키&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1083&quot; data-origin-height=&quot;355&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTzSO7/btsCRhqRfM9/2bmVqmfjTex6LiJm61lwQK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTzSO7/btsCRhqRfM9/2bmVqmfjTex6LiJm61lwQK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTzSO7/btsCRhqRfM9/2bmVqmfjTex6LiJm61lwQK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTzSO7%2FbtsCRhqRfM9%2F2bmVqmfjTex6LiJm61lwQK%2Fimg.jpg&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;600&quot; height=&quot;355&quot; data-origin-width=&quot;1083&quot; data-origin-height=&quot;355&quot;/&gt;&lt;/span&gt;&lt;/figure&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;직속상관이 없는 경우 NULL로 표현이 가능하다.&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;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1005&quot; data-origin-height=&quot;799&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cR7oLw/btsCX6IiTBE/mmdmCc7a1c9hxQKVc1OnW1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cR7oLw/btsCX6IiTBE/mmdmCc7a1c9hxQKVc1OnW1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cR7oLw/btsCX6IiTBE/mmdmCc7a1c9hxQKVc1OnW1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcR7oLw%2FbtsCX6IiTBE%2FmmdmCc7a1c9hxQKVc1OnW1%2Fimg.jpg&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;600&quot; height=&quot;799&quot; data-origin-width=&quot;1005&quot; data-origin-height=&quot;799&quot;/&gt;&lt;/span&gt;&lt;/figure&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;수강 릴레이션에 최소한의 Attribute로 구성된 기본키가 없으므로 (학번, 과목번호)가 기본 키가 된다.&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;자연키&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본키만을&amp;nbsp;위한&amp;nbsp;데이터가&amp;nbsp;아니라&amp;nbsp;비즈니스&amp;nbsp;모델에서&amp;nbsp;자연스레&amp;nbsp;나오는&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;인조키&lt;/b&gt;&lt;/li&gt;
&lt;/ul&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 style=&quot;color: #555555;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #555555;&quot; data-ke-size=&quot;size16&quot;&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;a href=&quot;https://limkydev.tistory.com/108&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://limkydev.tistory.com/108&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Songwonseok/CS-Study/blob/main/Database/%ED%82%A4(Key)%20%EC%A0%95%EB%A6%AC.md&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/Songwonseok/CS-Study/blob/main/Database/%ED%82%A4(Key)%20%EC%A0%95%EB%A6%AC.md&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>CS/DataBase</category>
      <category>Database</category>
      <author>HJ39</author>
      <guid isPermaLink="true">https://hj39-develop.tistory.com/197</guid>
      <comments>https://hj39-develop.tistory.com/197#entry197comment</comments>
      <pubDate>Mon, 1 Jan 2024 00:46:56 +0900</pubDate>
    </item>
    <item>
      <title>App thinning</title>
      <link>https://hj39-develop.tistory.com/196</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;애플리케이션을 설치할 때, 앱스토어와 운영체제가 디바이스의 환경에 맞게 설치하는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;설치 최적화 기술&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;필요한 만큼의 리소스만 다운로드하기에 적은 디스크 사용량, 빠른 다운로드를 제공&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;Slicing&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-07-23 22.12.53.png&quot; data-origin-width=&quot;618&quot; data-origin-height=&quot;360&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQzIuB/btsoGhwIlDH/57wZmJnrCvx2S8tAACkDaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQzIuB/btsoGhwIlDH/57wZmJnrCvx2S8tAACkDaK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQzIuB/btsoGhwIlDH/57wZmJnrCvx2S8tAACkDaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQzIuB%2FbtsoGhwIlDH%2F57wZmJnrCvx2S8tAACkDaK%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;618&quot; height=&quot;360&quot; data-filename=&quot;스크린샷 2023-07-23 22.12.53.png&quot; data-origin-width=&quot;618&quot; data-origin-height=&quot;360&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 가지 디바이스와 운영체제를 위한 앱 번들의 variants(변형)을 생성 및 제공하는 과정&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;variants(변형)에는 각 디바이스와 운영체제가 필요로 하는 실행 가능한 아키텍처와 리소스가 담겨있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자가 앱스토어 커넥트에 풀버전의 앱 빌드를 업로드하게 되면 앱스토어는 자동적으로 variants를 생성하고 전달한다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;유저가 앱스토어에서 앱을 다운로드하게 되면, 유저의 디바이스와 운영체제 버전에 맞는 variants를 다운로드하게 된다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;on-demand&lt;span&gt;&amp;nbsp;&lt;/span&gt;resource(ODR)&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;주문형 리소&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;스는 이미지, 음원과 같은 앱의 리소스를 키워드로 태그 해놓고, 태그를 통해 그룹으로 요청이 가능한 리소스&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;앱스토어는 사용자&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;에게 현재 필요한 리소스를 관리하고 다운로드하게 한다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;또한 주문형 리소스의 슬라이싱 작업을 통해 variants의 최적화 작업을 진행한다.&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot;&gt;앱의 사이즈가 작아지게 되고, 이를 통해 더 빠른 다운로드를 제공, 사용자가 앱의 최초 실행 경험을 개선하게 된다.&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot;&gt;사용자가 앱을 체험하면서 필요하게 되는 주문형 리소스들을 백그라운드에서 다운로드하게 된다.&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc;&quot;&gt;운영체제가 더 이상 필요로 하지 않는 주문형 리소스들은 제거하게 되고, 이로 인해 저장공간을 절약한다.&lt;/li&gt;
&lt;/ul&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;847&quot; data-origin-height=&quot;698&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/85kwF/btsoyoqdI0Q/9mVx0tcqztpKFzncjq73h0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/85kwF/btsoyoqdI0Q/9mVx0tcqztpKFzncjq73h0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/85kwF/btsoyoqdI0Q/9mVx0tcqztpKFzncjq73h0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F85kwF%2FbtsoyoqdI0Q%2F9mVx0tcqztpKFzncjq73h0%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;412&quot; data-origin-width=&quot;847&quot; data-origin-height=&quot;698&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;대표적인 예시를 들 수 있는 경우가 게임의 추가 리소스 다운이다. 일반적으로 이미지와 음원이 많은 게임 앱의 경우, 최초 실행을 위한 최소한의 리소스를 우선적으로 받고, 게임 실행 후 필요한 부분만 리소스를 추가적으로 다운로드하여 저장공간 절약, 실행을 위한 다운로드 시간 감소 등 대용량 앱 사용에 더욱 쾌적한 환경을 제공할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;위 그림으로 살펴보자면 현재 필요한 리소스는 Level 1만 필요한데 처음 다운로드를 할 때 Level 2를 다운로드하여 휴대폰의 리소스를 낭비하지 않게 하는 방법이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;Level 1을 사용하던 중 Level 2 ODR을 사용하기 위해 Level 2를 다운로드하면 자동적으로 이제는 필요 없는 Level 1 ODR을 삭제하여 공간을 확보하는 방법이다.&lt;/span&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;bitcode&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;개발자는 앱스토어 커넥트에 자신의 앱에 비트 코드를 포함시켜 올릴 수 있으며 그러한 비트 코드는 컴파일되어 앱스토어에 연결된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;애플은 업로드된 비트 코드를 통해서 개발자의 새로운 버전의 앱 업로드 없이도 앱 바이너리를 최적화할 수 있다고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;따라서 최신 컴파일러용으로 자동으로 앱을 컴파일하고,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: center;&quot;&gt;특정 아키텍처(예 : iPhone 6 및 iPad Air 2와 같은 64 비트 프로세서의 경우 arm64)에 맞게 최적화한다고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Bitc&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;ode&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;는 다른 아키텍처에 대한 최적화를 제거하여 다운로드는 더 작게 만듦 / 관련 최적화만 다운로드하여 위에 언급한 App Thining 기술과 함께 사용됩니다. (App Slicing 방법을 사용한다고 한다)&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 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;Bitcode는 기계어와 인간이 읽을 수 있는 언어 중간 단계의 언어로 &lt;span style=&quot;color: #000000;&quot;&gt;일련의 지침이 주어지면 &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000; background-color: #ffffff; text-align: center; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;다양한 방식으로 다시 컴파일하는 데 사용할 수 있는 앱의 추상 인코딩이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 예전&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-07-23 23.56.57.png&quot; data-origin-width=&quot;654&quot; data-origin-height=&quot;187&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFaili/btsoxHD10oK/zGwYvx9K1tAvhB5vMBLyB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFaili/btsoxHD10oK/zGwYvx9K1tAvhB5vMBLyB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFaili/btsoxHD10oK/zGwYvx9K1tAvhB5vMBLyB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFaili%2FbtsoxHD10oK%2FzGwYvx9K1tAvhB5vMBLyB0%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;143&quot; data-filename=&quot;스크린샷 2023-07-23 23.56.57.png&quot; data-origin-width=&quot;654&quot; data-origin-height=&quot;187&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; background-color: #ffffff; text-align: center; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&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 style=&quot;color: #000000; background-color: #ffffff; text-align: center; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;지금은 bitcode가 적용되어 새로운 아키텍처가 나와도 개발자가 다시 코드를 수정할 필요가 없다고 한다. ㅎㅎ&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 data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;※ 참고&lt;/span&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;a href=&quot;https://hyun083.tistory.com/80&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://hyun083.tistory.com/80&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zeddios.tistory.com/655&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://zeddios.tistory.com/655&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;</description>
      <category>iOS/iOS 상식</category>
      <category>ios</category>
      <author>HJ39</author>
      <guid isPermaLink="true">https://hj39-develop.tistory.com/196</guid>
      <comments>https://hj39-develop.tistory.com/196#entry196comment</comments>
      <pubDate>Sun, 23 Jul 2023 23:58:47 +0900</pubDate>
    </item>
    <item>
      <title>Async/Await</title>
      <link>https://hj39-develop.tistory.com/195</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;async는 함수가 비동기로 처리된다는 것을 의미한다.&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 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;await은 &lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;마킹된 곳은 potential suspension point(잠재적 일시 중단 지점)로 지정된다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;async로 선언한 함수가 완료될 때까지 일시 중지 되는 지점이다.&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 data-ke-size=&quot;size16&quot;&gt;□ 예시&lt;/p&gt;
&lt;pre id=&quot;code_1690043761543&quot; class=&quot;swift&quot; data-ke-language=&quot;swift&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;func asyncTest() async throws -&amp;gt; String {
    try await Task.sleep(nanoseconds: 3_000_000_000) //3초
    return &quot;sleep 끝&quot;
}

print(&quot;before task&quot;)
Task{
    let string: String = try await asyncTest()
    print(string)
}
print(&quot;after task&quot;)

// 출력
// before task
// after task
// sleep 끝&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;asyncTest() 함수는 3초 뒤에 &quot;sleep 끝&quot;을 출력한다.&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;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://jeong9216.tistory.com/498&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://jeong9216.tistory.com/498&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</description>
      <category>iOS/Swift 상식</category>
      <category>swift</category>
      <author>HJ39</author>
      <guid isPermaLink="true">https://hj39-develop.tistory.com/195</guid>
      <comments>https://hj39-develop.tistory.com/195#entry195comment</comments>
      <pubDate>Sun, 23 Jul 2023 01:59:43 +0900</pubDate>
    </item>
  </channel>
</rss>