달력

92016  이전 다음

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
카테고리 없음 2016. 9. 23. 10:33

***************************************************************************

제가 작성한것이 아닌 다른 블로그에서 퍼온 글입니다.

공부하면서 필요했던 내용들이고 공유했으면 하는 마음으로 올립니다.

출처는 밝혀 놓았고, 문제가 될시 수정하겠습니다. 감사합니다.

***************************************************************************


의 일부가 되어 버린 인터넷에서 가장 중요한 것이 무엇인가? 어떤 사람들은 당장 자신이 자주 사용하는 서비스를 생각할 수 있고 누군가는 메신저 서비스 등 자신이 친숙한 것을 먼저 떠올리게 될 것이다. 그러나 전기가 이 세상에서 사라진다고 상상하면 상황은 달라진다. 인터넷이 삶의 일부일 수 있는 이유는 가장 먼저 전기를 사용할 수 있다는 기본적 조건을 충족시키기 때문이다. 그리고 작은 소형 스마트폰부터 시작해서 대형 컴퓨터까지 모든 것들은 인터넷에 서비스를 하고 사용자들이 사용할 수 있도록 다양한 표준을 따라서 이에 맞춰 활용하기 때문에 가능하다는 사실은 조금만 생각하면 알게 된다. 그렇다면 전기라는 가장 기본적인 조건을 충족시킨 다음은 중요한 것은 무엇이 있을까?

미국드라마 Revolution 은 전세계의 전기가 사라지면서 생기는 이야기들을 전한다. 너무도 당연한 요소가 사라져야 그 소중함을 느끼게 된다.


누구나 인터넷 웹브라우저에서 검색을 위해서 'google.com' 이라고 주소를 입력하면 구글의 홈페이지가 나올 것을 기대한다. 그런데 아주 간단한 궁금증이 생긴다. 내가 google.com 이라고 입력했을 때 구글의 서비스를 사용할 수 있도록 구글의 홈페이지를 제공하는 서버가 전세계 어디에 있는지 알 수 있는가? 즉, 내가 실제 접속해서 필요한 페이지를 다운 받아서 내 컴퓨터에 보여주기 위해서 어떤 서버 컴퓨터에 접속해야 하는지 어떻게 알 수 있는지에 대해서 물어본다.

DNS 서비스에 대해서...

DNS 는 Domain Name Service 의 약자이다. 도메인이란 우리가 인터넷 주소로 사용하는 모든 이름을 이야기한다. 블로그에 들어오기 위해서 검색엔진에서 원하는 검색어를 통해 검색된 결과에서 클릭해서 들어올 수 있지만 주소를 직접 알기 때문에 june.meson.kr 이란 주소를 직접 입력하고 들어올 수 있다. 검색 엔진에서 검색된 결과의 경우에도 해당 페이지가 가지는 주소는 도메인을 가진다. 도메인이란 인터넷 상의 주소이다. 도메인은 인간이 쉽게 인지할 수 있는 의미를 가지는 주소를 사용하기 위해 필요하다. 일반적으로 지인에게 편지를 보낼 때 주소 + 수취인 의 정보를 적어야 상대방에게 전달될 수 있는 것과 소포를 보낼 때 일반 등기 우편 및 택배와 같이 보내는 방법 (protocol) 이 다른 것처럼 인터넷에도 이와 같이 정보를 주고 받는 방법 (protocol) 과 주소 (domain) 그리고 대상 (object) 가 주어져야 인터넷의 정보를 획득할 수 있게 되는 것이다.

http://blog.meson.kr

이란 주소를 살펴보면 http:// 이란 프로토콜 (주고 받는 약속) 을 표현하고 뒤의 blog.meson.kr 는 주소를 뜻하는 도메인을 뜻한다. 다른 예로...

mailto:myid@meson.kr

과 같이 되어 있으면  mailto: 라는 전자메일 (email) 을 사용하고 그 해당 수취인은 meson.kr 이란 메일 서버에 있는 아이디 myid 를 가진 사람에게 전달하란 약속체계이다.


아주 간단하다. 그런데 여전히 의문은 인간은 이처럼 아주 간단하게 확인하고 인지할 수 있지만 이를 처리하는 컴퓨터도 이처럼 간단하게 처리할 수 있는가란 질문에는 그리 쉽게 대답할 수 없다. 우선 http (hypertext transfer protocol) 이란 웹의 표준을 이용해서 페이지를 보여준다고 정하고 이를 해석할 수 있는 웹브라우저가 있어도 blog.meson.kr 이란 주소를 가진 서버 (컴퓨터) 가 어디에 있는지 어떻게 알 수 있는지 컴퓨터 시스템은 그리 쉽게 알아내지 못한다. 왜냐하면 컴퓨터는 기본적으로 멍청하기 때문이다. 따라서 컴퓨터가 도메인의 주소와 실제로 접속해야 하는 서버의 실체적인 (physical) 대상에 접속하기 위해서는 이를 해석해주는 또하나의 서비스가 필요하다. 이를 DNS 라고 부른다. 간단하게 DNS 란 인터넷의 익숙한 주소 (도메인) 이 제대로 작동하게 하기 위한 전화번호부 (yellow pages) 라 부를 수 있다. 만약 DNS 서버가 제대로 작동하지 않는다면 아무리 도메인이 정확해도 제대로 된 목적지를 알 수 없기 때문에 목적지 페이지가 열리지 않거나 메일이 전달되지 않을 것이다.

DNS 서비스의 해석 방법에 대해서...

컴퓨터는 기본적으로 멍청하다. 다만 속도가 빠르기 때문에 빠르게 처리하는 것처럼 보이는 것 뿐이다. 인간의 경우 주소를 듣고 '서울시 서초구 잠원동 ...' 이라고 말하면 서울시 서초구... 까지 듣지 않고 잠원동 이라는 정보 하나만으로 상당히 세부적인 지역의 위치를 파악할 수 있다. 이는 인간이 좀 똑똑하기 때문이다. 그러나 컴퓨터는 이처럼 직접적인 인지를 통해서 바로 파악하지 못한다. 메일주소를 통해서 생각해보면...

mailto:myid@univ.ac.kr 

라는 주소를 생각 해보면 우선 컴퓨터는 사용자가 입력한 주소 중 가장 뒷편의 kr 이란 주소를 찾게 된다. 그럼 kr 을 관리하는 DNS 서비스가 존재할 것이다. 해당 DNS 서비스에 접속한다. 즉, 이 간단한 주소체계를 해석하기 위해서 그것도 가장 기본적인 .kr 이란 주소에서 .ac 이란 주소가 도대체 어디를 봐야 하는지 물어본다. .kr 을 담당하는 서버에게 물어본다. '.ac.kr' 이란 주소를 찾고 있는데 여기는 어디를 가야하나요?' 그럼 .kr 을 담당하는 서버는 또다른 전화번호부를 알려준다. 그럼 다시 찾아가서 .ac.kr 를 관리하는 서버에 들어가서 univ.ac.kr 란 주소를 가진 서버는 아이피가 165.125.267.xyz 이다 라고 알려준다. 이렇게 알아낸 최종 목적지 서버의 IP 주소를 알아낸다. 여기에서 IP 주소란 컴퓨터가 인터넷을 사용하기 위해서 부여받는 인터넷 상의 주소이다. 인간에게는 univ.ac.kr 이란 주소이지만 실제로 컴퓨터는 도메인이 아니라 IP 주소를 통해서 통신을 이루게 되는 것이다. 그럼 이 IP 주소에 메일을 보내게 된다. 그리고 그 메일을 받은 univ.ac.kr 이란 서버는 그 중 해당 아이디가 myid 란 계정에게 전달하여 메일을 보낼 수 있게 된다.

인터넷 주소의 해석; 구매하는 도메인은 domain name. top-level domain 이 조합된 주소를 구매한다. 


이처럼 도메인 주소를 최종적으로 보내야 하는 목표 서버가 어디에 있는지 알려주는 서비스가 DNS 서비스이다. 아주 간단한 이야기를 너무 장황하게 설명한 것 같다. 결론적으로 DNS 란 우리가 접속하려는 서버의 실체적인 위치를 알려주는 서비스라고 생각하면 된다.

인 인터넷 서비스를 위해서...

예전에는 자신의 홈페이지를 가진다는 것이 참 어려운 일이었다. 우선 자신의 홈페이지를 올려 놓을 수 있는 서버를 구하는 것이 쉽지 않았다. 이제는 역사의 한 구석으로 사라지는 것 같은 생각마저 드는 개인 홈페이지 주소인 server.univ.ac.kr/~myid 와 같은 ~ 으로 개인 홈페이지 주소를 표시하는 유닉스 서버를 기억하는 사람들도 이제 점점 사라질 것이다. 거의 대부분 개인 계정이 사라진 도메인만으로 구성된 홈페이지 주소를 가지는 것도 어렵지 않다. 대부분의 블로그 서비스도 myid.blogservice.com 과 같은 주소를 제공하기 때문이다.

Search Engine Optimization (SEO) 친화적인 주소체계; 블로그 글의 주소체계에 대한 내용


앞으로 적어 내려갈 내용의 목표는 '최소의 비용으로 운영할 수 있는 개인 인터넷 서비스'이다. 개인 인터넷 서비스란 자신만의 도메인 주소를 가지고 블로그를 운영하거나, 간단한 홈페이지를 보여주거나, 자신만의 메일 주소를 가지는 것과 같은 활동을 인터넷에 대한 전문적 지식이 없어도 쉽게 할 수 있는 방법을 설명할 것이다.

[참고: 본 블로그 내용은 2011년 12월 03일에 작성된 - 개인 도메인을 사용하자 ─ 구글앱스 & DNSEver 서비스 에서 변경된 내용을 반영하고 글의 구성을 변경하여 추가 작성한 내용이다. ] 

[ 기본적인 용어 정리 ]

─ 도메인: 우리가 일상에서 웹브라우저에 입력하는 주소 중, 우리가 알기 쉽도록 지정된 모든 주소를 이야기한다.

─ IP주소: 실제로 우리가 도메인 주소를 웹주소에 입력을 해도 컴퓨터는 우리처럼 똑똑해서 도메인으로 인식하는 것이 아니라 IP주소라고 부르는 숫자로 구성된 주소로 인식하게 된다. 우리가 쉽게 주소창에 google.com 을 입력하면 컴퓨터는 이에 해당하는 IP주소 209.85.148.147 를 인식하고 이에 해당하는 서버(호스트 컴퓨터)에 접속하게 되는 것이다.

─ DNS 서버: 앞서 이야기한대로 우리가 쉽게 기억하고 있는 도메인 주소가 어떤 IP주소를 가지는가의 정보를 가지고 있는 서비스이다. 웹브라우저에서 우리가 google.com 이라고 입력하면 해당 google.com 이라는 도메인이 어떤 IP주소를 가지는지 DNS서버에서 가지고 와서 해당 IP주소의 버서에 접속하게 되는 것이다. 따라서 DNS 서버는 인터넷을 사용하는데 있어 공기와 같은 존재이다. 만약 DNS 서버가 작동을 안하면 우리는 모든 인터넷 주소를 도메인이 아닌 IP주소로 외우거나 입력해놔야할 것이다.

─ 웹호스팅: 자신의 홈페이지를 보여줄 수 있는 물리적인 서버 및 그 기반 시설, 예를 들어 www.yahoo.com 이라고 주소창에 주소를 넣으면 그 주소에 해당하는 물리적인 서버에 연결이 되어서 필요한 자원(텍스트, 이미지 등)을 가지고 와서 웹 브라우저에 보여준다. 이런 역할을 해주는 물리적 서버와 그에 따른 기반 서비스를 웹호스팅이라고 부른다. 


개인 도메인 서비스를 사용하기 위해서는 위의 개념은 가지는 것이 필요하다. 그리 어렵지 않은 내용이기 때문에 간단하게 홈페이지 = 웹호스팅 물리적인 서버도메인 인터넷 주소 =〔DNS서버〕IP주소 이런 구조를 가진다고 생각하면 된다.

메인 구매 혹은 획득

가장 먼저 해야 하는 것은 자신이 원하는 도메인을 구매하는 것이다. 앞서 '최소의 비용' 이란 표현을 쓴 유일한 이유는 바로 도메인 구매에 비용이 발생하기 때문이다. 실질적으로 도메인 구매와 유지 (1년 단위) 를 위한 비용은 거의 들지 않는다고 볼 수 있다. 이유는 무료로 제공하는 서비스들이 적당히(?) 존재하기 때문이다. 도메인 구매는 도메인 구매 업체를 통해서 가능하다. 비용이 발생하는 것이고 시기에 따라서도 비용이 변동되기 때문에 특정 업체를 언급하는 것은 부적절할 것이다. 따라서 인터넷 검색을 통해서 가장 저렴한 구매 업체 + 업체의 안정성을 고려하여 선택하면 된다.

참고로 국내 업체뿐만 아니라 해외 업체의 경우 종종 도메인 하나에 1달러 (1$) 에 판매하기도 한다. 도메인 종류에는 다양하게 존재한다. 국가별 도메인으로 한국의 경우 .kr , 일본의 경우 .jp , 독일의 경우 .de 와 같이 국가를 나타내는 도메인 체계가 있고 잘 알려진 .com , .net , .org , .edu 와 같은 실질적으로 미국 주도의 도메인도 있고 때로는 국가 도메인이 엉뚱한 쓰임으로 인기있는 경우도 있다. 가장 대표적인 예가 .me 는 몬테네그로 국가 도메인인데 자신을 나타내는 me 의 의미로 거의 국가의 의미는 사라진 체 광범위하게 사용되고 bit.ly 와 같이 .ly 는 리비아의 국가 도메인인데 ...ly 와 같이 형용사형 접미사 ly 의 의미가 되어 인기가 있는 경우이다. 도메인 종류에 따라서 가격은 다양하다. 자신이 원하는 도메인 주소를 구매하면 해당 도메인에 대한 소유권 (ownership) 을 가지게 된다.

국가별 도메인 주소 (top-level) 지도


그런데 꼭 도메인은 구매해야 하는 것만은 아니다. 예를 들어 자신이 소속된 기관이나 학교에서 도메인을 획득할 수도 있다. 물론 해당 기관의 자격이 끝나면 이도 정리할 수 있지만 예를 들어 univ.ac.kr 이란 학교에서 자신만의 도메인으로 mydomain.univ.ac.kr 와 같이 univ.ac.kr 을 관리하는 학교 전산관리자에게 mydomain 이란 도메인을 부여받고 싶다고 신청하여 획득할 수 있다. 이 경우 자신의 도메인이 실제로 어떤 컴퓨터 (서버) 인지를 알려주어야 한다. 즉, 자신이 서버로 사용할 IP 주소를 알려주어야 mydomain.univ.ac.kr 에 접속할 때 해당 서버에 접속할 수 있게 될 것이다. 앞서 말한 것처럼 univ.ac.kr 까지 컴퓨터가 찾아와서 해당 학교의 DNS 서버에서 mydomain 이란 이름을 가진 컴퓨터가 어떤 IP 를 가지는지 최종적으로 찾아내는 과정이기 때문이다.

따라서 도메인을 획득할 수 있는 방법은 다양하게 존재한다. 중요한 것은 해당 도메인을 제대로 사용할 수 있는 적절한 권한과 소유권 (permission & ownership) 을 가지고 있어야 한다. 구매한 경우에는 도메인 구매 업체에 자신의 도메인 정보에 대한 내용을 관리할 수있게 된다. 많은 경우 도메인 구매대행 업체에서 이메일, DNS 혹은 간단한 경우 홈페이지를 올릴 수 있는 웹호스팅 서비스까지 제공해주는 경우가 있다. 만족할 수준이라면 도메인 구매 업체에서 제공하는 서비스를 이용하는 것도 하나의 방법이다.

DNS 서비스 사용하기

자신이 쓸 수 있는 도메인의 소유권을 획득하면 이후 이를 이용할 수 있는 DNS 서비스를 사용하는 것이다. 앞서 이야기한 것처럼 DNS 서비스는 인터넷의 주소록이다. 즉, 자신의 도메인에 맞는 적절한 주소를 알려주는 설정을 하는 것이다. 처음 DNS 서비스에 대한 내용을 쓸 때는 DNSEver 란 업체를 중심으로 해서 설명했다. 이유는 당시 무료로 제공했었고 일반 사용자들도 쉽게 접근할 수 있었기 때문이었다. 기업의 입장에서 무료로 제공해주는 것에 한계가 있을 수 있고 안정된 서비스를 위해 유료 서비스를 사용할 필요가 있다. 그러나 개인의 경우 규모가 큰 것이 아니기 때문에 작은 비용이지만 부담이 되는 것도 사실이다. 그렇기 때문에 DNS 의 기본적인 내용을 설명하는 것이 필요하다 본다. DNS 서비스를 무료 (거의 무료) 에 가까운 웹서비스 제공자들을 먼저 소개한다. [ DNS 서비스를 웹상에서 일반 사용자들도 관리할 수 있는 곳만 해당한다. ]

1) DNSEver [ 홈페이지 ]: 초기에는 파격적으로 웹으로 DNS 서비스를 쉽게 관리할 수 있는 서비스를 제공했다. 현재는 정책의 변화로 기본적으로 유료화 되었고 비영리 목적의 개인 및 비영리 단체를 위하여 홈페이지에 DNSEver 배너를 달면 DNS서비스를 무료로 제공하는 “서포터즈 프로그램”을 제공하고 있다. 무료는 아니지만 그래도 많은 사용자들이 쉽게 DNS 를 접할 수 있고 개인 도메인 시대를 열었던 국내 업체 중 가장 큰 역할을 했다고 평가해서 가장 먼저 소개하게 되었다.

2) DNSZi [ 홈페이지 ]: 무료이며 기본적인 DNS 서비스를 제공한다. 웹포워딩 서비스가 인상적이다.

3) FreeDNS ; Afraid DNS [ 홈페이지 ]: 기본적 서비스는 무료이지만 제한적이다. 독특하게 자신이 가진 도메인을 다른 사람들이 사용할 수 있도록 도메인 공유 (public subdomains) 기능을 제공한다.

4) CloudFlare [ 홈페이지 ]: 무료 서비스에서 사용할 수 있는 기능의 갯수 등 제한적 부분이 있지만 기본적 서비스는 무료로 제공된다. 무료 SSL 연결을 제공한다. 


네 곳 이외 아직 찾지 못한 서비스들도 있지만 개인적으로 사용한[하고 있는] 서비스만 소개했다. 그렇다면 이제 DNS 서비스에서 사용자가 무엇을 할 수 있는지 살펴본다.

DNS 서비스의 내용

a. DNS 서버 주소 등록

도메인 구매 업체는 일차적으로 구매한 도메인에 대한 정보를 제공한다. 내가 구매한 도메인이 meson.kr 이고 myblog.meson.kr 이란 주소를 가진 서버 IP 가 무엇인지 알기 위해서 .kr 을 찾아보고 그중 meson.kr 이란 주소를 찾고 myblog.meson.kr 이란 도메인이 어떤 IP 를 가지는지 확인하기 위해서 어떤 주소록을 찾아야 하는지 물어본다. 즉, meson.kr 이란 도메인에 연결된 DNS 서버가 무엇인지 물어본다. 그렇기 때문에 DNS 서비스에 가입하고 자신의 도메인이 획득한 도메인 (meson.kr) 을 등록하면 해당 DNS 서비스에서 자신의 DNS 서버 주소를 알려준다. 이 DNS 서버 주소를 도매인 구매 업체의 설정 화면에 입력해야 meson.kr 이 어떤 DNS 서버를 사용하는지 인터넷 상에서 알려주는 것이다.

인터넷 접속 순간 어떤 일들이 일어나는가?서버의 성능은 실제 인터넷 속도에 영향을 준다. 출처: 인텔


DNS 서버도 동일하게 도메인 이름 (Domain Name) 을 가지고 이에 해당하는 IP 주소를 가진다. 이를 알려주는대로 도매인 구매 업체 설정화면에 들어가서 설정해주면 된다.

b. A 레코드 (A Record)

A 레코드란 앞서 설명한 모든 DNS 의 기본적 내용이다. 즉, 해당 도메인 주소가 가지는 IP 가 무엇인지 알려주는 것이다. 예를 들어 blog.meson.kr 이란 주소는 110.45.229.135 이란 IP 를 가진다. 웹브라우저에서 blog.meson.kr 이란 주소를 입력하면 결국 DNS 는 해당 블로그를 들어가기 위해서는 110.45.229.135 이란 IP 주소를 가지는 서버에 접속하록 알려주는 것이다.


만약 ftp 서비스를 제공하고 싶다면 ftp 를 제공하는 서버를 구성하고 이 서버의 IP 주소를 알아서 해당 IP 주소를 ftp 와 함께 등록하면 간단하게 끝이다. 그 다음에 복잡하게 IP 주소를 입력해서 접속하지 않고 ftp.meson.kr 이란 입력하기 편한 주소로 접속하면 된다. 예를 들어 연구실 동료의 컴퓨터에 접속할 때도 응용할 수 있다. myfriend 란 도메인을 등록하고 상대 컴퓨터의 IP 를 입력하면 매번 상대방 아이피를 확인하지 않고 myfriend.meson.kr 이라 입력해서 들어갈 수 있다. 웹뿐만 아니라 이 원도우즈 공유 / 리눅스 삼바 공유에도 사용할 수 있다. 예를 들어 파일 탐색기에서\\myfriend.meson.kr 이라 접속할 수 있다. 개인적으로는 printer.meson.kr 와 같이 네트워크 프린터 접속을 위해서도 등록하고 사용한다.

c. CNAME 별명 (CNAME Alias)

A 레코드의 경우 특정 IP 를 지정해야 하지만 모든 웹 서비스가 1:1 로 IP 주소가 지정되기 어렵다. 또한 다양한 주소가 접근하는 서비스가 동일한 경우라면 각 도메인마다 하나씩 IP 주소를 할당해주는 것도 비효율적이다. 이경우 해당 도메인 주소가 가지는 별명을 부여하여 해당 도메인이 어떤 주소로 접속하면 되는지 확인해주는 것이다. CNAME 이란 Canonical Name Record 의 약자이다. 예를 들어 웹서비스, FTP 서비스 등을 해주어서 www.mydomain.com 과 ftp.mydomain.com 의 주소를 가진다고 할 때 두개의 다른 도메인을 가지지만 실제로 접속하는 물리적인 서버는 동일하다고 할 때 두개의 A 레코드를 동일한 IP 주소로 부여할 수 있을 것이다. 그러나 관리적 차원에서 IP 를 변경하게 된다면 그때마다 두개의 IP 주소를 변경해주면 상당히 번거롭기 때문에 server.domain.com 이란 서버의 이름을 가진 서버에 별칭을 모두 주면 server.domain.com 의 IP 주소만 변경하면 www 와 ftp 도메인 주소 모두 별도의 DNS 변경을 해주지 않아도 그대로 서비스를 사용할 수 있게 된다.


d. MX 레코드 (MX Reocrd)

MX 란 Mail eXchange 레코드로 기본적으로 메일을 주고 받을 수 있도록 가능하게 해주는 서비스이다. 예를 들어myid@meson.kr 이란 이메일 주소로 메일을 주고 받을 수 있는 이유는 meson.kr 이란 도메인이 메일을 주고 받을 수 있는 실체적 서버가 누구인지 밝혀주고 있기 때문이다. 개인이 서버를 두고 서비스를 할 수 있지만 쉽게 구성하기 어렵고 (사실 그렇게까지 어렵지는 않지만...) 무엇보다 보안과 관리에 신경쓰이기 때문에 자신의 도메인을 가지고 메일 서비스를 사용할 수 있는 서비스를 이용하는 것이 가장 현명한 방법이 될 것이다.

Google Apps (구글앱스) 메일 설정을 위한 MX 레코드 값


대표적으로 제공하는 업체는 구글, 네이버, 다음, 마이크로소프트 등이 있다. 이 밖에도 앞서 말한 도메인 구매 업체에서도 메일 서비스를 제공하는 경우가 있다. 그러나 구글과 마이크로소프트는 초기의 무료 제공 정책을 변경하여 유료로 정책이 변경되었다. 구글은 Google Apps for Work 으로 유료 제공하고 교육기관의 경우 Google Apps for Education 으로 무료이지만 개인은 해당사항이 제한적이다. 마이크로소프트의 경우 Office 365 란 이름으로 유료 사용이 가능하다. 무료로 [ 네이버 웍스 [ 다음 스마트 워크 사용가능하다. 예를 들어 구글을 통해 서비스를 등록하면 해당 MX 정보를 DNS 정보에 입력하면 된다. 이후 메일을 사용하기 위한 설정, 사용법은 일반적 구글메일 (쥐메일) 사용법과 동일하다. 마찬가지로 네이버나 다음의 경우에도 자신의 도메인 주소로 메일을 주고 받을 수 있으면서 해당 서비스에서 제공하는 클라우드 등 부가적인 서비스도 일반 가입자와 동일하게 사용할 수 있게 된다. 한가지 다르다면 동일한 도메인을 사용하는 사용자들을 하나의 업무 그룹으로 취급해서 설정할 수 있다는 점을 추가할 수 있다.

e. TXT 레코드 (TXT Record)

일반적인 텍스트 내용을 기록한다. 예를 들어 아무리 컴퓨터만 알아들을 수 있도록 한다고 해도 인간이 이 서버가 어떤 것인지 알리고 싶을 때 서버의 성격, 이름, 가능한 자원 등이 무엇인지도 알릴 수 있고 실제 해당 도메인의 소유자인지 확인하기 위해서 특정 문장열 (string) 을 입력해서 해당 도메인의 소유권을 확인하는 방법으로도 사용된다. 또한 메일의 보안 관련 설정인 SPF ( Sender Policy Framework) 이나 DKIM ( DomainKeys Identified Mail ) 설정에도 사용된다. 거의 대부분 설정하라는 대로 설정해주면 별 문제 없는 레코드 항목이지만 상당히 유용하게 자주 사용되는 부분이다.

SPF 설정을 위해 사용된 TXT 레코드 값들


이밖에도 다양한 레코드 형태가 존재한다. 그러나 기본적으로 이 정도만 익숙해도 자신이 원하는 목적을 이룰 수 있을 정도로 충분한 내용이다.

DNS 는 왜 중요한가

DNS 가 인터넷에 필수적인 요소라는 것은 알겠지만 왜 DNS 가 중요한지 생각해볼 필요가 있다. DNS 서비스를 웹에서 무료 (에 가깝게) 제공한다는 것이 얼마나 고마운 일인지 DNS 서버를 구성해보거나 관리해본 경험이 있다면 알 수 있다. 인터넷이란 공간이 얼마나 공개된 공간인지 아주 개인적으로 만든 서버도 조금만 보안에 소홀히 하면 몇일 안되어서 스팸 메일을 보내는 서버로 바뀌거나 특정 서버를 공격하기 위한 릴레이 서버 (relay server) 로 약용되기 쉽다. 즉, 일반적 사용자이 사용과 악의적 공격자의 공격을 구별해서 이를 적절하게 걸러내지 않으면 특정 서버는 동시에 엄청난 접속을 만들어 내서 서버의 성능 이상의 요청을 지속적으로 해서 서비스를 중지하게 만드는 디도스 (DDoS ; Distributed Denial of Services) 공격을 만들어 낼 수 있다. 즉, 어떤 서버가 한번에 1억명 동시 접속자를 받을 수 있을 때 5억명 정도의 접속을 특정 서버에 들어가게 만들 수 있다.

DNS Hijacking: 사용자에게 악의적인 DNS 정보를 사용하도록 하여 해킹에 이용될 서버에 접속하도록 유도한다.


따라서 보안이 잘 되어 있는 서버는 이를 막기 위해서 특정 IP 가 고정되지 않고 변동되면서 잘 관리해주고 여러개의 물리적인 서버들이 자원을 골고루 사용하여 분산되도록 노력한다. 만약 IP 가 고정되어 특정 IP 에 공격하게 된다면 DNS 서버를 거치지 않고 바로 IP 로 공격할 수 있다. ( yourdomain.com 의 IP 주소가 예를 들어 182.22.32.45 이라면 사용자는 yourdomain.com 을 입력하지 않고 IP 주소를 직접 넣어도 접속이 된다. 사실 조금은 더 빠를 수 있다.) 따라서 IP 로 직접 공격하는 정도는 가볍게 막을 수 있지만 그렇기 때문에 DNS 서버가 수많은 요청을 처리해야 한다. 문제는 이때 적절하게 악의적인 공격임을 파악하게 된다면 이를 거절하여 접속하지 못하게 하여 차단하고 일반적 사용자들도 불편없이 접속할 수 있도록 만들어 준다. DNS 서버도 결국 서버이다. 즉, 물리적인 컴퓨터란 말이다. 이 말은 서버에 연결된 네트워크 환경 (접속 환경, 백본망 속도 등) 뿐만 아니라 처리 성능 등에 따라서 인터넷의 실질적 (practical) 속도가 정해질 수 있다는 것이다.

인터넷 상에서 특정 사이트에 들어갈 때 걸리는 소요 시간을 보여주는 [ 서비스 ] 이다. 예를 들어 본 블로그를 들어갈 때 어떤 이미지를 내려받고 어떤 자바스크립트를 실행하며 어떤 자료들을 내려 받아서 블로그 초기 화면을 보여주는데 얼마나 시간이 걸리는지 보여준다. 이 서비스를 통해서 자신이 원하는 홈페이지에서 가장 많이 시간이 걸리는 요소가 무엇인지 알려준다. 그런데 이미지 하나를 받는 것만 해도 DNS / Connect / Send / ... / Receive 와 같이 구성되어 있는 것을 볼 수 있다. 즉, 아주 간단해 보이는 이미지 내려 받는 것만 해도 해당 이미지의 주소에 따라서 DNS 에서 해당 서버를 찾고 이에 연결 요청하고 연결해서 이미지를 내려받는 시간이 걸리는 것이다. 다만 화려한 (?) 인터넷 속도에 그 소요시간이 정말 눈깜짝할 사이도 안될 정도로 빠르다는 것일 뿐이다.

웹의 한페이지를 구성하기 위해 필요한 이미지, 스크립트 등을 내려받는 동안 걸리는 시간을 표시해준다. 분석을 통해 어떤 요소가 속도를 느리게 하는지, DNS 반응속도는 얼마나 빠른지 확인할 수 있다. 


그런데 만약 DNS 서버의 조회 후 결과 (IP 주소) 를 알려주는데 처리하는 시간이 오래 걸리는 성능이 안좋은 DNS 서버라면 이 시간은 늘어나게 된다. 이에 대한 실험은 아주 간단하게 해볼 수 있다. DNS 서비스를 변경해서 확인해보는 것이다.  따라서 DNS 서버가 얼마나 빠르게 반응하냐에 따라서 웹페이지가 표시되는 시간도 빠르게 될 수 있다. 얼마나 차이가 있을까 싶지만 개인적으로 동일한 블로그 페이지가 9초 가까이 걸리던 시간이 DNS 서비스 하나만 변경하여 5초 미만으로 지속적으로 나오는 것을 확인하게 되었다. 당연하지만 정확한 결과를 위해서 브라우저에서 이미 저장된 캐시 (cache) 내용은 지워주고 확인하는 것이 필요할 것이다.

만의 홈페이지를 만들어 보기...

홈페이지에는 블로그부터 아주 간단한 페이지로만 구성된 다양한 공간이 존재한다. 중요한 것은 인터넷 상에 내 홈페이지를 제공해줄 수 있는 (serving) 서버가 존재하고 여기에 마치 내 하드 디스크 처럼 올리거나 원하는 페이지를 구성할 수 있도록 한다는 것이다.

a. 블로그 : 워낙 많은 블로그 서비스가 있기 때문에 별로도 설명하지 않아도 어렵지 않게 구성할 수 있다. 대부분 블로그 (워드프레스는 유료) 가 자신의 도메인 주소를 지정할 수 있도록 해준다. 블로그 서비스에서 자신의 도메인 주소를 지정하고 (e.g.: myblog.meson.kr) 을 입력하고 DNS 서비스에 들어가서 블로그 서비스가 알려준 설정 방법 (A 레코드 아니면 CNAME) 에 맞춰 설정해주면 된다.

티스토리 블로그 서비스에서 2차주소를 설정하고 DNS 서비스에서 A 레코드 값을 등록해준다.


b. 웹호스팅 : 웹호스팅이란 인터넷에 자신의 저장 공간을 가진다고 생각하면 된다. 호스팅 업체에서 필요한 스크립트를 지원해주거나 간단하게 설치형 게시판, 블로그 등도 만들어 주기도 하고 다양한 서비스를 제공해주는 경우가 많다. 아주 기본적 원리이지만 돈이 많다면 유료 호스팅은 조금 더 쾌적한 환경을 제공해준다. 그러나 개인의 경우 무료도 문제없다. 대부분 무료/유료의 제한은 저장공간, 대역폭, 광고 배너 등이 추가되는지 아닌지 정도이다. 대역폭이 턱없이 부족한 무료 서비스들도 있지만 개인이 사용하기 별 문제없는 호스팅 업체를 몇군데 소개하면...

  • 000webhost.com [ 홈페이지 ]: 1.5G 저장공간 / 100G 대역폭 (월) / PHP 지원 
  • freehostia.com [ 홈페이지 ]: 250M 저장공간 / 6G 대역폭 (월) / PHP & MySQL 지원 
  • serversFree.com [ 홈페이지 ]:  10G 저장공간 / 100G 대역폭 (월) / addon Domains 무제한 
  • hostinger.kr [ 홈페이지 ]: 2.0G 저장공간 / 100G 대역폭 (월) 


간단하게 페이지를 만들 때 사용했던 웹호스팅 서비스들이다. 물론 이 밖에도 수없이 많은 업체들이 있지만 모두 소개하는 것은 어렵고 우선 삽입되는 광고가 없는 서비스들을 중심으로 소개했다.

웹호스팅은 자신의 홈페이지 뿐만 아니라 다양한 서비스를 제공해준다. 예를 들어 메일서비스도 그 중 하나이다. 만약 해당 호스팅 업체의 메일서비스를 사용하고 싶다면 해당 서비스에서 알려주는 MX 레코드를 DNS 서비스에 입력 설정하면 된다.

c. 조금은 특이한 서비스 : 드랍박스 [ dropbox ] 는 많은 인기를 얻는 클라우드 서비스이다. 기본적으로 자신의 작업 컴퓨터에도 동기화가 되어서 자신이 작업한 파일을 드랍박스의 폴더에 넣으면 자동으로 클라우드에 올라가게 된다. 또한 웹상에서 공개적으로 (public) 공유할 수 있는 기능도 있기 때문에 이를 이용해서 아주 간단한 형태의 웹페이지를 만들 수 있는 서비스가 있다.

드랍박스 서비스와 연결되는 Pancake 서비스는 작업 컴퓨터에서 편집하면 드랍박스로 바로 동기화되고 바로 웹페이지에 반영이 된다. 


Pancake.io [ 홈페이지 ]: 가입하면 자신이 사용하는 드랍박스 계정을 인증하게 된다. 그럼 드랍박스에 Apps/Pancake.io 란 폴더가 만들어진다. 클라우드 뿐만 아니라 동기화 설정한 컴퓨터에도 만들어진다. 그럼 해당 프로젝트 폴더에 웹페이지 구성 파일을 넣으면 된다. 이후 설정 (settings) 에서 자신의 URL 을 입력하고 이를 DNS 서비스의 CNAME 으로 반영하면 자신이 설정한 주소로 아주 간단한 홈페이지를 만들 수 있다.

이와 비슷한 형태로 [ DropPages ] , [ Scriptogr.am ] 등 다양하게 있다.

d. 직접 서버를 운영하기: 직접 서버를 운영하는 것도 나쁘지 않다. 보안 및 관리에 자신이 있거나 시스템 관리자를 꿈꾸는 사람이라면 꼭 해볼 필요가 있을 것이다. 최근에 나온 리눅스 및 서버 계열은 대부분 보안에도 일반적인 내용에 대해서 잘 되어 있기 때문에 겁먹을 필요는 없을 것 같다. [ 오래된 컴퓨터 활용기 ] 을 통해서 구형 컴퓨터에 리눅스 서버 배포판을 설치하는 방법을 소개했으니 참조하면 좋을 것 같다. 다만 DNS 관련해서 한가지 사소한 문제점은 집이나 개인 인터넷의 경우 공유기가 고정된 IP 를 받지 못한다는 점이 있다. 이를 해결하기 위해 많은 DNS 서비스가 유동 IP (Dynamic IP) 란 기능을 제공하고 있다 이 부분은 바로 이어 소개한다.

DNS 서비스의 추가적 기능에 대해서...

DNS 서비스의 기본적인 기능 뿐만 아니라 부가적인 기능들이 존재한다. 많은 기능들이 서비스 업체에 따라서 다르지만 기본적으로 사용하면 편리한 두가지 기능은 1. 웹포워딩 기능과 2. 유동 IP (Dynamic IP) 이다.

1. 웹포워딩 기능 : 말 그대로 원하는 주소를 입력하면 원하는 주소로 이동시켜주는 것이다. 예를 들어 너무 길거나 클라우드 서비스의 공유 주소가 지나치게 복잡하거나 도저히 암기할 수 없을 때 이용하면 편리하다. 예를 들어 자신의 드랍박스 공개 공유 주소 (public link) 를 보면

https://www.dropbox.com/sh/r8ou6rbmd6x3kje/AADVUg-tqOnF8yhLUhhAjKGEa

과 같이 기억하기 불가능하다. 이 경우 해당 주소를 dropbox.meson.kr 이란 주소를 위의 주소로 지정을 하면 위의 주소를 입력할 필요없이 간단히 기억하기 편한 dropbox.meson.kr 으로 들어갈 수 있다.

DNS 서비스에 따라서 유료로 제공하거나 혹은 갯수에 제한을 두는 경우가 있다. 100개로 제한두지만 100개를 다 쓴다는 것은 특별한 상황이 아니라면 충분한 갯수이다. CloudFlare 의 경우 무료는 3개로 제한을 두는데 웹포워딩에서 와일드카드 (*) 를 지원한다. 개인적으로 부딪친 문제 중 하나는 Google Apps 설정에서 mail.mydomain.com 은 실제로 mail.google.com/a/mydomain.com 으로 이동된다. 구글 앱스에서 이를 위해서 대표 도메인 (가입할 때 입력한 최초 도메인) 의 경우에는 CNAME 으로 깔끔하게 처리해주지만 추가로 입력한 도메인이 2nddomain.net 이라면 mail.2nddomain.net 은 지원해주지 않는다. 이런 경우 웹포워딩으로 해결할 수 있다. mail.2dndomain.net 을 mail.google.com/a/2nddomain.net 으로 웹포워딩하면 되기 때문이다. 그런데 구글앱스의 경우 mail 뿐만 아니라 drive, sites, calendar 등이 존재한다. 이 모든 서비스들을 각각 포워딩해줄려면 이 경우 4개의 포워딩이 필요하다. 그러나 CloudFlare 는 3개만 지원한다. 이 경우 와일드카드를 이용해 해결할 수 있었다. 포워딩은 Page Rules 에서 설정하는데 여기에서 포워딩을 설정하고,

웹포워딩 규칙을 통해서 규칙성을 가지는 URL 에 대한 포워딩을 한번에 설정할 수 있다. - CloudFlare


*.2nddomain.net/  을  https://$1.google.com/a/2nddomain.net 으로 포워딩해주는 규칙을 만든다. 이 뜻은 * 에 해당하는 문자열을 그대로 $1 에 반영해서 포워딩하란 뜻이다. 결과적으로

mail.2nddomain.net → https://mail.google.com/a/2nddomain.net ,
calendar.2nddomain.net → https://calendar.google.com/a/2nddomain.net ,
drive.2nddomain.net → https://drive.google.com/a/2nddomain.net , 
sites.2nddomain.net → https://sites.google.com/a/2nddomain.net , 

으로 한꺼번에 웹포워딩을 설정할 수 있다. (CloudFlare 와 Google Apps 사용시 유용한 팁)

2. 유동 IP (Dynamic IP): 개인이 구축한 서버의 경우, 혹은 어떤 이유에서 IP 가 변경되는 서버의 경우 서버의 IP 가 변경되면 DNS 에서 알려준 IP 주소가 옛날 주소가 되어서 접근할 수 없게 된다. 이 경우 서버에서 DNS 서비스에 자신의 현재 IP 가 무엇이다 알려주어서 이를 업데이트 하여 IP 가 변경되어도 사용할 수 있도록 도와주는 서비스이다. 기본적으로 많은 서비스의 경우 어떻게 설정하는지 친절하게 설명을 해 놓았다.

DNSEver , DNSZi (도메인의 고급관리) 의 경우에는 사용 운영체제에 따라서 필요한 내용을 잘 정리해 주었다. CloudFlare 의 경우 조금 복잡할 수 있지만 제공되는클라이언트 API 를 통해서 기본 A 레코드를 업데이트하는 방식으로 해결할 수 있다. [ 참고: Dynamically update DNS with CloudFlare Client API ; in case link is broken 

간단한 요약하면 해당 DNS 의 고유 record id 를 찾아내서 이 정보와 API Key 와 자신의 IP 주소를 업데이트 하는 명령어를 만들고 이를 주기적으로 업데이트 해주는 것이다.

무리하며...

블로그를 새롭게 단장하면서 가장 느끼게 된 것은 너무도 기본적이기 때문에 그 중요함을 생각하지 못하는 기본적인 요소가 많다는 점이다. 그 중 가장 첫번째가 바로 DNS 서비스가 아닐까 싶다. 공기같이 당연한 서비스들이라 그 안에서 최적화를 생각할 필요가 없다는 고정관념에서 DNS 하나만으로도 서비스의 속도가 빨라질 수 있는 충분한 가능성이 존재한다는 것을 느끼게 된다.


DNS 서비스와 같이 기간 서비스를 제공하는 것은 이제 더이상 수익이 나지 않을 것이라는 어떤 소프트웨어 전문가의 글을 본적이 있었다. DNS 와 같이 너무도 오랜동안 서비스되어서 장단점 및 다양한 환경, 상황에서의 문제점들에 대한 오랜 정보들이 축적되어 더이상 발전될 가능성이 없다고 했을 때마다 뭔가 새로운 도약같은 변화가 일어나는 것이 기술의 도약이라는 생각이 든다. 개인적으로 CloudFlare 에 다니는 지인이 계신데 자신의 역할을 '인터넷의 낭비되는 자원을 절약하는 코디네이터' - Coordinator who lessen wasted resources throughout the internet' 이라 소개한 적이 있었다. 이미 존재하는 기술들을 적절하게 모을 수 있는 창의적 아이디어 몇개로 사용자들이 바로 느낄 수 있는 서비스의 변화를 만들어 낼 수 있다는 점을 주목할 필요가 있다.

CloudFlare 를 통해 향상된 수치를 분석 (Analytics) 화면에서 보여준다. 


CloudFlare 의 경우가 그런 예가 될 것 같다. DNS 반응 속도를 높이기 위해서 여러 위치에 놓인 서버를 두고 가장 빠르게 반응할 수 있는 방법을 제시한다. 또한 DNS 서버 자체가 요청한 웹페이지의 이미지 등 내려받아야 할 요소들을 미리 저장 (caching) 해서 목적지 서버에 요청하지 않고 바로 DNS 에서 처리해준다. 아주 사소해 보이지만 자바스크립트 (javascript) 와 같이 공백이나 탭을 줄여 파일 자체의 용량을 줄인 _min.js 방법을 자동으로 적용하고 있다. 

항상 기본을 다루는 내용은 글이 길어지고 어느 범위까지 다루어야 할지 고민될 때가 많지만 앞으로 개인도메인을 이용한 개인 메일 주소 / 구글앱스 서비스 등과 같은 개인화 웹서비스 및 다양한 응용에 활용될 수 있는 부분이기에 우선 글을 올리게 되었다. 광범위하게 좀 더 많은 사람들이 DNS 의 개념을 쉽게 이해하고 활용하기를 바라며 글을 마무리한다.


출처 : http://june.meson.kr/2014/10/dns-service-its-basic-and-application.html

Posted by 당구치는 개발자
|
프로그래밍/It 용어 2016. 9. 23. 10:30

도메인이란?

도메인은 인터넷에 연결된 컴퓨터를 사람이 쉽게 기억하고 입력할 수 있도록 문자(영문, 한글 등)로 만든 인터넷주소입니다.

법률상으로는 인터넷주소자원에 관한 법률 제2조에 따라 도메인은 인터넷에서 인터넷 프로토콜 주소를 사람이 기억하기 쉽도록 하기 위하여 만들어진 것 입니다.

도메인 체계

도메인은 “.”또는 루트(root)라 불리는 도메인 이하에 아래 그림과 같이 역트리(Inverted tree)구조로 구성되어 있습니다.
루트 도메인 바로 아래의 단계를 1단계 도메인 또는 최상위 도메인(TLD, Top Level Domain)이라고 부르며, 그 다음 단계를 2단계 도메인(SLD, Second Level Domain)이라고 부릅니다

도메인 종류

도메인에는 국가도메인(ccTLD, country code Top Level Domain)과 일반도메인(gTLD, generic Top Level Domain)이 있습니다.

국가도메인은 인터넷 상에서 국가를 나타내는 도메인으로 ‘.kr(대한민국) .jp(일본), .cn(중국), .us(미국) 등 영문으로 구성된 영문 국가도메인이 있습니다. 또한 ‘.한국(대한민국)’, ‘중국(중국), .러시아(러시아), .이집트(이집트)처럼 자국어 국가도메인이 있습니다.

일반도메인은 ‘.com(회사)’, ‘.net(네트워크 관련기관)’, ‘org(비영리기관)’, ‘.biz(사업)’ 등 등록인의 특성에 따라 사용할 수 있는 도메인입니다.


문서 : http://www.kisa.or.kr/uploadfile/201310/201310071959231513.pdf

출처 : http://krnic.or.kr/jsp/resources/domainInfo/domainInfo.jsp

Posted by 당구치는 개발자
|
프로그래밍/DB 2016. 9. 23. 10:26


[Tip] INNER JOIN & OUTER JOIN의 차이

* 출처 : http://isstory83.tistory.com/57


INNER JOIN : simple join이라고도 하며, 둘 이상의 테이블에서 join     condition을 만족하는 행만 반환한다.


즉, 둘 이상의 테이블에 전부 존재하는 데이터만 조회한다는 것이다. (물론 ON조건에 만족하는 데이터)

집합으로 표현하자면 교집합이라 이해하면 된다.

간단한 예는 http://isstory83.tistory.com/entry/조인Join-쿼리


OUTER JOIN : OUTER JOIN 에는 LEFT , RIGHT, FULL OUTER JOIN 등의 세가지 형식이 있다.

INNER JOIN과 는 달리 두 테이블에서 지정된 쪽의 (LEFT or RIGHT) 모든 결과를 모두 보여준 후 반대쪽에 매칭되는 값을 보여주고, 값이 없어도 NULL로 보여주는 JOIN이다.

JOIN 이전에 나오는 테이블이 왼쪽(LEFT)테이블이 되고, JOIN 이후에 나오는 테이블은 오른쪽(RIGHT)테이블이 된다.


OUTER JOIN의 종류 및 사용


LEFT OUTER JOIN – A라는 테이블과 B라는 테이블이 있다면 그 두 테이블 중 왼쪽 테이블을 기준을 세우는 JOIN


SELECT t1.컬럼1, t1.컬럼2, t2.컬럼4, t2.컬럼5  FROM 테이블1 t1 LEFT JOIN 테이블2 t2 ON (t1.컬럼1 = t2.컬럼6)


왼쪽 TABLE1을 기준으로 컬럼1과 컬럼6를 매칭하여 결과 값을 보여주되 컬럼6에 3이 매칭되는 값이 없기에 NULL을 보여준다.


RIGHT OUTER JOIN – A라는 테이블과 B라는 테이블이 있다면 그 두 테이블 중 오른쪽 테이블을 기준을 세우는 JOIN


SELECT t1.컬럼1, t1.컬럼2, t2.컬럼4, t2.컬럼5 FROM 테이블1 t1 RIGHT JOIN 테이블2 t2 ON (t1.컬럼1 = t2.컬럼6)


테이블2의 컬럼6의 값 4에 해당하는 컬럼1이 없으므로 해당 데이터를 NULL로 보여준다.


FULL OUTER JOIN – 간단하게 LEFT와 RIGHT OUTER JOIN의 합이라고 생각하면 된다.


SELECT t1.컬럼1, t1.컬럼2, t2.컬럼4, t2.컬럼5 FROM 테이블1 t1 FULL OUTER JOIN 테이블2 t2 ON (t1.컬럼1 = t2.컬럼6)


참고적으로, 같은 두 개의 테이블을 INNER JOIN하면 아래와 같은 결과를 보여준다.


SELECT t1.컬럼1, t1.컬럼2, t2.컬럼4, t2.컬럼5 FROM 테이블1 t1 INNER JOIN 테이블2 t2 ON (t1.컬럼1 = t2.컬럼6)


위의 FULL OUTER JOIN에서 양쪽에 NULL이 들어간 데이터들이 사라진 것을 확인 할 수 있다.



'프로그래밍 > DB' 카테고리의 다른 글

SQL의 JOIN에서 ON과 WHERE의 차이점  (0) 2016.09.23
절차형 SQL  (0) 2016.09.23
풀스캔을 방지  (0) 2016.09.23
Posted by 당구치는 개발자
|
프로그래밍/DB 2016. 9. 23. 10:25


SQL의 JOIN에서 ON과 WHERE의 차이점은 JOIN하는 범위가 다르다.
아래 두 SQL문을 보자. 두 SQL문 모두 LEFT JOIN을 수행하는 OUTER JOIN이다.

1)
SELECT *
FROM test1 a LEFT JOIN test2 b
ON (a.aa = b.aa)
WHERE b.cc = 7;

2)
SELECT *
FROM test1 a LEFT JOIN test2 b
ON (a.aa = b.aa AND b.cc = 7);


1)의 경우는 a와 b 테이블의 OUTER JOIN을 수행한 후에 b.cc = 7인 데이터들을 추출하지만
2)의 경우는 (a 테이블)과 (b 테이블 중 b.cc = 7인 경우)를 OUTER JOIN 한 결과가 나온다.

따라서 1)의 결과는 b.dd = 7인 데이터만 존재하지만
2)의 결과는 b.cc = 7이 아닌 데이터도 존재한다.
아래와 같은 test1, test2 테이블이 있을 때,

test1     test2
aa|bb      aa|cc
-----     -----
1 | 4        1 | 7
2 | 5       2 | 8
3 | 6


그 SQL의 결과는 다음과 같다.

1)
1|4|1|7

2)
1|4|1|7
2|5|null|null
3|6|null|null



한마디로 ON과 WHERE의 경우는 JOIN을 할 대상(범위)이 달라진다는 것이다.


여기서 OUTER JOIN을 가지고 차집합을 구현할 수 있다. 오라클이나 MSSQL과 같은 경우는 EXCEPT 혹은 MINUS 등을 사용하면 되겠지만 MySQL은 버전에 따라 지원하는 경우도 있고, 아닌 경우도 있다. Document 페이지에서 찾아보려 했으나 오늘따라 접속이 안된다. -ㅅ-;;

test1 테이블의 데이터 중 test2 테이블에 있는 데이터를 제외하고 가져오고 싶다. test2.aa에 있는 데이터가 test1.aa에 없는 데이터를 test1 테이블에서 가져온다는 것이다. 말이 어려운가 -ㅅ-a 한마디로 test1에서 3|6을 가지고 오고 싶은 것이다. 일단 SQL문을 보자 -ㅅ-;;;

SELECT *
FROM test1 a LEFT JOIN test2 b
ON (a.aa = b.aa)
WHERE b.aa IS NULL;


3|6|null|null


test2.aa에 있는 1, 2의 데이터를 제외한 데이터를 test1.aa에서 가져왔다. SQL문의 * 부분은 알아서 잘 세팅하여 사용하면 될 것이다. LEFT OUTER JOIN이기 때문에 WHERE절 이전까지 실행했을 때 아래와 같은 결과가 나온다.

1|4|1|7
2|5|2|8
3|6|null|null


여기에서 test2 테이블에 존재하지 않아서 test2 테이블의 column이 null인 부분만을 가지고 오게 WHERE절을 달아주면!! 차집합이 된다는 것이다.


출처 : http://egloos.zum.com/entireboy/v/2996500

'프로그래밍 > DB' 카테고리의 다른 글

INNER JOIN & OUTER JOIN의 차이  (0) 2016.09.23
절차형 SQL  (0) 2016.09.23
풀스캔을 방지  (0) 2016.09.23
Posted by 당구치는 개발자
|
프로그래밍/DB 2016. 9. 23. 10:25

1. 절차형 SQL 개요

일반적인 개발 언어처럼 SQL에도 절차 지향적인 프로그램이 가능하도록 DBMS 벤더별로 PL(Procedural Language)/SQL(Oracle), SQL/PL(DB2), T-SQL(SQL Server) 등의 절차형 SQL을 제공하고 있다. 절차형 SQL을 이용하면 SQL문의 연속적인 실행이나 조건에 따른 분기처리를 이용하여 특정 기능을 수행하는 저장 모듈을 생성할 수 있다. 본 절에서는 절차형 SQL을 이용하여 만들 수 있는 저장 모듈인 Procedure, User Defined Function, Trigger에 대해서 간단하게 살펴본다. (상세한 내역은 각 DBMS 벤더의 매뉴얼을 참조한다.)

2. PL/SQL 개요

가. PL/SQL 특징

Oracle의 PL/SQL은 Block 구조로 되어있고 Block 내에는 DML 문장과 QUERY 문장, 그리고 절차형 언어(IF, LOOP) 등을 사용할 수 있으며, 절차적 프로그래밍을 가능하게 하는 트랜잭션 언어이다. 이런 PL/SQL을 이용하여 다양한 저장 모듈(Stored Module)을 개발할 수 있다. 저장 모듈이란 PL/SQL 문장을 데이터베이스 서버에 저장하여 사용자와 애플리케이션 사이에서 공유할 수 있도록 만든 일종의 SQL 컴포넌트 프로그램이며, 독립적으로 실행되거나 다른 프로그램으로부터 실행될 수 있는 완전한 실행 프로그램이다. Oracle의 저장 모듈에는 Procedure, User Defined Function, Trigger가 있다.

PL/SQL의 특징은 다음과 같다.

- PL/SQL은 Block 구조로 되어있어 각 기능별로 모듈화가 가능하다. - 변수, 상수 등을 선언하여 SQL 문장 간 값을 교환한다. - IF, LOOP 등의 절차형 언어를 사용하여 절차적인 프로그램이 가능하도록 한다. - DBMS 정의 에러나 사용자 정의 에러를 정의하여 사용할 수 있다. - PL/SQL은 Oracle에 내장되어 있으므로 Oracle과 PL/SQL을 지원하는 어떤 서버로도 프로그램을 옮길 수 있다. - PL/SQL은 응용 프로그램의 성능을 향상시킨다. - PL/SQL은 여러 SQL 문장을 Block으로 묶고 한 번에 Block 전부를 서버로 보내기 때문에 통신량을 줄일 수 있다.

[그림 Ⅱ-2-18]은 PL/SQL Architecture이다. PL/SQL Block 프로그램을 입력받으면 SQL 문장과 프로그램 문장을 구분하여 처리한다. 즉 프로그램 문장은 PL/SQL 엔진이 처리하고 SQL 문장은 Oracle 서버의 SQL Statement Executor가 실행하도록 작업을 분리하여 처리한다.

나. PL/SQL 구조

다음은 PL/SQL의 블록 구조를 표현한 내용이다.

- DECLARE : BEGIN ~ END 절에서 사용될 변수와 인수에 대한 정의 및 데이터 타입을 선언하는 선언부이다. - BEGIN ~ END : 개발자가 처리하고자 하는 SQL문과 여러 가지 비교문, 제어문을 이용하여 필요한 로직을 처리하는 실행부이다. - EXCEPTION : BEGIN ~ END 절에서 실행되는 SQL문이 실행될 때 에러가 발생하면 그 에러를 어떻게 처리할 것이지를 정의하는 예외 처리부이다.

다. PL/SQL 기본 문법(Syntax)

앞으로 살펴볼 User Defined Function이나 Trigger의 생성 방법이나 사용 목적은 다르지만 기본적인 문법은 비슷하기 때문에 여기에서는 Stored Procedure를 통해서 PL/SQL에 대한 기본적인 문법을 정리한다.

CREATE [OR REPLACE] Procedure [Procedure_name] ( argument1 [mode] data_type1, argument2 [mode] date_type2, ... ... ) IS [AS] ... ... BEGIN ... ... EXCEPTION ... ... END; /

다음은 생성된 프로시저를 삭제하는 명령어이다.

DROP Procedure [Procedure_name];

CREATE TABLE 명령어로 테이블을 생성하듯 CREATE 명령어로 데이터베이스 내에 프로시저를 생성할 수 있다. 이렇게 생성한 프로시저는 데이터베이스 내에 저장된다. 프로시저는 개발자가 자주 실행해야 하는 로직을 절차적인 언어를 이용하여 작성한 프로그램 모듈이기 때문에 필요할 때 호출하여 실행할 수 있다. [OR REPLACE] 절은 데이터베이스 내에 같은 이름의 프로시저가 있을 경우, 기존의 프로시저를 무시하고 새로운 내용으로 덮어쓰기 하겠다는 의미이다. Argument는 프로시저가 호출될 때 프로시저 안으로 어떤 값이 들어오거나 혹은 프로시저에서 처리한 결과값을 운영 체제로 리턴시킬 매개 변수를 지정할 때 사용한다. [mode] 부분에 지정할 수 있는 매개 변수의 유형은 3가지가 있다. 먼저 IN은 운영 체제에서 프로시저로 전달될 변수의 MODE이고, OUT은 프로시저에서 처리된 결과가 운영체제로 전달되는 MODE이다. 마지막으로 잘 쓰지는 않지만 INOUT MODE가 있는데 이 MODE는 IN과 OUT 두 가지의 기능을 동시에 수행하는 MODE이다. 마지막에 있는 슬래쉬(“/”)는 데이터베이스에게 프로시저를 컴파일하라는 명령어이다. 앞에서 잠깐 언급했지만 PL/SQL과 관련된 내용은 상당히 다양하고 분량이 많기 때문에 본 가이드에서는 간단한 문법과 사용 목적에 초점을 맞춰 이해하기 바란다.

3. T-SQL 개요

가. T-SQL 특징

T-SQL은 근본적으로 SQL Server를 제어하기 위한 언어로서, T-SQL은 엄격히 말하면, MS사에서 ANSI/ISO 표준의 SQL에 약간의 기능을 더 추가해 보완적으로 만든 것이다. T-SQL을 이용하여 다양한 저장 모듈(Stored Module)을 개발할 수 있는데, T-SQL의 프로그래밍 기능은 아래와 같다.

- 변수 선언 기능 @@이라는 전역변수(시스템 함수)와 @이라는 지역변수가 있다. - 지역변수는 사용자가 자신의 연결 시간 동안만 사용하기 위해 만들어지는 변수이며 전역변수는 이미 SQL서버에 내장된 값이다. - 데이터 유형(Data Type)을 제공한다. 즉 int, float, varchar 등의 자료형을 의미한다. - 연산자(Operator) 산술연산자( +, -, *, /)와 비교연산자(=, <, >, <>) 논리연산자(and, or, not) 사용이 가능하다. - 흐름 제어 기능 IF-ELSE와 WHILE, CASE-THEN 사용이 가능하다. - 주석 기능한줄 주석 : -- 뒤의 내용은 주석범위 주석 : /* 내용 */ 형태를 사용하며, 여러 줄도 가능함

T-SQL과 타 DBMS가 제공하는 SQL은 약간만 다를 뿐 그 맥락은 같이 하기 때문에, 조금의 변경 사항만 적용하면 같은 기능을 수행할 수 있다. 그리고 많은 사람들이 SQL 서버에 엔터프라이즈 매니저의 UI를 통하여 접근하는 경우가 많은데, 실??이 더 바람직하다.

나. T-SQL 구조

다음은 T-SQL의 구조를 표현한 내용이다. PL/SQL과 유사하다.

- DECLARE : BEGIN ~ END 절에서 사용될 변수와 인수에 대한 정의 및 데이터 타입을 선언하는 선언부이다. - BEGIN ~ END : 개발자가 처리하고자 하는 SQL문과 여러 가지 비교문, 제어문을 이용하여 필요한 로직을 처리하는 실행부이다. T-SQL에서는 BEGIN, END 문을 반드시 사용해야하는 것은 아니지만 블록 단위로 처리하고자 할 때는 반드시 작성해야 한다. - ERROR 처리 : BEGIN ~ END 절에서 실행되는 SQL문이 실행될 때 에러가 발생하면 그 에러를 어떻게 처리할 것이지를 정의하는 예외 처리부이다.

다. T-SQL 기본 문법(Syntax)

앞으로 살펴볼 User Defined Function이나 Trigger의 생성 방법과 사용 목적은 Stored Procedure와 다르지만 기본적인 문법은 비슷하기 때문에 여기에서는 Stored Procedure를 통해서 T-SQL에 대한 기본적인 문법을 정리한다.

CREATE Procedure [schema_name.]Procedure_name @parameter1 data_type1 [mode], @parameter2 date_type2 [mode], ... ... WITH AS ... ... BEGIN ... ... ERROR 처리 ... ... END;

다음은 생성된 프로시저를 삭제하는 명령어이다.

DROP Procedure [schema_name.]Procedure_name;

CREATE TABLE 명령어로 테이블을 생성하듯 CREATE 명령어로 데이터베이스 내에 프로시저를 생성할 수 있다. 이렇게 생성한 프로시저는 데이터베이스 내에 저장된다. 프로시저는 개발자가 자주 실행해야 하는 로직을 절차적인 언어를 이용하여 작성한 프로그램 모듈이기 때문에 필요할 때 호출하여 실행할 수 있다. 프로시저의 변경이 필요할 경우 Oracle은 [CREATE OR REPLACE]와 같이 하나의 구문으로 처리하지만 SQL Server는 CREATE 구문을 ALTER 구문으로 변경하여야 한다. @parameter는 프로시저가 호출될 때 프로시저 안으로 어떤 값이 들어오거나 혹은 프로시저에서 처리한 결과 값을 리턴 시킬 매개 변수를 지정할 때 사용한다. [mode] 부분에 지정할 수 있는 매개 변수(@parameter)의 유형은 4가지가 있다.

① VARYING결과 집합이 출력 매개 변수로 사용되도록 지정합니다. CURSOR 매개변수에만 적용된다. ② DEFAULT지정된 매개변수가 프로시저를 호출할 당시 지정되지 않을 경우 지정된 기본값으로 처리한다. 즉, 기본 값이 지정되어 있으면 해당 매개 변수를 지정하지 않아도 프로시저가 지정된 기본 값으로 정상적으로 수행이 된다. ③ OUT, OUTPUT프로시저에서 처리된 결과 값을 EXECUTE 문 호출 시 반환한다. ④ READONLY자주 사용되지는 않는다. 프로시저 본문 내에서 매개 변수를 업데이트하거나 수정할 수 없음을 나타낸다. 매개 변수 유형이 사용자 정의 테이블 형식인 경우 READONLY를 지정해야 한다.

WITH 부분에 지정할 수 있는 옵션은 3가지가 있다.

① RECOMPILE데이터베이스 엔진에서 현재 프로시저의 계획을 캐시하지 않고 프로시저가 런타임에 컴파일 된다. 데이터베이스 엔진에서 저장 프로시저 안에 있는 개별 쿼리에 대한 계획을 삭제하려 할 때 RECOMPILE 쿼리 힌트를 사용한다. ② ENCRYPTIONCREATE PROCEDURE 문의 원본 텍스트가 알아보기 어려운 형식으로 변환된다. 변조된 출력은 SQL Server의 카탈로그 뷰 어디에서도 직접 표시되지 않는다. 원본을 볼 수 있는 방법이 없기 때문에 반드시 원본은 백업을 해두어야 한다. ③ EXECUTE AS 해당 저장 프로시저를 실행할 보안 컨텍스트를 지정한다.

앞에서 잠깐 언급했지만 T-SQL과 관련된 내용은 상당히 다양하고 분량이 많기 때문에 본 가이드에서는 간단한 문법과 사용 목적에 초점을 맞춰 이해하기 바란다.

4. Procedure의 생성과 활용

[그림 Ⅱ-2-21]은 앞으로 생성할 Procedure의 기능을 Flow Chart로 나타낸 그림이다.

[예제] SCOTT 유저가 소유하고 있는 DEPT 테이블에 새로운 부서를 등록하는 Procedure를 작성한다. SCOTT 유저가 기본적으로 소유한 DEPT 테이블의 구조는 [표 Ⅱ-2-14]와 같다.

[예제] Oracle CREATE OR REPLACE Procedure p_DEPT_insert -------------① ( v_DEPTNO in number, v_dname in varchar2, v_loc in varchar2, v_result out varchar2) IS cnt number := 0; BEGIN SELECT COUNT(*) INTO CNT -------------② FROM DEPT WHERE DEPTNO = v_DEPTNO AND ROWNUM = 1; if cnt > 0 then -------------③ v_result := '이미 등록된 부서번호이다'; else INSERT INTO DEPT (DEPTNO, DNAME, LOC) -------------④ VALUES (v_DEPTNO, v_dname, v_loc); COMMIT; -------------⑤ v_result := '입력 완료!!'; end if; EXCEPTION -------------⑥ WHEN OTHERS THEN ROLLBACK; v_result := 'ERROR 발생'; END; /

[예제] SQL Server CREATE Procedure dbo.p_DEPT_insert -------------① @v_DEPTNO int, @v_dname varchar(30), @v_loc varchar(30), @v_result varchar(100) OUTPUT AS DECLARE @cnt int SET @cnt = 0 BEGIN SELECT @cnt=COUNT(*) -------------② FROM DEPT WHERE DEPTNO = @v_DEPTNO IF @cnt > 0 -------------③ BEGIN SET @v_result = '이미 등록된 부서번호이다' RETURN END ELSE BEGIN BEGIN TRAN INSERT INTO DEPT (DEPTNO, DNAME, LOC) -------------④ VALUES (@v_DEPTNO, @v_dname, @v_loc) IF @@ERROR<>0 BEGIN ROLLBACK -------------⑥ SET @v_result = 'ERROR 발생' RETURN END ELSE BEGIN COMMIT -------------⑤ SET @v_result = '입력 완료!!' RETURN END END END

DEPT 테이블은 DEPTNO 칼럼이 PRIMARY KEY로 설정되어 있으므로, DEPTNO 칼럼에는 유일한 값을 넣어야만 한다. [예제]에 대한 설명은 다음과 같다.

① DEPT 테이블에 들어갈 칼럼 값(부서코드, 부서명, 위치)을 입력 받는다. ② 입력 받은 부서코드가 존재하는지 확인한다. ③ 부서코드가 존재하면 '이미 등록된 부서번호입니다'라는 메시지를 출력 값에 넣는다. ④ 부서코드가 존재하지 않으면 입력받은 필드 값으로 새로운 부서 레코드를 입력한다. ⑤ 새로운 부서가 정상적으로 입력됐을 경우에는 COMMIT 명령어를 통해서 트랜잭션을 종료한다. ⑥ 에러가 발생하면 모든 트랜잭션을 취소하고 'ERROR 발생'라는 메시지를 출력값에 넣는다.

앞에 있는 프로시저를 작성하면서 주의해야 할 몇 가지 문법적 요소가 있다. 첫째, PL/SQL 및 T-SQL에서는 다양한 변수가 있다. 예제에서 나온 cnt라는 변수를 SCALAR 변수라고 한다. SCALAR 변수는 사용자의 임시 데이터를 하나만 저장할 수 있는 변수이며 거의 모든 형태의 데이터 유형을 지정할 수 있다. 둘째, PL/SQL에서 사용하는 SQL 구문은 대부분 지금까지 살펴본 것과 동일하게 사용할 수 있지만 SELECT 문장은 다르다. PL/SQL에서 사용하는 SELECT 문장은 결과값이 반드시 있어야 하며, 그 결과 역시 반드시 하나여야 한다. 조회 결과가 없거나 하나 이상인 경우에는 에러를 발생시킨다. T-SQL에서는 결과 값이 없어도 에러가 발생하지 않는다. 셋째, T-SQL을 비롯하여 일반적으로 대입 연산자는 “=”을 사용하지만 PL/SQL에서는 “:=”를 사용한다. 넷째, 에러 처리를 담당하는 EXCEPTION에는 WHEN ~ THEN 절을 사용하여 에러의 종류별로 적절히 처리한다. OTHERS를 이용하여 모든 에러를 처리할 수 있지만 정확하게 에러를 처리하는 것이 좋다. T-SQL에서는 에러 처리를 다양하게 처리할 수 있으며 위의 예제는 그 한 예이다. 다음은 지금까지 작성한 프로시저를 실행하여 기능을 테스트한 과정이다.

[실행 결과] Oracle SQL> SELECT * FROM DEPT; -----------------① DEPTNO DNAME LOC ------- ------- --------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON SQL> variable rslt varchar2(30); -----------------② SQL> EXECUTE p_DEPT_insert(10,'dev','seoul',:rslt); -----------------③ PL/SQL 처리가 정상적으로 완료되었다. SQL> print rslt; -----------------④ RSLT -------------------------------- 이미 등록된 부서번호이다 SQL> EXECUTE p_DEPT_insert(50,'NewDev','seoul',:rslt); ----------------⑤ PL/SQL 처리가 정상적으로 완료되었다. SQL> print rslt; ----------------⑥ RSLT -------------------------------- 입력 완료!! SQL> SELECT * FROM DEPT; ----------------⑦ DEPTNO DNAME LOC ------ -------- --------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON 50 NewDev SEOUL 5개의 행이 선택되었다.

① DEPT 테이블을 조회하면 총 4개 행의 결과가 출력된다. ② Procedure를 실행한 결과 값을 받을 변수를 선언한다. (BIND 변수) ③ 존재하는 DEPTNO(10)를 가지고 Procedure를 실행한다. ④ DEPTNO가 10인 부서는 이미 존재하기 때문에 변수 rslt를 print해 보면 '이미 등록된 부서번호이다' 라고 출력된다. ⑤ 이번에는 새로운 DEPTNO(50)를 가지고 입력한다. ⑥ rslt를 출력해 보면 '입력 완료!!' 라고 출력된다. ⑦ DEPT 테이블을 조회하여 보면 DEPTNO가 50인 데이터가 정확하게 저장되었음을 확인할 수 있다.

T-SQL로 작성한 프로시저를 실행하기 위해서는 일반적으로 SQL Server에서 제공하는 기본 클라이언트 프로그램인 SQL Server MANAGEMENT STUDIO를 사용한다.

[실행 결과] SQL Server SELECT * FROM DEPT; -----------------① DEPTNO DNAME LOC ------- ---------- --------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON DECALRE @v_result VARCHAR(100) -----------------② EXECUTE dbo.p_DEPT_insert 10, 'dev', 'seoul', @v_result=@v_result OUTPUT -----------------③ SELECT @v_result AS RSLT -----------------④ RSLT -------------------------------- 이미 등록된 부서번호이다 DECALRE @v_result VARCHAR(100) -----------------⑤ EXECUTE dbo.p_DEPT_insert 50, 'dev', 'seoul', @v_result=@v_result OUTPUT -----------------⑥ SELECT @v_result AS RSLT -----------------⑦ RSLT -------------------------------- 입력 완료! SELECT * FROM DEPT; ----------------⑧ DEPTNO DNAME LOC ------- -------- --------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON 50 NewDev SEOUL 5개의 행에서 선택되었다.

① DEPT 테이블을 조회하면 총 4개 행의 결과가 출력된다. ② Procedure를 실행한 결과 값을 받을 변수를 선언한다. ③ 존재하는 DEPTNO(10)를 가지고 Procedure를 실행한다. ④ DEPTNO가 10인 부서는 이미 존재하기 때문에 변수 rslt를 print해 보면 ‘이미 등록된 부서번호이다’라고 출력된다. ⑤ Procedure를 실행한 결과 값을 받을 변수를 선언한다. ⑥ 이번에는 새로운 DEPTNO(50)를 가지고 입력한다. ⑦ rslt를 출력해 보면 ‘입력 완료!’라고 출력된다. ⑧ DEPT 테이블을 조회하여 보면 DEPTNO가 50인 데이터가 정확하게 저장되었음을 확인할 수 있다.

5. User Defined Function의 생성과 활용

User Defined Function은 Procedure처럼 절차형 SQL을 로직과 함께 데이터베이스 내에 저장해 놓은 명령문의 집합을 의미한다. 앞에서 학습한 SUM, SUBSTR, NVL 등의 함수는 벤더에서 미리 만들어둔 내장 함수이고, 사용자가 별도의 함수를 만들 수도 있다. Function이 Procedure와 다른 점은 RETURN을 사용해서 하나의 값을 반드시 되돌려 줘야 한다는 것이다. 즉 Function은 Procedure와는 달리 SQL 문장에서 특정 작업을

[예제] K-리그 8월 경기결과와 두 팀간의 점수차를 ABS 함수를 사용하여 절대값으로 출력한다.

[예제] Oracle SELECT SCHE_DATE 경기일자, HOMETEAM_ID || ' - ' || AWAYTEAM_ID 팀들, HOME_SCORE || ' - ' || AWAY_SCORE SCORE, ABS(HOME_SCORE - AWAY_SCORE) 점수차 FROM SCHEDULE WHERE GUBUN = 'Y' AND SCHE_DATE BETWEEN '20120801' AND '20120831' ORDER BY SCHE_DATE;

[예제] SQL Server SELECT SCHE_DATE 경기일자, HOMETEAM_ID + ' - ' + AWAYTEAM_ID AS 팀들, HOME_SCORE + ' - ' + AWAY_SCORE AS SCORE, ABS(HOME_SCORE - AWAY_SCORE) AS 점수차 FROM SCHEDULE WHERE GUBUN = 'Y' AND SCHE_DATE BETWEEN '20120801' AND '20120831' ORDER BY SCHE_DATE;

[실행 결과] 경기일자 팀들 SCORE 점수차 ------- -------- ----- ----- 20120803 K01 - K03 3 - 0 3 20120803 K06 - K09 2 - 1 1 20120803 K08 - K07 1 - 0 1 20120804 K05 - K04 2 - 1 1 20120804 K10 - K02 0 - 3 3 20120811 K07 - K10 1 - 1 0 20120811 K03 - K08 2 - 0 2 20120811 K09 - K05 0 - 1 1 20120811 K04 - K02 0 - 2 2 20120811 K01 - K06 0 - 0 0 20120818 K05 - K01 0 - 2 2 20120818 K02 - K09 1 - 2 1 20120818 K08 - K10 3 - 1 2 20120818 K04 - K07 1 - 0 1 20120818 K06 - K03 3 - 1 2 20120824 K02 - K01 1 - 1 0 20120824 K05 - K03 3 - 3 0 20120824 K08 - K06 4 - 3 1 20120825 K10 - K04 1 - 1 0 20120825 K09 - K07 1 - 1 0 20120828 K04 - K08 2 - 3 1 20120828 K09 - K10 2 - 0 2 20120828 K03 - K02 0 - 0 0 20120828 K01 - K07 0 - 1 1 20120828 K06 - K05 1 - 1 0 25개의 행이 선택되었다.

[예제]에서 사용한 ABS 함수를 만드는데, INPUT 값으로 숫자만 들어온다고 가정한다.

[예제] Oracle CREATE OR REPLACE Function UTIL_ABS (v_input in number) ---------------- ① return NUMBER IS v_return number := 0; ---------------- ② BEGIN if v_input < 0 then ---------------- ③ v_return := v_input * -1; else v_return := v_input; end if; RETURN v_return; ---------------- ④ END; /

[예제] SQL Server CREATE Function dbo.UTIL_ABS (@v_input int) ---------------- ① RETURNS int AS BEGIN DECLARE @v_return int ---------------- ② SET @v_return=0 IF @v_input < 0 ---------------- ③ SET @v_return = @v_input * -1 ELSE SET @v_return = @v_input RETURN @v_return; ---------------- ④ END

[예제]에서 생성한 UTIL_ABS Function의 처리 과정은 다음과 같다.

① 숫자 값을 입력 받는다. 예제에서는 숫자 값만 입력된다고 가정한다. ② 리턴 값을 받아 줄 변수인 v_return를 선언한다. ③ 입력 값이 음수이면 -1을 곱하여 v_return 변수에 대입한다. ④ v_return 변수를 리턴한다.

[예제] 함수를 이용하여 앞의 SQL을 수정하여 실행한다.

[예제] Oracle SELECT SCHE_DATE 경기일자, HOMETEAM_ID || ' - ' || AWAYTEAM_ID 팀들, HOME_SCORE || ' - ' || AWAY_SCORE SCORE, UTIL_ABS(HOME_SCORE - AWAY_SCORE) 점수차 FROM SCHEDULE WHERE GUBUN = 'Y' AND SCHE_DATE BETWEEN '20120801' AND '20120831' ORDER BY SCHE_DATE;

[예제] SQL Server SELECT SCHE_DATE 경기일자, HOMETEAM_ID + ' - ' + AWAYTEAM_ID AS 팀들, HOME_SCORE + ' - ' + AWAY_SCORE AS SCORE, dbo.UTIL_ABS(HOME_SCORE - AWAY_SCORE) AS 점수차 FROM SCHEDULE WHERE GUBUN = 'Y' AND SCHE_DATE BETWEEN '20120801' AND '20120831' ORDER BY SCHE_DATE;

[실행 결과] 경기일자 팀들 SCORE 점수차 ------- -------- ------ ------ 20120803 K01 - K03 3 - 0 3 20120803 K06 - K09 2 - 1 1 20120803 K08 - K07 1 - 0 1 20120804 K05 - K04 2 - 1 1 20120804 K10 - K02 0 - 3 3 25개의 행이 선택되었다.

실행 결과는 앞의 ABS 내장함수를 사용한 SQL 문장과 같은 결과를 확인할 수 있다.

6. Trigger의 생성과 활용

Trigger란 특정한 테이블에 INSERT, UPDATE, DELETE와 같은 DML문이 수행되었을 때, 데이터베이스에서 자동으로 동작하도록 작성된 프로그램이다. 즉 사용자가 직접 호출하여 사용하는 것이 아니고 데이터베이스에서 자동적으로 수행하게 된다. Trigger는 테이블과 뷰, 데이터베이스 작업을 대상으로 정의할 수 있으며, 전체 트랜잭션 작업에 대해 발생되는 Trigger와 각 행에 대해서 발생되는 Trigger가 있다. 요구 사항은 다음과 같다고 가정한다. 어떤 쇼핑몰에 하루에 수만 건의 주문이 들어온다. 주문 데이터는 주문일자, 주문상품, 수량, 가격이 있으며, 사장을 비롯한 모든 임직원이 일자별, 상품별 총 판매수량과 총 판매가격으로 구성된 주문 실적을 온라인상으로 실시간 조회한다고 했을 때, 한 사람의 임직원이 조회할 때마다 수만 건의 데이터를 읽어 계산해야 한다. 가끔 한 번씩 조회한다면 문제가 없을 수도 있으나 빈번하게 조회작업이 일어난다면 조회작업에 많은 시간을 허비할 수 있다.

[예제] 트리거(Trigger)를 사용하여 주문한 건이 입력될 때마다, 일자별 상품별로 판매수량과 판매금액을 집계하여 집계자료를 보관하도록 한다. 먼저 관련 테이블을 생성한다.

[예제] Oracle CREATE TABLE ORDER_LIST ( ORDER_DATE CHAR(8) NOT NULL, PRODUCT VARCHAR2(10) NOT NULL, QTY NUMBER NOT NULL, AMOUNT NUMBER NOT NULL); CREATE TABLE SALES_PER_DATE ( SALE_DATE CHAR(8) NOT NULL, PRODUCT VARCHAR2(10) NOT NULL, QTY NUMBER NOT NULL, AMOUNT NUMBER NOT NULL);

[예제] SQL Server CREATE TABLE ORDER_LIST ( ORDER_DATE CHAR(8) NOT NULL, PRODUCT VARCHAR(10) NOT NULL, QTY INT NOT NULL, AMOUNT INT NOT NULL); CREATE TABLE SALES_PER_DATE ( SALE_DATE CHAR(8) NOT NULL, PRODUCT VARCHAR(10) NOT NULL, QTY INT NOT NULL, AMOUNT INT NOT NULL);

[예제] 이제 Trigger를 작성한다. Trigger의 역할은 ORDER_LIST에 주문 정보가 입력되면 주문 정보의 주문 일자(ORDER_LIST.ORDER_DATE)와 주문 상품(ORDER_LIST.PRODUCT)을 기준으로 판매 집계 테이블(SALES_PER_DATE)에 해당 주문 일자의 주문 상품 레코드가 존재하면 판매 수량과 판매 금액을 더하고 존재하지 않으면 새로운 레코드를 입력한다.

[예제] Oracle CREATE OR REPLACE Trigger SUMMARY_SALES ---------------- ① AFTER INSERT ON ORDER_LIST FOR EACH ROW DECLARE ---------------- ② o_date ORDER_LIST.order_date%TYPE; o_prod ORDER_LIST.product%TYPE; BEGIN o_date := :NEW.order_date; o_prod := :NEW.product; UPDATE SALES_PER_DATE ---------------- ③ SET qty = qty + :NEW.qty, amount = amount + :NEW.amount WHERE sale_date = o_date AND product = o_prod; if SQL%NOTFOUND then ---------------- ④ INSERT INTO SALES_PER_DATE VALUES(o_date, o_prod, :NEW.qty, :NEW.amount); end if; END; /

SUMMARY_SALES Trigger의 처리절차를 설명하면 다음과 같다.

① Trigger를 선언한다.CREATE OR REPLACE Trigger SUMMARY_SALES : Trigger 선언문AFTER INSERT : 레코드가 입력이 된 후 Trigger 발생 ON ORDER_LIST : ORDER_LIST 테이블에 Trigger 설정FOR EACH ROW : 각 ROW마다 Trigger 적용 ② o_date(주문일자), o_prod(주문상품) 값을 저장할 변수를 선언하고, 신규로 입력된 데이터를 저장한다. : NEW는 신규로 입력된 레코드의 정보를 가지고 있는 구조체 : OLD는 수정, 삭제되기 전의 레코드를 가지고 있는 구조체 [표 Ⅱ-2-17] 참조 ③ 먼저 입력된 주문 내역의 주문 일자와 주문 상품을 기준으로 SALES_PER_DATE 테이블에 업데이트한다. ④처리 결과가 SQL%NOTFOUND이면 해당 주문 일자의 주문 상품 실적이 존재하지 않으며, SALES_ PER_DATE 테이블에 새로운 집계 데이터를 입력한다.

[예제] SQL Server CREATE Trigger dbo.SUMMARY_SALES ---------------- ① ON ORDER_LIST AFTER INSERT AS DECLARE @o_date DATETIME,@o_prod INT,@qty int, @amount int BEGIN SELECT @o_date=order_date, @o_prod=product, @qty=qty, @amount=amount FROM inserted ---------------- ② UPDATE SALES_PER_DATE ---------------- ③ SET qty = qty + @qty, amount = amount + @amount WHERE sale_date = @o_date AND product = @o_prod; IF @@ROWCOUNT=0 ---------------- ④ INSERT INTO SALES_PER_DATE VALUES(@o_date, @o_prod, @qty, @amount) END

SUMMARY_SALES Trigger의 처리절차를 설명하면 다음과 같다.

① Trigger를 선언한다.CREATE Trigger SUMMARY_SALES : Trigger 선언문ON ORDER_LIST : ORDER_LIST 테이블에 Trigger 설정AFTER INSERT : 레코드가 입력이 된 후 Trigger 발생 ② o_date(주문일자), o_prod(주문상품), qty(수량), amount(금액) 값을 저장할 변수를 선언하고, 신규로 입력된 데이터를 저장한다.inserted는 신규로 입력된 레코드의 정보를 가지고 있는 구조체deleted는 수정, 삭제되기 전의 레코드를 가지고 있는 구조체. [표 Ⅱ-2-18] 참조 ③ 먼저 입력된 주문 내역의 주문 일자와 주문 상품을 기준으로 SALES_PER_DATE 테이블에 업데이트한다. ④ 처리 결과가 0건이면 해당 주문 일자의 주문 상품 실적이 존재하지 않으며, SALES_PER_DATE 테이블에 새로운 집계 데이터를 입력한다.

[예제] ORDER_LIST 테이블에 주문 정보를 입력한다.

[예제] Oracle SQL> SELECT * FROM ORDER_LIST; 선택된 레코드가 없다. SQL> SELECT * FROM SALES_PER_DATE; 선택된 레코드가 없다. SQL> INSERT INTO ORDER_LIST VALUES('20120901', 'MONOPACK', 10, 300000); 1개의 행이 만들어졌다. SQL> COMMIT; 커밋이 완료되었다.

[예제] SQL Server SELECT * FROM ORDER_LIST; 선택된 레코드가 없다. SELECT * FROM SALES_PER_DATE; 선택된 레코드가 없다. INSERT INTO ORDER_LIST VALUES('20120901', 'MONOPACK', 10, 300000); 1개의 행이 만들어졌다.

[예제] 주문 정보와 판매 집?.

[실행 결과] SQL> SELECT * FROM ORDER_LIST; ORDER_DATG PRODUCT QTY AMOUNT --------- -------- -------- ------- 20120901 MONOPACK 10 300000 SQL> SELECT * FROM SALES_PER_DATE; SALE_DATG PRODUCT QTY AMOUNT -------- -------- -------- -------- 20120901 MONOPACK 10 300000

[예제] 다시 한 번 같은 데이터를 입력해보고, 두 테이블의 데이터를 확인한다.

[실행 결과] Oracle SQL> INSERT INTO ORDER_LIST VALUES('20120901','MONOPACK',20,600000); 1개의 행이 만들어졌다. SQL> COMMIT; 커밋이 완료되었다. SQL> SELECT * FROM ORDER_LIST; ORDER_DATG PRODUCT QTY AMOUNT --------- ---------- ------ ------- 20120901 MONOPACK 10 300000 20120901 MONOPACK 20 600000 SQL> SELECT * FROM SALES_PER_DATE; SALE_DATG PRODUCT QTY AMOUNT -------- --------- ----- ------- 20120901 MONOPACK 30 900000

[실행 결과] SQL Server INSERT INTO ORDER_LIST VALUES('20120901','MONOPACK',20,600000); 1개의 행이 만들어졌다. SELECT * FROM ORDER_LIST; ORDER_DATG PRODUCT QTY AMOUNT --------- --------- ----- -------- 20120901 MONOPACK 10 300000 20120901 MONOPACK 20 600000 SELECT * FROM SALES_PER_DATE; SALE_DATG PRODUCT QTY AMOUNT -------- --------- ---- -------- 20120901 MONOPACK 30 900000

[예제] 이번에는 다른 상품으로 주문 데이터를 입력한 후 두 테이블의 결과를 조회해 보고 트랜잭션을 ROLLBACK 수행한다. 판매 데이터의 입력 취소가 일어나면, 주문 정보 테이블과 판매 집계 테이블에 동시에 입력(수정) 취소가 일어나는지 확인해본다.

[실행 결과] Oracle SQL> INSERT INTO ORDER_LIST VALUES('20120901','MULTIPACK',10,300000); 1개의 행이 만들어졌다. SQL> SELECT * FROM ORDER_LIST; ORDER_DA PRODUCT QTY AMOUNT -------- -------- ------ ------- 20120901 MONOPACK 10 300000 20120901 MONOPACK 20 600000 20120901 MULTIPACK 10 300000 SQL> SELECT * FROM SALES_PER_DATE; SALE_DATG PRODUCT QTY AMOUNT -------- -------- ------ ------- 20120901 MONOPACK 30 900000 20120901 MULTIPACK 10 300000 SQL> ROLLBACK; 롤백이 완료되었다. SQL> SELECT * FROM ORDER_LIST; ORDER_DATG PRODUCT QTY AMOUNT -------- -------- ------ ------- 20120901 MONOPACK 10 300000 20120901 MONOPACK 20 600000 SQL> SELECT * FROM SALES_PER_DATE; SALE_DATG PRODUCT QTY AMOUNT -------- --------- ------ ------- 20120901 MONOPACK 30 900000

[실행 결과] SQL Server BEGIN TRAN INSERT INTO ORDER_LIST VALUES('20120901','MULTIPACK',10,300000); 1개의 행이 만들어졌다. SELECT * FROM ORDER_LIST; ORDER_DATG PRODUCT QTY AMOUNT --------- --------- ------ ------- 20120901 MONOPACK 10 300000 20120901 MONOPACK 20 600000 20120901 MULTIPACK 10 300000 SELECT * FROM SALES_PER_DATE; SALE_DATG PRODUCT QTY AMOUNT -------- --------- ------ ------- 20120901 MONOPACK 30 900000 20120901 MULTIPACK 10 300000 ROLLBACK; 롤백이 완료되었다. SELECT * FROM ORDER_LIST; ORDER_DATG PRODUCT QTY AMOUNT --------- -------- ------ ------- 20120901 MONOPACK 10 300000 20120901 MONOPACK 20 600000 SELECT * FROM SALES_PER_DATE; SALE_DATG PRODUCT QTY AMOUNT -------- -------- ------ ------- 20120901 MONOPACK 30 900000

ROLLBACK을 하면 하나의 트랜잭션이 취소가 되어 Trigger로 입력된 정보까지 하나의 트랜잭션으로 인식하여 두 테이블 모두 입력 취소가 되는 것을 보여 주고 있다. Trigger는 데이터베이스에 의해 자동 호출되지만 결국 INSERT, UPDATE, DELETE 문과 하나의 트랜잭션 안에서 일어나는 일련의 작업들이라 할 수 있다. Trigger는 데이터베이스 보안의 적용, 유효하지 않은 트랜잭션의 예방, 업무 규칙 자동 적용 제공 등에 사용될 수 있다.

7. 프로시저와 트리거의 차이점

프로시저는 BEGIN ~ END 절 내에 COMMIT, ROLLBACK과 같은 트랜잭션 종료 명령어를 사용할 수 있지만, 데이터베이스 트리거는 BEGIN ~ END 절 내에 사용할 수 없다.


출처 : http://www.dbguide.net/db.db?cmd=view&boardUid=148207&boardConfigUid=9&categoryUid=216&boardIdx=135&boardStep=1

'프로그래밍 > DB' 카테고리의 다른 글

INNER JOIN & OUTER JOIN의 차이  (0) 2016.09.23
SQL의 JOIN에서 ON과 WHERE의 차이점  (0) 2016.09.23
풀스캔을 방지  (0) 2016.09.23
Posted by 당구치는 개발자
|