컨테이너 초기화와 종료

 

스프링 컨테이너는 초기화와 종료라는 라이프 사이클을 갖는다.

  • 컨텍스트 객체가 생성되는 시점에 컨테이너를 초기화함
  • 스프링 컨테이너는 설정 클래스에서 정보를 읽어와 알맞은 Bean 객체를 생성하고, 각 Bean을 연결(의존 주입)하는 작업 수행
  • 초기화가 끝난 후 컨테이너를 사용 가능(getBean()등의 작업으로 Bean 객체를 구하는 행위 등)
  • 컨테이너 사용이 끝나면 컨테이너를 close() 매서드를 사용해 종료, Bean 객체의 소멸

 기본적으로 Spring의 ApplicationContext 구현은 초기화 프로세스에서 모든 싱글톤 빈을 생성 및 설정


> 따라서 Bean에 문제가 있을 경우 초기화 단계에서 알 수 있다는 장점이 존재

 

 

// 1. 컨테이너 초기화
AnnotationConfigApplicationiContext ctx = 
        new AnnotationConfigContext(AppContext.class);

// 2. 컨테이너에서 빈 객체를 구해서 사용
Greeter g = ctx.getBean("greeter", Greeter.class);
String msg = g.greet("스프링");
System.out.println(msg);

// 3. 컨테이너 종료
ctx.close();

 

 

 

 

  1. AnnotationConfigApplicationiContext의 생성자를 이용해서 context 객체를 생성한다.
    이 시점에서 스프링 컨테이너 초기화가 진행되고, 이 스프링 컨테이너는 설정 클래스에서 정보를 읽어와 알맞은 빈 객체를 생성하고 각 빈을 연결(의존주입)하는 작업을 수행한다.

  2. (위에서 초기화되어 사용가능한 컨테이너) getBean()과 같은 메서드를 이용해서 컨테이너에 보관된 빈 객체를 구한다.

  3. 컨테이너 사용을 종료할 때 사용하는 메서드이다. AbstractApplicationContext 클래스에 정의되어 있다.
    AnnotationConfigApplicationiContext가 AbstractApplicationContext를 상속 받기 때문에 close() 사용이 가능하다.

 

컨테이너 초기화 -> 빈 객체의 생성, 의존 주입, 초기화
컨테이너 종료 -> 빈 객체의 소멸



 

 


스프링 빈 객체의 라이프 사이클

객체생성 - 의존설정 - 초기화 - 소멸

 

스프링 컨테이너는 빈 객체의 라이프 사이클을 관리한다.

 

 

1. 빈 객체의 초기화와 소멸 : 스프링 인터페이스

  • org.springframework.beans.factory.InitializingBean
  • org.springframework.beans.factory.DisposableBean

 

빈 객체를 생성한 뒤, 초기화 과정이 필요하면

InitializingBean 인터페이스를 상속하고 afterPropertiesSet()메서드를 구현하면 된다.

빈 객체의 소멸 과정이 필요하면 DisposableBean 인터페이스를 상속하고 destroy()메서드를 구현하면 된다.


ex. 데이터 베이스 커넥션 풀, 채팅 클라이언트

메서드 정의 인터페이스

  • org.springframework.beans.factory.InitializingBean
  • org.springframework.beans.factory.DisposableBean

 

 

//초기화 인터페이스
public interface InitializingBean {
    void afterPropertiesSet() throws Exception;
}

//소멸 인터페이스
public interface DisposableBean {
    void Destroy() throws Exception;
}

 

 

 

해당 코드를 수행하면 콘솔 화면에 매서드에서 정의한 "Client.afterPropertiesSet() 실행" 및 "Client.destroy() 실행"이 출력 됨

 

빈 객체 생성을 마무리한 뒤에 초기화 메서드를 실행한다.
또, 가장 마지막에 destroy() 메서드를 실행한다.



 

 

2. 빈 객체의 초기화와 소멸 : 커스텀 메서드

인터페이스로 상속받아 구현하는 것 말고 외부에서 제공받은 클래스를 스프링 빈 객체로 설정하고 싶을 때도 있다.

스프링 설정에서 직접 메서드를 지정할 수 있다.

@Bean태그에서 initMethod 속성과 destroyMethod 속성을 사용해서 초기화 메서드와 소멸 메서드의 이름을 지정하면 된다.

 

 

 

//Client2.java
        ...

// 직접 초기화 메서드 지정
public void connect(){
    System.out.println("Client2.connect() 실행");
}

// 직접 소멸 메서드 지정
public void close(){
        System.out.println("Client2.close() 실행");
}

        ...

 

 

 

이 메서드들을 @Bean 애노테이션의 initMethod 속성과 destroyMethod 속성에 사용될 메서드 이름인 connect와 close를 지정해주면 된다.

 

@Bean(initMethod = "connect", destoryMethod = "close") public Client2 clien2(){ ... }

초기화 메서드를 직접 실행할 때 초기화 메서드가 두 번 불리지 않다록 조심하자. afterPropertiesSet()이 두번 불릴 위험 있음



 

 


빈 객체의 생성과 관리 범위

 

// 한 식별자에 대해 한 개의 객체만 존재하는 빈
// 싱글톤 범위를 갖는다.
//client1 == client : true
Client client1 = ctx.getBean("client", Client.class);
Client client2 = ctx.getBean("client", Client.class);

------------------------
// client 빈의 범위가 프로토타입일 경우
// 매번 새로운 객체를 생성
// client1 != client : true
Client client1 = ctx.getBean("client", Client.class);
Client client2 = ctx.getBean("client", Client.class);

 

 

 

별도의 설정을 하지 않으면 싱글톤 범위를 갖는데, 특정 빈을 프로토 타입으로 빈을 설정할 수 도 있다. @Scope애노테이션을 사용해주면 된다.

 

 

@Bean
@Scope("prototype")
public Client client(){
        ...
}

 

 

 

  • 싱글톤 범위를 명시적으로 지정해주고 싶으면 @Scope("singleton)이라고 해주면 된다.
  • 프로토 타입은 별도의 소멸 처리를 코드에서 직접 해야 한다.

 


Reference.

'초보 웹 개발자를 위한 스프링5 프로그래밍 입문' 

'🔥 > Spring' 카테고리의 다른 글

[spring] 컴포넌트 스캔이란  (0) 2021.08.31
[Spring] "회초리단" 스프링 스터디 1차  (0) 2021.08.20
[Spring] DI의 세가지 방법  (0) 2021.08.18
[Spring] 의존성 주입(DI)이란 ?  (0) 2021.08.18
  • 자동 주입과 함께 사용되는 기능
  • 스프링이 직접 클래스를 검색해서 빈으로 등록해주는 기능
  • 설정 코드가 크게 줄어듦

Component-scan은 xml에 일일이 빈등록을 하지않고 각 빈 클래스에 @Component를 통해 자동 빈 등록이 된다.

@Component @Controller @Service @Repository와 같은 어노테이션을 자동 등록 처리해준다.

 

 

 

@Component 애노테이션으로 스캔 대상 지정

 

 

스프링이 검색해서 빈으로 등록할 수 있으려면 클래스에 @Component 애노테이션을 붙여야 한다.
이 애노테이션은 해당 클래스를 스캔 대상으로 표시한다.

 

  • @Component 애노테이션에 값을 주면 그 값을 빈 이름으로 사용한다.
    ex. @Component("listPrinter")

 

 


@ComponentScan 애노테이션으로 스캔 설정

 

@Component 애노테이션을 붙인 클래스를 스캔해서 스프링 빈으로 등록하려면, 설정 클래스에 @ComponentScan 애노테이션을 적용해야한다.

 

 

 

@Configuration
@ComponentScan(basePackages = {"spring"})
public class AppCtx{
    ...
}

 

 

 

이 코드를 보면 AppCtx 클래스에서

 

@ComponentScan 애노테이션을 사용하여 @Component 애노테이션이 붙은 클래스를 검색해서 빈으로 등록해주기 때문에 설정 코드가 확연히 줄어든다.


또 컴포넌트 스캔 애노테이션을 살펴보면 basePackages 속성값은 {"spring"}이다. 이 속성은 스캔 대상 패키지 목록을 지정하는 것이다.
이는 spring 패키지와 그 하위 패키지에 속한 클래스를 스캔 대상으로 설정한다. 스캔 대상에 해당하는 클래스중 @Component 애노테이션이 붙은 클래스의 객체를 생성해 빈으로 등록한다.

 

 


 

 

스캔 대상에서 제외하거나 포함하기

 

excludeFilters 속성을 사용하면 스캔할 때 특정 대상을 자동 등록 대상에서 제외할 수 있다.

// 정규 표현식을 사용해서 제외 대상을 지정한다.
// "spring."으로 시작하고 Dao로 끝나는 정규 표현식을 지정
@ComponentScan(basePackages = {"spring"},
    excludeFilters = @Filter(type = FilterType.REGEX, pattern = "spring\\..*Dao"))





// AspectJ 패턴을 사용해 대상을 지정한다.
// spring 패키지의 Dao로 끝나는 타입을 지정
// AspectJ 패턴이 동작하려면 의존 대상에 aspectjweaver모듈을 추가해야한다.
@ComponentScan(basePackages = {"spring"},
        excludeFilters = @Filter(type = FilterType.ASPECTJ, pattern = "spring.*Dao"))





// 특정 애노테이션을 붙인 타입을 컴포넌트 대상에서 제외한다.
// 패턴은 Stringp[] 타입이므로 배열을 이용해 패턴을 한 개 이상 지정할 수 있다.
@ComponentScan(basePackages = {"spring", "spring2"},
        excludeFilters = @Filter(type = FilterType.Annotation, pattern = {NoProduct.class, ManualBean.class}))





// 특정 타입이나 그 하위 타입을 컴포넌트 스캔 대상에서 제외한다.
@ComponentScan(basePackages = {"spring"},
        excludeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = MemberDao.class))






// 설정할 필터가 2개 이상이면 excludeFilters 속성에 배열을 사용해서 목록을 전달하면 된다.
@ComponentScan(basePackages = {"spring"},
        excludeFilters = {
                @Filter(type = FilterType.ANNOTATION, classes = ManualBean.class),
                @Filter(type = FilterType.REGEX, pattern = "spring2\\..*")
        }

 

 

 

 

 

 

@Component 애노테이션을 붙인 클래스만 스캔 대상에 포함되는 것이 아니다.

  • @Component
  • @Controller
  • @Service
  • @Repository
  • @Aspect
  • @Configuration

@Aspect를 제외하고 나머지 애노테이션은 @Component 애노테이션에 대한 특수 애노테이션이다.




 

컴포넌트 스캔에 따른 충돌 처리


컴포넌트 스캔 기능을 사용해서 Bean을 등록할 경우, 아래와 같은 두 가지 충돌이 발생 가능

  1. Bean 이름의 충돌
  2. 수동 등록에 따른 충돌

2-1. Bean 이름 충돌

  • 서로 다른 패키지에 같은 클래스의 이름이 존재하고, 두 클래스 모두 @Component 어노테이션이 붙게 된다면,
    Exception이 발생하게 됨
  • 이럴 경우, 둘 중 하나에 명시적으로 Bean 이름을 지정해서 이름 충돌을 피해야 함

2-2. 수동 등록에 따른 충돌

  1. 같은 클래스를 같은 이름으로 설정할 때:
    • @Component 어노테이션을 통해 이미 지정한 Bean의 클래스 이름이 존재하지만,
      클래스 설정에 직접 해당 클래스를 동일한 이름으로 정해 등록하는 경우 발생
    • 즉, 스캔할 때 사용하는 Bean 이름과 수동 등록한 이름이 같을 경우, 수동 등록한 Bean이 우선시 됨
  2. 같은 클래스를 다른 이름으로 설정할 때:
    • 만약, 스캔할 때 사용하는 Bean 이름과 동일한 클래스를 다른 이름으로 수동 등록하는 경우에는
      다른 이름의 두 개의 Bean이 만들어지게 됨
    • 이런 경우에는 @Qualifier 어노테이션을 통해 알맞은 Bean을 선택해야 함

 


Reference.

'초보 웹 개발자를 위한 스프링5 프로그래밍 입문' link1

 

시스템 콜이란?

운영 체제의 커널이 제공하는 서비스에 대해,
응용 프로그램의 요청에 따라 커널에 접근하기 위한 인터페이스이다.

보통 C나 C++과 같은 고급 언어로 작성된 프로그램들은
직접 시스템 호출을 사용할 수 없기 때문에
고급 API를 통해 시스템 호출에 접근하게 하는 방법이다.



✔ 시스템 콜은 왜 필요할까?


우리가 일반적으로 사용하는 프로그램은 '응용프로그램'이다.

 

유저레벨의 프로그램은 유저레벨의 함수들 만으로는 많은 기능을 구현하기 힘들기 때문에, 커널(kernel)의 도움을 반드시 받아야 한다. 이러한 작업은 응용프로그램으로 대표되는 유저 프로세스(User Process)에서 유저모드에서는 수행할 수 없다.

 

반드시 kernel에 관련된 것은 커널모드로 전환한 후에야, 해당 작업을 수행할 권한이 생긴다. 커널 모드를 통한 이러한 작업은 반드시 시스템 콜을 통해 수행하도록 설계되어 있습니다.

 

 

 

 

 

 

✔ 시스템 콜의 커널 모드와 사용자 모드


1. 커널 모드
프로그램 카운터가 운영체제가 존재하는 부분을 가리키고 있다면, 현재 운영체제의 코드를 수행 중이며 CPU가 커널 모드에서 수행 중이라고 한다.
2. 사용자 모드
프로그램 카운터가 사용자 프로그램이 존재하는 메모리 위치를 가리킬 경우, 사용자 프로그램을 수행 중이며 CPU가 사용자 모드에서 수행 중이라고 한다.
  • 일반 명령 : 메모리에서 자료를 읽어와서 CPU에서 계산하고 결과를 메모리에 쓰는 일련의 명령들. 모든 프로그램이 수행할 수 있음. (사용자 모드)
  • 특권 명령 : 보안이 필요한 명령으로 입출력 장치, 타이머 등 각종 장치를 접근하는 명령.(커널 모드)
  • CPU 내에 모드 비트를 두어 두 명령을 수행한다.
  • 사용자 프로그램이 디스크의 파일을 접근하거나, 화면에 결과를 출력하는 등의 작업이 필요한 경우가 있다. 하지만, 이러한 작업은 특권 명령의 수행을 필요로 한다.
  • 이와 같은 경우, 사용자 프로그램은 스스로 특권 명령을 수행할 수 없으므로 운영체제에게 특권 명령의 대행을 요청한다. 이러한 서비스 요청은 시스템 콜이라고 부른다. (즉, 특권 명령의 대행을 요청하여 사용자 프로그램이 커널 영역의 기능을 수행하게 해준다.)

 

 

 

 

✔ 디스크에서 자료를 읽어오는 시스템 콜이라고 가정!


  1. 사용자 프로그램이 시스템 콜을 하게 되면 운영체제는 자신의 커널 영역에 정의된 시스템 콜 처리 코드를 수행한다.
  2. CPU가 컨트롤 레지스터를 세팅해 디스크 컨트롤러에게 데이터를 읽어오라고 명령한다.
  3. 디스크 컨트롤러는 디스크로부터 데이터를 읽어와서 자신의 로컬 버퍼에 저장한다.
  4. 작업이 완료되면 디스크 컨트롤러가 CPU에게 인터럽트를 발생시켜 입출력 작업이 완료되었음을 통지한다.

통상적으로 시스템 콜은 여러 종류의 기능으로 나뉘어져 있다. 각 시스템 콜에는 번호가 할당되고 시스템 콜 인터페이스는 이러한 번호에 따라 인덱스되는 테이블을 유지한다. 아래 그림은 open() 시스템 콜을 호출했을 때, 운영체제에서 어떻게 처리되는지를 보여준다.

 

필요한 기능이나 시스템 환경에 따라 시스템 콜이 발생할 때, 좀 더 많은 정보가 필요할 수도 있다. 그러한 정보가 담긴 매개변수를 운영체제에 전달하기 위해서는 대략 3가지 정도의 방법이 있다.

  1. 매개변수를 CPU 레지스터 내에 전달한다. 이 경우에 매개변수의 갯수가 CPU 내의 레지스터 갯수보다 많을 수 있다.
  2. 위와 같은 경우에 매개변수를 메모리에 저장하고 메모리의 주소가 레지스터에 전달된다. (아래 그림 참고)
  3. 매개변수는 프로그램에 의해 스택으로 전달될 수도 있다.\

* 2,3번은 전달되는 매개변수의 갯수나 길이에 제한이 없기 때문에 몇몇 운영체제에서 선호하는 방식이다.

 

 

 

 

 

✔ 시스템 콜의 유형


5가지의 범주로 나눌 수 있다.

  1. 프로세스 제어 : 프로세스 특권 모드를 사용해 직접적으로 프로세스 제어가 가능
  2. 파일 조작 : 파일을 생성하거나 삭제, 관리 등
  3. 장치 관리 : 장치 요구 및 장치 해제, 읽기, 쓰기, 재배치 등
  4. 정보 유지 : 시간과 날짜의 설정과 획득, 시스템 자료의 설정과 획득
  5. 통신 : 통신 연결의 생성 및 제거, 메시지의 송수신, 상태 정보 전달 등

 

 


Reference.

link1 link2 


WWW world wide web의 약자

인터넷을 통해 접근할 수 있는 정보 공간
URL로 문서등 리소스를 식별하고, 리소스 간 하이퍼링크로 연결될 수 있다

 

 

 

웹 통신 


 

  • 클라이언트 : 사용자가 서버에 접속하기 위해 사용하는 프로그램 또는 서비스. 웹 브라우저, 모바일 앱 등
  • 서버 : 클라이언트에게 네트워크를 통해 정보나 서비스를 제공하는 컴퓨터 시스템

 

 

 

 

 

 

 

 

웹 통신 과정


 

  1. 사용자가 웹 브라우저를 통해 URL을 입력한다
  2. 입력된 URL 중 도메인 네임을 DNS 서버에서 검색한다
  3. DNS 서버에서 해당 도메인 네임에 해당하는 IP 주소를 찾아 사용자가 입력한 URL 정보와 함께 전달한다
  4. 웹 페이지 URL 정보와 전달받은 IP 주소를 이용해 HTTP 요청 메시지를 생성한다
  5. 요청은 TCP를 통해 서버로 전송된다
  6. 서버는 클라이이너트의 요청을 받고 응답을 전송한다

 

 

 

 

 

 

 

 

 

 

 

DNS의 웹/앱 라우팅 과정


 

  1. 사용자가 웹 브라우저 주소창에 www.example.com을 입력
  2. www.example.com에 대한 요청이 인터넷 서비스 제공업체(ISP)가 관리하는 DNS 해석기로 라우팅
  3. DNS 해석기는 요청을 DNS 루트 이름 서버에 전달
  4. DNS 해석기는 요청을 .com 도메인 TLD(Top-level Domain) 네임 서버 중 하나에 다시 전달
  5. DNS 해석기는 요청을 Route 53 네임 서버에 다시 전달
  6. Route 53 네임 서버는 www.example.com 레코드를 찾아 IP주소를 DNS 해석기로 반환
  7. DNS 해석기는 웹 브라우저에 IP주소 반환

 

 

 

 

 

 

 

❗우리가 Chrome 을 실행시켜 주소창에 특정 URL 값을 입력시키면 어떤 일이 일어나는가?


in 브라우저

  1. url 에 입력된 값을 브라우저 내부에서 결정된 규칙에 따라 그 의미를 조사한다.
  2. 조사된 의미에 따라 HTTP Request 메시지를 만든다.
  3. 만들어진 메시지를 웹 서버로 전송한다.

이 때 만들어진 메시지 전송은 브라우저가 직접하는 것이 아니다. 브라우저는 메시지를 네트워크에 송출하는 기능이 없으므로 OS에 의뢰하여 메시지를 전달한다. 우리가 택배를 보낼 때 직접 보내는게 아니라, 이미 서비스가 이루어지고 있는 택배 시스템(택배 회사)을 이용하여 보내는 것과 같은 이치이다. 단, OS에 송신을 의뢰할 때는 도메인명이 아니라 ip주소로 메시지를 받을 상대를 지정해야 하는데, 이 과정에서 DNS서버를 조회해야 한다.

 

 

 

in 프로토콜 스택, LAN 어댑터

  1. 프로토콜 스택(운영체제에 내장된 네트워크 제어용 소프트웨어)이 브라우저로부터 메시지를 받는다.
  2. 브라우저로부터 받은 메시지를 패킷 속에 저장한다.
  3. 그리고 수신처 주소 등의 제어정보를 덧붙인다.
  4. 그런 다음, 패킷을 LAN 어댑터에 넘긴다.
  5. LAN 어댑터는 다음 Hop의 MAC주소를 붙인 프레임을 전기신호로 변환시킨다.
  6. 신호를 LAN 케이블에 송출시킨다.

프로토콜 스택은 통신 중 오류가 발생했을 때, 이 제어 정보를 사용하여 고쳐 보내거나, 각종 상황을 조절하는 등 다양한 역할을 하게 된다. 네트워크 세계에서는 비서가 있어서 우리가 비서에게 물건만 건네주면, 받는 사람의 주소와 각종 유의사항을 써준다! 여기서는 프로토콜 스택이 비서의 역할을 한다고 볼 수 있다.

 

 

in 허브, 스위치, 라우터

  1. LAN 어댑터가 송신한 프레임은 스위칭 허브를 경유하여 인터넷 접속용 라우터에 도착한다.
  2. 라우터는 패킷을 프로바이더(통신사)에게 전달한다.
  3. 인터넷으로 들어가게 된다.

 

 

in 액세스 회선, 프로바이더

  1. 패킷은 인터넷의 입구에 있는 액세스 회선(통신 회선)에 의해 POP(Point Of Presence, 통신사용 라우터)까지 운반된다.
  2. POP 를 거쳐 인터넷의 핵심부로 들어가게 된다.
  3. 수 많은 고속 라우터들 사이로 패킷이 목적지를 향해 흘러가게 된다.

 

 

 

in 방화벽, 캐시서버

  1. 패킷은 인터넷 핵심부를 통과하여 웹 서버측의 LAN 에 도착한다.
  2. 기다리고 있던 방화벽이 도착한 패킷을 검사한다.
  3. 패킷이 웹 서버까지 가야하는지 가지 않아도 되는지를 판단하는 캐시서버가 존재한다.

굳이 서버까지 가지 않아도 되는 경우를 골라낸다. 액세스한 페이지의 데이터가 캐시서버에 있으면 웹 서버에 의뢰하지 않고 바로 그 값을 읽을 수 있다. 페이지의 데이터 중에 다시 이용할 수 있는 것이 있으면 캐시 서버에 저장된다.

 

 

 

 

in 웹 서버

  1. 패킷이 물리적인 웹 서버에 도착하면 웹 서버의 프로토콜 스택은 패킷을 추출하여 메시지를 복원하고 웹 서버 애플리케이션에 넘긴다.
  2. 메시지를 받은 웹 서버 애플리케이션은 요청 메시지에 따른 데이터를 응답 메시지에 넣어 클라이언트로 회송한다.
  3. 왔던 방식대로 응답 메시지가 클라이언트에게 전달된다.

 

 


Reference.

link1 link2 

트랜잭션이란 


트랜잭션은 여러 개의 수행이 일련의 처리 단위로 묶이는 것을 말한다.

위 그림은 왼쪽 계좌의 돈을 오른쪽 계좌로 입금하는 과정이다.
첫번 째처럼 왼쪽 계좌에서 출금이 성공되면 오른쪽 계좌로 입금된다.
ATM의 문제로 왼쪽에서 출금이 되고 몇 분 후, 출금이 취소되었다고 하면 두번째 그림처럼 오른쪽 계좌에도 입금이 되지 않아야한다.

만약 출금은 취소 되었는데 입금이 돼버리면 큰 기능상의 문제인 것이다.
이렇게 일련의 처리가 All or Nothing으로 이루어지는 것이 트랜잭션이다.
  • 데이터베이스의 상태를 변화시키기 위해 수행하는 작업 단위
  • 상태를 변화 시킨다 =  SQL 질의어를 통해 DB에 접근한다 
    • SELECT INSERT DELETE UPDATE
  • 작업 단위 ---> 많은 SQL 명령문들을 사람이 정하는 기준에 따라 정하는 것
    •  게시판에서 사용자가 글을 작성하고 올리기 버튼을 누른 후 게시판에 다시 돌아오면 게시판에 내가 쓴 글이 업데이트된 상태를 볼 수 있다.
      • 이때 DB 작업
        • 올리기 버튼을 누른다. : INSERT문을 사용해 사용자가 입력한 게시글 데이터를 옮김.
        • 게시판 새로 구성 : SELECT문을 사용해 최신 정보를 유지.
      • 현재 작업 단위  INSERT 문 + SELECT 문 -----------> 이를 통틀어 하나의 tranaction이라 한다!

즉. 하나의 트랜잭션 설계를 잘 만드는 것이 데이터를 다룰 때 많은 이점을 준다.

 

작업의 완전성 을 보장해주는 것이다. 즉, 논리적인 작업 셋을 모두 완벽하게 처리하거나 또는 처리하지 못할 경우에는 원 상태로 복구해서 작업의 일부만 적용되는 현상이 발생하지 않게 만들어주는 기능이다. 사용자의 입장에서는 작업의 논리적 단위로 이해를 할 수 있고 시스템의 입장에서는 데이터들을 접근 또는 변경하는 프로그램의 단위가 된다.

 

 

 

 

 

트랜잭션의 Commit, Rollback 연산


Commit

 이란 하나의 트랜잭션이 성공적으로 끝났고, 데이터베이스가 일관성있는 상태에 있을 때, 하나의 트랜잭션이 끝났다라는 것을 알려주기위해 사용하는 연산이다.

이 연산을 사용하면 수행했던 트랜잭션이 로그에 저장되며, 후에 Rollback 연산을 수행했었던 트랜잭션단위로 하는것을 도와준다.

 

 

Rollback

이란 하나의 트랜잭션 처리가 비정상적으로 종료되어 트랜잭션의 원자성이 깨진경우, 트랜잭션을 처음부터 다시 시작하거나, 트랜잭션의 부분적으로만 연산된 결과를 다시 취소시킨다.

후에 사용자가 트랜잭션 처리된 단위대로 Rollback을 진행할 수도 있다.

 

 

 

 

트랜잭션 특징 ACID


ACID 4가지 특성을 만족해야한다.

 

1. 원자성(Atomicity)

만약 트랜잭션 중간에 어떠한 문제가 발생한다면 트랜잭션에 해당하는 어떠한 작업 내용도 수행되어서는 안되며 아무런 문제가 발생되지 않았을 경우에만 모든 작업이 수행되어야 한다.

 

2. 일관성(Consistency)

트랜잭션이 완료된 다음의 상태에서도 트랜잭션이 일어나기 전의 상황과 동일하게 데이터의 일관성을 보장해야 한다.

 

3. 고립성(Isolation)

각각의 트랜잭션은 서로 간섭없이 독립적으로 수행되어야 한다.

 

4. 지속성(Durability)

트랜잭션이 정상적으로 종료된 다음에는 영구적으로 데이터베이스에 작업의 결과가 저장되어야 한다.

 

 

 

 

 

트랜잭션의 상태


 

Active

트랜잭션의 활동 상태. 트랜잭션이 실행중이며 동작중인 상태를 말한다.

 

Failed

트랜잭션 실패 상태. 트랜잭션이 더이상 정상적으로 진행 할 수 없는 상태를 말한다.

 

Partially Committed

트랜잭션의 Commit 명령이 도착한 상태. 트랜잭션의 commit이전 sql문이 수행되고 commit만 남은 상태를 말한다.

 

Committed

트랜잭션 완료 상태. 트랜잭션이 정상적으로 완료된 상태를 말한다.

 

Aborted

트랜잭션이 취소 상태. 트랜잭션이 취소되고 트랜잭션 실행 이전 데이터로 돌아간 상태를 말한다.

 

Partially Committed 와 Committed 의 차이점

Commit 요청이 들어오면 상태는 Partial Commited 상태가 된다. 이후 Commit을 문제없이 수행할 수 있으면Committed 상태로 전이되고, 만약 오류가 발생하면 Failed 상태가 된다.

즉, Partial Commited는 Commit 요청이 들어왔을때를 말하며, Commited는 Commit을 정상적으로 완료한 상태를 말한다.

 

 

 

 

잠금


■ 잠금(Locking)이란 ?

- 여러 사용자가 동일한 시간에 동일한 데이터를 동시에 액세스할 수 있게 해준다.

- 잠금은 트랜잭션을 순차적으로 처리되도록 함으로써 손실된 업데이트를 방지하는데 중요한 역할을 하며 자동으로 발생한다.

- 잠금을 통해 데이터에 대한 일관성 유지와 동시 사용이 가능해진다.

 

 

 

 ■ 블로킹(Blocking)이란 ?

- 어떤 프로세스가 자원을 엑세스하려고 할 때 이미 다른 프로세스가 그 자원을 잠그고 있어서 그 잠금이 풀릴 때까지 기다려야 하는 상황을 말한다. 이러한 차단이 오랫동안 유지될 경우 문제가 된다.

 

 

 

■ 잠금 관리

- 교착상태(Dead Locks) :

  * 트랜잭션 A는 트랜잭션 B가 원하는 데이터를 잠그고 있으면서 트랜잭션 B가 잠그고 있는 데이터를 원한다.

  * 트랜잭션 B는 트랜잭션 A가 원하는 데이터를 잠그고 있으면서 트랜잭션 A가 잠그고 있는 데이터를 원한다.

- MSSQL 해결방법 : 한쪽 트랜잭션 처리를 강제로 종료(비용이 적은 트랜잭션의 처리를 강제 종료한다.)

- SET DEADLOCK_PRIORITY 문을 사용해 교착 상태 발생 시 트랜잭션의 중요도를 지정할 수 있다.

- 우리 회사의 경우 sp_mon_blocking 프로시저를 이용해 블로킹 상태인 spid를 찾아낸다. 블로킹하고 있는 spid 세션을 죽이기 위해 ' kill [spid] ' 명령어를 사용한다.

 

 

 

트랜잭션을 사용할 때 주의할 점


트랜잭션은 꼭 필요한 최소의 코드에만 적용하는 것이 좋다. 즉 트랜잭션의 범위를 최소화하라는 의미다.

 

일반적으로 데이터베이스 커넥션은 개수가 제한적이다.

그런데 각 단위 프로그램이 커넥션을 소유하는 시간이 길어진다면 사용 가능한 여유 커넥션의 개수는 줄어들게 된다.

그러다 어느 순간에는 각 단위 프로그램에서 커넥션을 가져가기 위해 기다려야 하는 상황이 발생할 수도 있는 것이다.

 

 

교착상태

교착상태란 무엇인가
복수의 트랜잭션을 사용하다보면 교착상태가 일어날수 있다. 교착상태란 두 개 이상의 트랜잭션이 특정 자원(테이블 또는 행)의 잠금(Lock)을 획득한 채 다른 트랜잭션이 소유하고 있는 잠금을 요구하면 아무리 기다려도 상황이 바뀌지 않는 상태가 되는데, 이를 교착상태라고 한다.

 

 

 

교착상태의 빈도를 낮추는 방법

  • 트랜잭션을 자주 커밋한다.
  • 정해진 순서로 테이블에 접근한다. 위에서 트랜잭션 1 이 테이블 B -> A 의 순으로 접근했고, 트랜잭션 2 는 테이블 A -> B의 순으로 접근했다. 트랜잭션들이 동일한 테이블 순으로 접근하게 한다.
  • 읽기 잠금 획득 (SELECT ~ FOR UPDATE)의 사용을 피한다.
  • 한 테이블의 복수 행을 복수의 연결에서 순서 없이 갱신하면 교착상태가 발생하기 쉽다, 이 경우에는 테이블 단위의 잠금을 획득해 갱신을 직렬화 하면 동시성을 떨어지지만 교착상태를 회피할 수 있다.

 


Reference.

link1 link2 link3

주변장치와 입출력 장치는 CPU나 메모리와 달리 인터럽트라는 메커니즘을 통해 관리된다.

인터럽트를 하는 이유는???
그 이유는 입출력 연산이 CPU 명령 수행속도보다 현저히 느리기 때문이다.
CPU는 비싼데 오래걸리는 입출력 연산을 기다리며 CPU가 쉬게 만들 수 없어서
연산 결과가 나올 때 까지 다른 일을 하라고 시키는 것인데,
입출력이 완료되면 다시 CPU를 불러와 해당 작업을 이어가게 한다.

이때 CPU에게 완료되었음을 알려주는 것이 인터럽트이다.

 

- 하드웨어 장치가 CPU에게 어떤 사실을 알려주거나 CPU의 서비스를 요청해야 할 경우, CPU 내에 있는 인터럽트 라인을 세팅하여 인터럽트를 발생시킨다. (프로그램이 명령을 수행하기 위해서는 CPU를 할당받아야 함)

- CPU는 매번 프로그램 카운터가 가리고 있는 곳의 명령을 수행한 뒤, 다음 명령을 수행하기 직전에 인터럽트 라인이 세팅되었는지 체크한다.

- 이를 통해 인터럽트가 발생했으면 CPU는 현재 수행 중이던 프로세스를 멈추고 운영 체제의 인터럽트 처리 루틴으로 이동하여 인터럽트 처리를 수행한다.

 

인터럽트는 크게 하드웨어 인터럽트와 소프트웨어 인터럽트로 나뉘는 경우도 있다. 

 

 

 

 

 

 

하드웨어 인터럽트


  • 일반적인 인터럽트
  • 하드웨어 컨트롤러가 CPU의 서비스를 요청하기 위해 발생시키는 인터럽트

 

하드웨어 인터럽트가 발생하는 예

1. 기계검사 인터럽트

      - 프로그램을 실행하는 도중 갑작스런 정전이나 컴퓨터 자체 내에서 기계적인 문제가 발생한 경우

2. 외부 인터럽트

      - 오퍼레이터나 타이머에 의해 의도적으로 프로그램이 중단된 경우

3. 입출력 인터럽트 

      - 입출력의 종료나 입출력의 오류에 의해 CPU의 기능이 요청되는 경우

4. 프로그램검사 인터럽트 

      - 프로그램 실행 중 보호된 기억공간 내에 접근하거나 불법적인 명령 수행과 같은 프로그램의 문제가 발생한 경우

 

 

 

 

소프트웨어 인터럽트


  • 소프트웨어 인터럽트는 외부가 아닌 CPU 내부에서 자신이 실행한 명령이나 CPU의 명령 실행에 관련된 모듈이 변화하는 경우 발생
  • 프로그램 실행 중 프로그램 상의 처리 불가능한 오류나 이벤트를 알리기 위한 경우 발생하는데, 이를 트랩 또는 예외라 부른다.
  • 또한 프로그램 내에서 특별한 서비스를 요구하거나
  • 감시를 목적으로, 의도적으로 프로그램이 발생시킨 특별한 명령어에 의해 발생되기도 한다.

1. 예외 상황(Exception)

  • 프로그램이 허용되지 않은 연산을 수행하려고 할 때, 자동적으로 발생한다. 운영체제는 예외 상황이 발생했을 때, CPU의 제어권을 획득해 이 상황에 대한 조치를 취한다.
  • ex) 0으로 나누는 연산, 자신의 주소 공간을 넘어서는 메모리 참조 등
  • 예외 상황에 대한 처리 루틴을 자신의 코드 영역에 가지고 있음

2. 시스템 콜(System Call)

  • 사용자 프로세스가 운영체제의 서비스를 요청하기 위해 커널의 함수를 호출하는 것이다.
  • 사용자 프로세스가 직접 특권 명령을 수행할 수 없으므로 특권 명령을 수행하려 할 때, 시스템 콜을 사용한다.
시스템 콜이나 예외 상황은 모두 사용자 프로세스로부터 CPU의 제어권이 운영 체제에게 이양되어 처리되는데 이 과정에 인터럽트 라인을 세팅하여 인터럽트를 발생시킨 후 제어권이 넘어가게 되므로 이들도 넓은 의미에서는 인터럽트의 범주에 포함시킨다. 
단지 발생시키는 주체가 하드웨어 장치가 아닌 소프트웨어이므로 이들을 소프트웨어 인터럽트라고 부른다.

 

 

 

 

 

인터럽트 발생 처리 과정


A 프로그램이 CPU를 할당받고 명령을 수행하고 있는데 인터럽트가 발생하면 A는 현재 수행중인 명령의 위치를 저장해놓는다. 그 후, 운영 체제 내부 코드인 인터럽트 처리 루틴으로 넘어가서 인터럽트 처리를 하고 다시 돌아와 A의 이전 작업 지점부터 수행을 계속 이어나가게 된다.

 

그렇다면, 인터럽트가 발생했을 때 수행중이던 프로세스의 정보는 어디에 저장될까?

 

-> 진행 중이던 A 프로세스의 정보는 프로세스 제어 블록(PCB: Process Control Block)에 저장한다. 그리고 인터럽트 처리를 모두 마치면 프로그램 A의 PCB에 저장된 주소를 복원시켜 원래 수행하던 일을 재개하게 된다.

 

 

인터럽트 벡터 

  • 여러가지 인터럽트에 대해 해당 인터럽트 발생시 처리해야 할 루틴의 주소를 보관하고 있는 테이블.
  • 일종의 함수를 가리키는 포인터

 

인터럽트 핸들러

  • 실제 인터럽트를 처리하기 위한 루틴으로 인터럽트 서비스 루틴이라고도 한다.
  • 운영체제 코드 부분에는 각종 인터럽트 별로 처리해야 할 내용이 이미 프로그램되어 있으며, 이 부분을 인터럽트 서비스 루틴 또는 인터럽트 핸들러라고 한다.

 

PCB

  • 커널의 데이터 영역에 존재하며 각각의 프로세스마다 고유의 PCB가 있다.
  • 인터럽트 발생 시 프로세스의 어느 부분이 수행중이었는지를 저장한다.
    (수행중이던 memory 주소, 레지스터값, 하드웨어 상태 ...)

 

 

 


Reference.

link1 link2 link3 

Process Address Space
프로그램이 실행되면 메모리에 할당되는 것

 

 

프로세스는 CPU에 의해서 실행이 되고 memory에 저장이 된다.

프로그램이 실행되면 프로세스 주소 공간이 memory에 할당(생성)되는데, 할당 된 프로세스를 실행시키는 것은 CPU가 한다.

구성요소

Address Space안은 위 그림과 같이 Code, Data, Stack 부분으로 이루어져 있다.

 

1) Code(Text)

  • 우리가 작성한 소스코드가 들어 가는 부분. 즉, 실행할 프로그램의 코드가 저장되는 영역으로 텍스트(code)영역 이라고도 부른다.
  • 코드영역은 실행 파일을 구성하는 명령어들이 올라가는 메모리 영역으로 함수, 제어문, 상수 등이 여기에 지정된다.
  • 컴파일 타임에 결정되고 중간에 코드를 바꿀 수 없게 Read-Only 로 지정돼있다.

2) Data

  • 프로그램의 **전역 변수와 정적(static) 변수가 저장되는 영역**이다.즉, 프로그램이 구동되는 동안 항상 접근 가능한 변수가 저장되는 영역이다.
  • 전역변수, static 값을 참조한 코드는 컴파일 하고 나면 Data 영역의 주소값을 가르키도록 바뀐다.
  • 데이터 영역은 프로그램의 시작과 함께 할당되며, 프로그램이 종료되면 소멸한다.
  • 실행 중도에 전역변수가 변경 될 수도 있으니 이 영역은 Read-Write로 지정돼있다.

(상위 그림에서는 표현되어있지 않지만,) 초기화 된 데이터는 Data 영역에 저장되고,초기화 되지 않은 데이터는 BSS(Block Stated Symbol)영역에 저장된다.

Q.data영역과 bss 영역을 구분하는 이유는 무엇인가?
초기화되지 않은 변수는 프로그램이 실행될 때 영역만 잡아주면 되고 그 값을 프로그램에 저장하고 있을 필요는 없으나 초기화가 되는 변수는 그 값도 프로그램에 저장하고 있어야 하기 때문이다. 따라서 bss 영역 변수들이 많아져도 프로그램의 실행코드 사이즈를 늘리지 않는다.

 

3) Stack

  • 함수의 호출과 관계되는 지역 변수와 매개변수가 저장되는 영역이다.
  • Stack은 함수의 호출과 함께 할당되며, 함수의 호출이 완료되면 소멸한다.
  • 원시타입의 데이터가 값과 함께 할당된다.
  • Heap 영역에 생성된 Object 타입의 데이터 참조값이 할당된다.
  • 메모리의 높은 주소에서 낮은 주소의 방향으로 할당된다.
  • 컴파일 타임에 크기가 결정되기 때문에 무한히 할당 할 수 없다. 재귀함수가 너무 깊게 호출되거나 함수가 지역변수를 너무 많이 가지고 있어 stack 영역을 초과하면 stack overflow 에러가 발생한다.



Q. 왜 Code 부분을 따로 두었나?
Program의 Code는 Program이 만들어지고(컴파일되고) 나서는 바뀔 일이 전혀 없다. (따라서 Read Only)
그렇기 때문에 같은 프로그램을 실행시켜 몇 개의 Prcess가 실행되더라도 같은 프로그램이라면 Code 부분은 다 똑같은 내용을 가지고 있게 된다.
따라서 같은 Program의 Process일 경우 Code 부분을 공유(Share)하여 메모리 사용량을 줄이는 목적입니다.
Q. 왜 Stack 부분과 Data 부분을 나누었나? 
Stack 구조는 아래의 사진과 같이 이루어져 있다. (하단 부가 막혀있고 상단 부가 뚫려있는 구조)
따라서 한 쪽으로만 데이터를 집어 넣을 수 있고 꺼낼 때는 최근에 집어넣었던 것 부터 꺼낼 수 밖에 없는 구조 C언어를 예로 들면 함수의 호출이 stack 구조로 되어있다고 볼 수 있다.
전역변수는 어떤 함수에서도 접근할 수 있기 때문에 Data로 따로 관리해준다.

 

<stack 구조>

main 함수부터 실행되며 

처음 printf를 수행한 뒤 함수 func1 실행

함수 func1 실행 후 main 에서 다시 printf를 실행하고 함수 func2 실행

tunc2에서 printf를 수행하고 func3실행

 

이러한 stack 구조로 인해 data 부분과 stack 부분을 따로 나누어 둔 것이다.
전역 변수(global variables)는 어떤 함수에서도 접근 할 수 있기 때문에 Data로 따로 관리를 해주는 것

 

 


Reference.

link1 link2 link3

DNS란
Domain Name System


www.xxx.com 과 같이 사람이 읽을 수 있는 이름을
192.0.0.1 과 같은 숫자 IP주소로 변환하여
컴퓨터가 서로 통신할 수 있도록 도와주는 서버

 

  • DNS 시스템은 이름을 숫자로 매핑하여 전화번호 부와 같은 역할을 한다.
  • DNS 서버는 이름에 대한 요청을 IP 주소로 변환하여, 최종 사용자가 도메인 이름을 웹 브라우저에 입력할 때 해당 사용자를 어떤 서버에 연결할 것인지 제어한다. --> 이 요청을 쿼리라고 한다.

DNS

1. DNS Query
    DNS 서버에서 domain name을 이용하여 IP를 받아온다
2. IP Communication
    IP를 받아온 유저는 리퀘스트 메세지 발송을 통하여 정상적으로 네트워크 통신을 실시한다

 


 

DNS 동작원리

1. 사용자가 www.naver.com 을 브라우저에 입력한다.
2. Local DNS에게 IP 주소를 질의하여 캐시된 것에 없으면 다른 DNS 서버에 전달 (Root DNS)
3. ROOT 로 부터 com 도메인을 관리하는 TLD이름 서버 정보 전달 받는다.
4. COM DNS로 질의 한다.
5. naver.com DNS 정보를 전달 받는다.
6. www.naver.com 호스트네임에 대한 IP 주소를 질의 한다.
7. IP 정보를 전달받는다.
8. Local DNS는 www.nvaer.com에 대한 IP 주소를 캐싱을 하고 IP 주소 정보를 전달한다.

※ ROOT -> COM -> xxx.com 서버를 차례대로 질의해서 답을 찾는 과정을 Recursive Query라고 한다.

 

 


DNS Round Robin

round robin이란 DNS 서버 구성 방식 중 하나다.
Domain에 대한 IP요청 

 

원리

  • 웹 서비스를 담당할 여러 대의 웹 서버는 자신의 공인 IP를 각각 가지고 있다.
  • 사이트 접속을 위해 사용자가 해당 도메인 주소를 브라우저에 입력하면 DNS는 도메인의 정보를 조회하는데 이떄 IP주소를 여러 대의 서버 IP리스트 중에서 라운드 로빈 형태로 랜덤하게 하나 혹은 여러개를 선택하여 사용자에게 알려준다.
  • 결과적으로 웹 사이트에 접속하는 다수의 사용자는 실제로는 복수의 웹 서버에 나뉘어 접속하도 되면서 자연스럽게 서버의 부하가 분산되는 방식이다.
라운드 로빈 DNS는 여러개의 IP주소를 결과로 돌려준다.

사용자의 OS 애플리케이션에 따라 동작이 다르다.
여러개의 IP 중 제일먼저 조회된 IP를 선택, 무작위로 IP를 선택한다.
또는 선택 IP 접속이 안되면 그다음 조회된 IP접속하도록 호직을 추가할 수 있다.
  •  

 

 

단점

1. 서버의 수 만큼 공인 IP 주소가 필요합니다.
부하 분산을 위해 서버의 대수를 늘리기 위해서는 그 만큼의 공인 IP 가 필요합니다.

2. 균등하게 분산되지 않습니다.
모바일 사이트 등에서 문제가 될 수 있는데, 스마트폰의 접속은 캐리어 게이트웨이 라고 하는 프록시 서버를 경유 합니다.
프록시 서버에서는 이름변환 결과가 일정 시간 동안 캐싱되므로 같은 프록시 서버를 경유 하는 접속은 항상 같은 서버로 접속됩니다.
또한 PC 용 웹 브라우저도 DNS 질의 결과를 캐싱하기 때문에 균등하게 부하분산 되지 않습니다.
DNS 레코드의 TTL 값을 짧게 설정함으로써 어느 정도 해소가 되지만, TTL 에 따라 캐시를 해제하는 것은 아니므로 반드시 주의가 필요하다.

3. 서버가 다운되도 확인이 불가능합니다.
DNS 서버는 웹 서버의 부하나 접속 수 등의 상황에 따라 질의결과를 제어할 수 없다.
웹 서버의 부하가 높아서 응답이 느려지거나 접속수가 꽉 차서 접속을 처리할 수 없는 상황인 지를 전혀 감지할 수가 없기 때문에 어떤 원인으로 다운되더라도 이를 검출하지 못하고 유저들에게 제공됩니다.
이때문에 유저들은 간혹 다운된 서버로 연결이 되기도 하죠.
DNS 라운드 로빈은 어디까지나 부하분산 을 위한 방법이지 다중화 방법은 아니므로 다른 S/W 와 조합해서 관리할 필요가 있다.

 

 

해결법

다중화 구성 방식 (Synchronous Time-Division Multiplexing)
AP 서버에 VIP(Virtual IP)를 부여해서 다중화를 구성한다. 각 AP 서버를 Health Check후 이상이 감지되면 VIP를 정상 AP 서버로 인계하는 방식을 사용한다.
즉 DNS Server Table 에 실시간으로 AP 서버의 상태를 확인할 수 있는 칼럼 및 함수를 추가하여 요청될 경우 서버 상태를 확인하여 우회루트를 제공하거나 에러를 전송하는 방식을 말합니다.

가중치 편성 방식 (Weighted round robin)
각각의 웹 서버에 가중치를 가미해서 분산 비율을 변경한다. 물론 가중치가 큰 서버일수록 빈번하게 선택되므로 처리능력이 높은 서버는 가중치를 높게 설정하는 것이 좋다.


또 다른 방법으로는 로드 밸런서의 도입을 통하여 다음과 같은 구성도 가능

최소 연결 방식 (Least connection)
접속 클라이언트 수가 가장 적은 서버를 선택한다. 로드밸런서에서 실시간으로 connection 수를 관리하거나 각 서버에서 주기적으로 알려주는 것이 필요하다.


Reference.

link1 link2

#1 성능 데이터 모델링의 개요

1. 성능 데이터 모델링의 정의 

성능 저하 데이터 모델의 경우 

1. 데이터 모델 구조에 의해
2. 데이터가 대용량이 됨으로 인해
3. 인덱스 특성을 충분히 고려하지 않고 인덱스로 생성함으로 인해

 

 

성능 = 데이터 조회의 성능

 

 

2. 성능 데이터 모델링의 수행 시점

사전에 할수록 비용이 들지 않는다.

특히 분석/설계 단계에서 데이터 모델에 성능을 고려힌 데이터 모델링을 수행할 경우 비용 최소화의 기회를 갖는다.

데이터 증가가 빠를 수록 성능저하에 따른 성능개선비용은 기하급수적으로 증가하게 된다.

 

 

 

3. 성능 데이터 모델링 고려사항

1. 정규화를 정확하게 수행한다.
2. 용량 산정을 수행한다.
3. 데이터베이스에 발생되는 트랜잭션의 유형을 파악한다.
4. 용량과 트랜잭션의 유형에 따라 반정규화를 수행한다.
5. 이력모델의 조정, pk/fk 조정, 슈퍼타입/서브타입 조정 등을 수행한다.
6. 성능관점에서 데이터 모델을 검증한다. 

* 대량 데이터 처리가 되는 이력 모델에 대해 성능 고려를 하고 PK/FK의 순서가 인덱스 특성에 따라 성능 영향을 미치는 영향도가 크기 때문에 반드시 PK/FK를 성능이 우수한 순서대로 칼럼의 순서를 조정해야한다.

 

 

 

 

 


#2 정규화와 기능 

1. 정규화를 통한 성능 향상 전략

정규화 하는 것 - 중복성 제거, 관심사별로 처리가 되기 때문에 성능 향상의 특징을 갖는다.

 

입력, 수정. 삭제의 성능은 일반적인 반정규화된 테이블에 비해 처리 성능이 향상된다. 

조회 성능은 향상될 수도, 저하될 수도 있다.

* 데이터의 중복 속성을 제거하고 결정자에 의해 동일한 의미의 일반 속성이 하나의 테이블로 집약되므로 한 테이블의 데이터 용량이 최소화되는 효과가 있기 때문

 

정규화하여 조인이 발생하면 성능이 심각하게 저하되는가??? 아니다! case by case

 

 


반정규화 :

정규화된 엔터티, 속성, 관계에 대해 시스 템의 성능향상과 개발과 운영의 단순화를 위해 중복, 통합, 분리 등을 수행하는 데이터 모델링의 기법 일반적으로 정규화시 입력/수정/삭제 성능이 향상되 며 반정규화시 조인 성능이 향상된다.

 

 

 

반정규화 절차

1. 반정규화 대상조사(범위처리빈도수, 범위, 통계성)

2. 다른 방법유도 검토(뷰, 클러스터링, 인덱스 조정)

3. 반정규화 적용(테이블, 속성, 관계 반정규화)

 

 

 

반정규화 대상조사

1. 자주 사용되는 테이블에 접근하는 프로세스의 수가 많고 항상 일정한 범위만을 조회하는 경우

2. 테이블에 대량의 데이터가 있고 대량의 데이터 범 위를 자주 처리하는 경우에 처리범위를 일정하게 줄 이지 않으면 성능을 보장할 수 없는 경우

3. 통계성 프로세스에 의해 통계 정보를 필요로 할 때 별도의 통계테이블을 생성한다.

4. 테이블에 지나치게 많은 조인이 걸려 데이터를 조 회하는 작업이 기술적으로 어려울 경우

 

 

 

식별자 관계

주식별자 : 자식의 주식별자로 부모의 주식별자 상속

1. 부모로부터 받은 식별자를 자식엔터티의 주식별자 로 이용하는 경우 강한 연결관계 표현, 실선 표기

 

비식별자 : 부모 속성을 자식의 일반 속성으로 사용

1. 부모 없는 자식이 생성될 수 있는 경우

2. 부모와 자식의 생명주기가 다른 경우

3. 여러개의 엔터티가 하나의 엔터티로 통합되어 표현 되었는데 각각의 엔터티가 별도의 관계를 가진 경우

4. 자식엔터티에 별도의 주식별자를 생성하는 것이 더 유리한 경우

5. SQL 문장이 길어져 복잡성 증가되는 것 방지 약한 연결관계 표현, 점선 표

'🌈 > SQLD' 카테고리의 다른 글

[SQLD] 모델링이란 무엇인가  (0) 2021.08.23

모델링의 정의

사전적 뜻 
가설적 또는 일정 양식에 맞춘 표현
어떤 것에 대한 예비 표현으로 그로부터 최종 대상이 구축되도록 하는 계획으로서 기여하는 것 
  • 복잡한 '현실세계'를 단순화시켜 표현하는 것
  • 사물이나 사건에 관한 양상이나 관점을 연관된 사람이나 그룹을 위하여 명확하게 하는 것
  • 현실세계의 추상화된 반영

 

 

모델링의 특징 

추상화  단순화  명확화

 

모델링의 세가지 관점 

데이터 관점

업무가 어떤 데이터와 관련이 있는지, 혹은 데이터간의 관계는 무엇인지에 대해서 모델링하는 방법 

What, Data

 

 

프로세스 관점

업무가 실제하고 있는 일은 무엇인지, 혹은 무엇을 해야 하는지 모델링하는 방법

How, Process

 

 

데이터와 프로세스의 상관관점

업무가 처리하는 일의 방법에 따라 데이터는 어떻게 영향을 받고 있는지 모델링하는 방법

 

 


데이터 모델링

  • 정보 시스템을 구축하기 위한 데이터 관점의 업무 분석 기법
  • 현실 세계의 데이터에 대해 약속된 표기법에 의해 표현하는 과정
  • 데이터베이스를 구축하기 위한 분석/설계의 과정
데이터 모델이 제공하는 기능
- 시스템을 현재 또는 원하는 모습으로 가시화
- 시스템의 구조와 행동을 명세화
- 시스템을 구축하는 구조화된 틀 제공
- 시스템을 구축하는 과정에서 결정한 것을 문서화
- 다양한 영역에 집중하기 위해, 다른 영역의 세부 사항은 숨기는 다양한 관점 제공
- 특정 목표에 따라 구체화된 상세 수준의 표현 방법을 제공

 

 

 

데이터 모델링의 중요성 및 유의점

1. 파급효과

많은 애플리케이션들이 테스트를 수행하고 대규모의 데이터 이행을 성공적으로 수행하기 위한 많은 단위 테스트들이 수행되고 반복된다. 이런 시점에 데이터 모델의 변경이 불가피한 상황이 발생한다면...? 

데이터 구조의 변경에 따른 많은 영향 분석이 일어난다. 그 이후에 실제적 변경작업이 발생한다. 변경을 해야하는 데이터 모델의 형태에 따라서 그 영향 정도는 차이가 있겠지만 이 시기의 데이터 구조 변경으로 인한 작업은 전체 시스템 구축에 큰 위험 요소가 될 수 있다. 

이러한 이유로 인해 시스템 구축 작업 중 다른 어떤 설계 과정보다 데이터 설계가 중요하다 볼 수 있다.

 

2. 간결한 표현

데이터 모델은 구축할 시스템 정보 요구사항과 한계를 가장 명확하고 간결하게 표현할 수 있는 도구이다.

간결하게 그려져 있는 데이터 모델을 리뷰하면서 파악하는 것이 요구사항을 파악하는데 빠른 방법이라고 볼 수 있다. (데이터 모델은 설계 도면에 해당)

 

3. 데이터 품질

데이터베이스에 담겨있는 데이터는 기업의 중요 자산이다. 데이터의 기간이 오래되면 될수록 활용가치는 더 높아진다. 이렇게 오래도록 저장된 데이터가 정확성이 떨어지는 데이터라고 하면 상당한 문제가 될 것이다.

따라서 데이터 품질의 문제가 중요한데 주로 데이터 품질 문제가 야기되는 중대한 이유 중 하나가 바로 데이터 구조의 문제이다. 중복 데이터를 미정의하거나 정의의 불충분, 동일한 성격의 데이터를 통합하지 않고 분리하는 행위로 나타나는 데이터 불일치 등의 경우가 있다. 

데이터 모델링을 할 때 유의 점은 다음과 같다.

1. 중복 
데이터베이스가 여러 장소에 같은 정보를 저장하는 잘못을 하지 않도록 한다.

2. 비유연성
사소한 업무변화에도 데이터 모델이 수시로 변경되므로써 유지 보수의 어려움을 가중시킬 수 있다.
데이터 정의를 데이터의 사용 프로세스와 분리함으로써 중대한 변화를 일으킬 가능성을 줄인다.

3. 비일관성
예를 들어 신용 상태에 대한 갱신 없이 고객의 납부 이력 정보를 갱신하는 듯한 상황.
개발자가 다른 데이터와 모순된다는 고려 없이 일련의 데이터를 수정할 수 도 있다.
따라서 데이터 모델링시 데이터와 데이터 간의 상호 연관 관계에 대한 명확한 정의는 위험을 사전에 예방할 수 있다.

 

 

 

데이터 모델링의 3단계 진행

데이터 모델링 내용 수준
개념적 
데이터 모델링
추상화 수준이 높고 업무 중심적이고 포괄적인 수준의 모델링 진행
전사적 데이터 모델링, EA수립시 많이 사용
추상적
논리적 
데이터 모델링
시스템으로 구축하고자 하는 업무에 대해
key, 속성, 관계 등을 정확하게 표현, 재사용성 높음
중간
물리적
데이터 모델링
실제로 데이터베이스에 이식할 수 있도록
성능, 저장 등 물리적인 성격을 고려하여 설계
구체적

개념적 데이터 모델링

주요한 활동은 핵심 엔터티와 그들 간의 관계를 발견하고, 그것을 표현하기 위해서 엔터티-관계 다이어그램을 생성하는 것이다. 

* 엔터티-관계 다이어그램 : 조직과 다양한 데이터베이스 사용자에게 어떠한 데이터가 중요한지 나타내기 위해서 사용

* 데이터 모델링 과정이 전 조직에서 이루어진다 --> 전사적 데이터 모델

개념적 데이터 모델로 지원하는 중요한 기능 

1. 사용자와 시스템 개발자가 데이터 요구 사항을 발견하는 것을 지원

추상적이기 때문에 상위 문제에 대한 구조화를 쉽게 하여 사용자와 개발자가 시스템 기능에 대해 논의할 수 있는 기반을 생성한다.

2, 개념 데이터 모델은 현 시스템이 어떻게 변형 되어야 하는가를 이해하는데 유용

 

 

논리적 데이터 모델링

데이터 모델링 과정 중 가장 핵심이 되는, 비즈니스 정보의 논리적인 구조와 규칙을 명확하게 표현하는 기법 또는 과정

논리 데이터 모델은 데이터 모델링이 최종적으로 완료된 상태 -> 물리적 스키마 설계전 단계의 "데이터 모델" 상태

누가, 어떻게, 그리고 비즈니스 데이터에 존재하는 사실들을 인식하여 기록하는 것!

정규화

정규화는 논리 데이터 모델 상세화 과정의 대표적 활동으로, 일관성을 확보하고 중복을 제거해 적절한 엔티티에 속성을 배치함으로써 보다 신뢰성 있는 데이터 구조를 얻는데 목적이 있다.

 

 

물리적 데이터 모델링

논리 데이터 모델이 데이터 저장소로서 어떻게 컴퓨터 하드웨어에 표현될 것인가를 다룬다.

이 단계에선 테이블, 칼럼 등으로 표현되는 물리적인 저장 구조와 사용될 저장 장치, 자료를 추출하기 위해 사용될 접근 방법 등이 있다.

 

 

 

 

 

프로젝트 생명 주기에서 모델링

waterfall 기반 : 데이터 모델링의 위치가 분석과 설계 단계로 구분되어 명확하게 정의 가능

정보공학이나 구조적 방법론 : 분석단계에서 업무 중심의 논리적인 데이터 모델링을 수행, 설계 단계에서 하드웨어와 성능을 고려한 물리적인 데이터 모델링 수행

일반적으로는 계획,분석 단계에 개념적 데이터 모델링 / 분석 단계에서 논리적 데이터 / 모델링 설계 단계에서 물리적 데이터 모델링
단, 현실 프로젝트에선 개념적 데이터 모델이 생략된 개념/ 논리 데이터 모델링이 분석 단계 때 대부분 수행

 

'🌈 > SQLD' 카테고리의 다른 글

[SQLD] 성능 데이터 모델링  (0) 2021.08.25

+ Recent posts