CPU는 메모리에 저장된 명령어를 읽어 들이고, 해석하고, 실행하는 장치입니다.

CPU 내부에는 계산을 담당하는 ALU, 명령어를 읽어 들이고 해석하는 제어장치, 작은 임시 저장 장치인 레지스터라는 구성 요소가 있습니다.

이번글에서는 ALU와 제어장치에 대해서 구체적으로 다뤄보겠습니다.

 

ALU

이 그림은 ALU가 어떤 정보를 받아들이고 내보내는지를 표현한 그림입니다.

계산을 할 때 생각해봅시다. 1+2 을 연산하고 싶을때 1,2 피연산자가 필요하고 더하기라는 수행할 연산이 필요합니다.

ALU는 '계산하는 부품'입니다. 위 연산을 기억하며 그림을 보고 생각해 봅시다.

  • ALU는 레지스터를 통해 피연산자를 받아들입니다. ( 1,2 를 받아들이는 것과 같습니다.)
  • 제어장치로부터 수행할 연산을 알려주는 제어 신호를 받아들입니다.( 데이터 읽기, 쓰기 등..)
  • ALU는 레지스터와 제어장치로부터 받아들인 피연산자와 제어 신호로 산술연산, 논리 연산 등 다양한 연산을 수행

ALU는 연산된 결과를 바로 메모리에 저장하지 않고 일시적으로 레지스터에 저장합니다.

그 이유는 CPU가 메모리에 접근하는 속도는 레지스터에 접근하는 속도보다 훨씬 느립니다( 메모리 접근 속도 < 레지스터 접근 속도 )

레지스터는 CPU내부에 있기 때문입니다.

ALU가 연산할 때마다 결과를 메모리에 저장하게 된다면 CPU가 프로그램 실행 속도를 늦출 수 있습니다.

 

플래그

마지막으로 계산 결괏값 외에 ALU가 내보내는 또 다른 정보로 플래그를 내보냅니다.

플래그는 이진수가 양수인지 음수인지 판단하기 어렵기 때문에 플래그를 사용하곤 합니다.

이처럼 때때로 ALU는 결괏값뿐만 아니라 연산 결과에 대한 추가적인 정보를 내보내야 할 때가 있습니다.

예시는 다음과 같습니다.

  • 연산 결과가 음수일때 ALU는 방금 계산한 결과가 음수라는 추가 정보를 내보냅니다.
  • 연산 결과가 연산 결과를 담을 레지스터보다 클 때 ALU는 결과값이 너무 크다라는 추가 정보를 내보냅니다.

다시 말하면 플래그연산 결과에 대한 추가적인 상태정보 입니다. 플래그 종류는 여러가지가 있습니다.

또한 플래그들은 플래그 레지스터라는 레지스터에 저장됩니다.

플래그 종류 의미 사용 예시
부호 플래그 연산한 결과의 부호를 나타낸다 부호 플래그 1 : 계산 결과는 음수
부호 플래그 0 : 계산 결과는 양수
제로 플래그 연산 결과가 0인지 여부를 나타낸다 제로 플래그 1 : 연산 결과는 0
제로 플래그 0 : 연산 결과는 0이 아님을 의미
캐리 플래그 연산 결과 올림수나 빌림수가 발생했는지를 나타낸다. 캐리 플래그 1 : 올림수나 빌림수가 발생했음을 의미
캐리 플래그 0 : 발생하지 않았음을 의미
오버플로우 플래그 오버플로우가 발생했는지를 나타낸다 오버플로우 플래그 1 : 오버플로우가 발생했음을 의미
오버플로우 플래그 0 : 발생하지 않았음을 의미한다.
인터럽트 플래그 인터럽트가 가능한지를 나타낸다.  인터럽트 플래그 1 : 인터럽트가 가능함을 의미
인터럽트 플래그 0 : 인터럽트가 불가능함을 의미한다.
슈퍼바이저 플래그 커널 모드로 실행 중인지, 사용자 모드로 실행 중인지를 나타낸다. 슈퍼바이저 플래그 1 : 커널 모드로 실행 중임을 의미
슈퍼바이저 플래그 0 : 사용자 모드로 실행 중임을 의미한다.

 

부호 플래그

연산한 결과의 부호를 나타낸다.

  • 부호 플래그 1 : 계산 결과는 음수
  • 부호 플래그 0 : 계산 결과는 양수

제어장치

제어장치는 제어 신호를 내보내고, 명령어를 해석하는 부품입니다.

그리고 제어 신호는 컴퓨터 부품들을 관리하고 작동시키기 위한 일종의 전기 신호입니다.

 

1. 제어장치는 클럭 신호를 받아들입니다.

클럭(clock)

컴퓨터의 모든 부품을 일사불란하게 움직일 수 있게 하는 시간 단위입니다.

클럭의 "똑-딱-똑-딱" 주기에 맞춰 한 레지스터에서 다른 레지스터로 데이터가 이동되거나, ALU에서 연산이 수행되거나, CPU가 메모리에 저장된 명령어를 읽어 들이는 것입니다.

 

하지만 주의해야합니다. 컴퓨터의 모든 부품이 한 클럭마다 작동한다라고 이해하면 안됩니다.

컴퓨터 부품들은 클럭이라는 박자에 맞춰 작동할 뿐이지 한 박자마자 작동하는 것은 아닙니다.

다음 그림은 하나의 명령어가 여러 클럭에 걸쳐 실행되고 있습니다.

 

2. 제어장치는 '해석해야 할 명령어'를 받아들입니다.

CPU가 해석해야 할 명령어는 명령어 레지스터라는 특별한 레지스터에 저장됩니다.

제어장치는 이 명령어 레지스터로부터 해석할 명령어를 받아들이고 해석한 뒤, 제어 신호를 발생시켜 컴퓨터 부품들에 수행해야 할 내용을 알려줍니다.

 

3. 제어장치는 플래그 레지스터 속 플래그 값을 받아들입니다.

플래그는 ALU연산에 대한 추가적인 상태 정보라고 했습니다.

제어장치게 제어 신호를 통해 컴퓨터 부품들을 제어할 때 이 중요한 상태 정보를 무시하면 안되겠죠?

제어장치는 이 플래그 값을 받아들이고 이를 참고하여 제어 신호를 발생시킵니다.

 

4. 제어장치는 시스템 버스, 그 중에서 제어 버스로 전달된 제어 신호를 받아들입니다.

제어 신호는 CPU뿐만 아니라 입출력 장치를 비롯한 CPU 외부 장치도 발생시킬 수 있습니다.

제어장치는 제어 버스를 통해 외부로부터 전달된 제어 신호를 받아들이기도 합니다.

 

다시 정리 해봅시다.

제어신호는 다음과 같은 정보들을 받아들입니다.

  • 클럭 신호를 받아들입니다.
  • '해석해야 할 명령어'를 받아들입니다.
  • 플래그 레지스터 속 플래그 값을 받아들입니다.
  • 시스템 버스 중 제어 버스로 전달된 제어 신호를 받아들입니다.

제어장치가 내보내는 정보

  • CPU 외부에 전달하는 제어 신호
    • 제어 버스로 제어신호를 보내는 것입니다.
    • 예시로 메모리에 전달하는 제어신호 / 입출력장치로 전달하는 제어신호가 있습니다.
  • CPU 내부에 전달하는 제어 신호 
    • ALU에 수행할 연산을 지시하기 위해 ALU에 전달하는 제어신호
    • 레지스터 간에 데이터를 이동시키거나 레지스터에 저장된 명령어를 해석하기 위해 레지스터에 전달하는 제어신호

 

 

 

'CS > 컴퓨터 구조' 카테고리의 다른 글

명령어의 구조  (0) 2024.01.17
컴퓨터의 4가지 핵심 부품  (0) 2023.12.05

누군가에게 명령할 때 어떻게 우리는 말할까요?

"학생들, 다음주까지 과제를 제출해주세요"

"멍멍아, 이거 물어와!" 와 같이 말합니다.

 

연산 코드와 오퍼랜드

 

"멍멍아, 이거 물어와" 명령을 내릴때 다음과 같은 구조를 가지고 있습니다.

무엇을 대상으로, 어떤 작동을 수행하라의 구조로 되어있습니다.

 

컴퓨터 속 명령어도 이와 같습니다.

더해라(작동) 100과 120을

 

빼라(작동) 메모리 32번지 안의 값과 메모리 33번지 안의 값

빨간색 글씨는 명령의 '작동' -> '연산' 을 담고 있으며

나머지 필드는 '연산에 사용할 데이터' or '연산에 사용할 데이터가 저장된 위치' 를 담고 있습니다.

 

명령어 = 연선코드 + 오퍼랜드

연사코드(operation code ) : '더해라', '빼라' 와 같은 명령어가 수행할 연산

오퍼랜드(operand) : '100과' '120을' / '메모리 32번지 안의 값과' '메모리 33번지 안의 값' -> '연산에 사용할 데이터' / '연산에 사용할 데이터가 저장된 위치' 

연산코드 = 연산자, 오퍼랜드 = 피연산자 

 


오퍼랜드(operand)

다시 짚고 넘어가겠습니다. 오퍼랜드는 '연산에 사용할 데이터' 또는 '연산에 사용할 데이터가 저장된 위치'를 의미합니다.

오퍼랜드 필드에는 무엇이 들어갈 수 있을까요?

  • 숫자와 문자 등을 나타내는 데이터 또는 메모리나 레지스터 주소가 올 수 있습니다.
  • 오퍼랜드 필드에는 숫자나 문자와 같이 연산에 사용할 데이터를 직접 명시하기 보다
    • 연산에 사용할 데이터가 저장된 위치 -> 메모리 주소 or 레지스터 이름이 담깁니다. 오퍼랜드 필드를 주소필드라고 부르기도 합니다.
  • 오퍼랜드 필드에는 명렁어가 없을 수 있고, 하나만 있을 수 있고, 두 개 또는 여러개가 있을 수 있습니다.
    • 0-주소 명령어: 오퍼랜드가 하나도 없는 명령어
    • 1-주소 명령어: 오퍼랜드가 하나인 명령어
    • 2-주소 명령어: 오퍼랜드가 두 개인 명령어로 가장 많이 사용하는 형식입니다.
      • 범용 레지스터 구조의 컴퓨터에 사용
      • 각 주소부는 레지스터나 주기억 장치의 주소를 지정합니다.
      • 연산 후 입력 자료의 보존이 필요 없으면 연산 결과를 두 개의 입력 자료가 기억되어 있던 곳들 중 한 레지스터에 기억시키는 방식입니다.
    • 3-주소 명령어: 오퍼랜드가 세 개인 명령어

 

 


연산 코드

연산코드는 명령어가 수행할 연산을 의미합니다. '더해라' '빼라' '저장해라'에 해당하는 부분이 연산코드입니다.

연산코드는 네 가지로 나눌 수 있습니다.

  • 데이터 전송
  • 산술/논리 연산
  • 제어 흐름 변경
  • 입출력 제어

데이터 전송

  • MOVE : 데이터를 옮겨라
  • STORE : 메모리에 저장하라
  • LOAD(FETCH) : 메모리에서 CPU로 데이터를 가져와라
  • PUSH : 스택에 데이터를 저장하라
  • POP : 스택의 최상단 데이터를 가져와라

 

산술/논리 연산

  • ADD / SUBTRACT / MULTIPLY / DIVIDE : 덧셈 / 뺄셈 / 곱셈 / 나눗셈을 수행해라
  • INCREMENT / DECREMENT : 오퍼랜드에 1을 더하라 / 오퍼랜드에 1을 빼라
  • AND / OR / NOT : AND / OR / NOT 연산을 수행하라
  • COMPARE : 두 개의 숫자 또는 TRUE / FALSE 값을 비교해라

 

제어 흐름 변경

  • JUMP : 특정 주소로 실행 순서를 옮겨라 ( ex. JUMP 120 : 120으로 특정 메모리 주소로 건너뛰어 실행 )
  • CONDITIONAL JUMP : 조건에 부합할 때 특정 주소로 실행 순서를 옮겨라
  • HALT : 프로그램의 실행을 멈춰라
  • CALL : 되돌아올 주소를 저장한 채 특정 주소로 실행 순서를 옮겨라
  • RETURN : CALL을 호출할 때 저장했던 주소로 돌아가라

* CALL과 RETURN은 함수를 호출하고 리턴하는 명령어입니다.

 

입출력 제어

  • READ(INPUT) : 특정 입출력 장치로부터 데이터를 읽어라
  • WRITE(OUTPUT) : 특정 입출력 장치로 데이터를 써라
  • START IO : 입출력 장치를 시작하라
  • TEST IO : 입출력 장치의 상태를 확인하라

주소 지정 방식

앞선 글에서 오퍼랜드에는 메모리나 레지스터의 주소를 담는 경우가 더 많다고 했습니다. 그래서 오퍼랜드 필드를 주소 필드라고 부릅니다.

왜 바로 담으면 되는데 주소를 담는걸까요?

 

이는 명령어의 길이 때문입니다. 

하나의 명령어가 n비트로 구성되어 있고, 그 중 연산 코드 필드가 m비트라고 가정한다.

이때 오퍼랜드 필드에 가장 많은 공간을 할당할 수 있는 1-주소 명령어라 할지라도 오퍼랜드 필드의 길이는 연산 코드만큼의 길이를 뺀 n-m비트가 됩니다.

2-주소 명령어, 3-주소 명령어라면 오퍼랜드 필드의 크키가 더욱 작아지는 것이다.

 

명렁어의 크키가 16비트, 연산 코드 필드가 4비트인 2-주소 명령어에서는 오퍼랜드 필드당 6비트 정도밖에 남지 않게 되는 것이다.

즉, 하나의 오프랜드 필드로 표현할 수 있는 정보의 가짓수는 2^6개 밖에 되지 않습니다.

 

하지만 오퍼랜드 필드 안에 메모리 주소가 담긴다면 표현할 수 있는 데이터의 크기는 하나의 메모리 주소에 저장할 수 있는 공간만큼 커집니다.

예를 들어 한 주소에 16비트를 저장할 수 있는 메모리가 있다고 가정해봅시다.

이 메모리 안에 데이터를 저장하고, 오퍼랜드 필드 안에 해당 메모리 주소를 명시한다면 표현할 수 있는 정보의 가짓수는 2^16으로 커지게 됩니다.

레지스터 이름을 명시할때도 마찬가지입니다. 이 경우 표현할 수 있는 정보의 가짓수는 해당 레지스터가 저장할 수 있는 공간만큼 커집니다.

 

연산에 사용할 데이터가 저장된 위치, 즉 연산의 대상이 되는 데이터가 저장된 위치를 유효주소(effective address)라고 합니다. 첫 번째 그림의 경우 유효 주소는 200번지, 두 번째 그림의 유효 주소는 레지스터 R이 되는 것입니다.

 

이렇듯 오퍼랜드 필드가 데이터가 저장된 위치를 명시할 때 연산에 사용할 데이터 위치를 찾는 방법을 주소 지정 방식(addressing mode)이라고 합니다.

주소 지정 방식은 유효 주소를 찾는 방법입니다.

주소지정방식에 대표적으로 다섯가지가 있습니다.

 

1. 즉시 주소 지정 방식(immediate addressing mode)

  • 가장 간단한 형태의 주소 지정 방식
  • 연산에 사용할 데이터를 오퍼랜드 필드에 직접 명시하는 방식입니다.
  • 단점 : 데이터의 크기가 작아집니다.
  • 장점 : 연산에 사용할 데이터를 메모리나 레지스터로부터 찾는 과정이 없기 때문에 이하 설명할 주소 지정 방식들보다 빠릅니다.

2. 직접 주소 방식(direct addressing mode)

  • 오퍼랜드 필드에 유효 주소를 직접적으로 명시하는 방식
  • 즉시 주소 지정 방식보다 데이터 크기는 커졌지만
  • 유효 주소를 표현할 수 있는 범위가 연산 코드의 비트 수만큼 줄어들었습니다.
    • 표현할 수 있는 오퍼랜드 필드의 길이가 연산 코드의 길이만큼 짧아져 표현할 수 있는 유효 주소에 제한이 생길 수 있습니다.

3. 간접 주소 지정 방식(indirect addressing mode)

  • 유효 주소를 오퍼랜드 필드에 명시
  • 직접 주소 지정 방식보다 표현할 수 있는 유효 주소의 범위가 넓어집니다.
  • 두 번의 메모리 접근이 필요하기 때문에 앞서 설명한 주소 지정 방식들보다 일반적으로 느린 방식입니다.
  • 때때로 연산에 사용할 데이터가 레지스터에 저장된 경우도 있습니다. 이 경우 레지스터 주소 지정 방식 or 레지스터 간접 주소 지정 방식을 사용할 수 있습니다.

4. 레지스터 주소 지정 방식(register addressing mode)

  • 직접 주소 지정 방식과 비슷하게 연산에 사용할 데이터를 저장한 레지스터를 오퍼랜드 필드에 직접 명시하는 방법입니다.
  • 일반적으로 CPU 외부에 있는 메모리에 접근하는 것보다 CPU 내부에 있는 레지스터에 접근하는 것이 빠릅니다.
  • 직접 주소 지정 방식보다 빠르게 데이터에 접근할 수 있습니다.
  • 다만, 레지스터 주소 지정 방식은 직접 주소 지정 방식과 비슷한 문제를 공유합니다.
  • 표현할 수 있는 레지스터 크기에 제한이 생길 수 있습니다.

5. 레지스터 간접 주소 지정 방식(register indirect addressing mode)

  • 연산에 사용할 데이터를 메모리에 저장하고, 그 주소(유효 주소)를 저장한 레지스터를 오퍼랜드 필드에 명시하는 방법입니다.
  • 유효 주소를 찾는 과정이 간접 주소 지정 방식과 비슷하지만, 메모리에 접근하는 횟수가 한 번으로 줄어든다는 차이이자 장점이 있습니다.
  • 메모리에 접근하는 것이 레지스터에 접근하는 것보다 더 느립니다. 따라서 레지스터 간접 주소 지정 방식은 간접 주소 지정 방식보다 빠릅니다.

정리

주소 지정 방식 : 연산에 필요한 데이터를 찾는 방법

유효 주소 : 연산에 사용할 데이터가 저장된 위치

  • 즉시 주소 지정 방식 : 연산에 사용할 데이터
  • 직접 주소 지정 방식 : 유효 주소(메모리 주소)
  • 간접 주소 지정 방식 : 유효 주소의 주소
  • 레지스터 주소 지정 방식 : 유효 주소(레지스터 이름)
  • 레지스터 간접 주소 지정 방식 : 유효 주소를 저장한 레지스터

'CS > 컴퓨터 구조' 카테고리의 다른 글

ALU와 제어장치  (0) 2024.01.18
컴퓨터의 4가지 핵심 부품  (0) 2023.12.05
쿠키, 세션의 개념과 차이를 설명해보세요
쿠키와 세션은 HTTP의 특성인 비연결성과 무상태의 특징으로 인한 약점을 보완하기 위해 쿠키와 세션을 사용합니다. 만약 쿠키와 세션을 사용하지 않는다면 물건을 구입하려 할 때 계속 로그인을 해야하는 문제가 발생할 수 있습니다. 쿠키와 세션이 있다면 로그인한 뒤 사용자에 대한 인증을 유지하게 됩니다. 쿠키는 클라이언트(브라우저)에 저장되어 키와 값이 들어있는 작은 데이터 파일입니다. 사용자 인증에 대한 유효시간을 설정할 수 있으며 브라우저가 종료되어도 인증이 유지된다는 특징이 있습니다. 쿠키의 장점으로는 기존 로그인 정보가 사용되기 때문에 인증을 위한 추가적인 데이터 저장이 필요합니다. 또한 서버가 아닌 클라이언트에 위치하기 때문에 속도가 세션에 비해서 빠릅니다. 하지만 보안상으로 취약한 단점이 있습니다. 사용자의 주요 정보를 매번 요청에 담기 때문에 쿠키 정보를 쉽게 변경 삭제가 가능하고 가로채기 당할 수 있습니다. 또한 쿠키 사이즈가 커질수록 네트워크 부하가 심해집니다. 쿠키는 쇼핑몰의 장바구니 기능이나 자동로그인 팝업 다시보지 않음 체크 등에 이용되고 있습니다. 세션은 쿠키를 기반하고 있지만 서버 측에서 관리하고 있습니다. 서버에서는 클라이언트를 구분하기 위해 세션 ID를 부여하여 웹 브라우저가 서버에 접속해서 브라우저를 종료할때까지 인증상태를 유지합니다. 접속 시간에 제한을 두어 일정시간 응답이 없다면 정보가 유지되지 않게 설정이 가능합니다. 사용자에 대한 정보를 서버에 두기때문에 쿠키보다 보안에 좋지만 사용자가 많아질수록 서버 메모리를 많이 차지하게 됩니다. 서버에 과부하를 주는 원인이 될 수 있습니다. 세션은 주로 로그인에서 사용됩니다.
 

SpringSecurity와 인증, 인가, JWT의 구조, 동작 과정

Spring Security의 구조와 JWT 발급 과정에 대해 설명해주실 수 있을까요? Spring Security란? 스프링 시큐리티는 인증(Authentication), 인가(Authorize) 부여 및 보호 기능을 제공하는 프레임워크이다. 인증(Authen

jung-mmmmin.tistory.com

앞선 spring security, jwt에서 쿠키와 세션에 대해 알아본적 있는데 쿠키와 세션을 좀 더 자세히 알아보고자 한다.

 

HTTP의 특징

Http 프로토콜은 두가지 특성을 가지고 있는데 비연결성(Connectionless)무상태(Stateless)로 이루어져있습니다.

 

비연결성(Connectionless)

  • 서버와 클라이언트가 연결되어있지 않습니다.
  • 그 이유는 리소스를 절약하기 위해서이고, 만약 서버와 클라이언트가 실제로 계속 연결이 되어있다면 서버의 비용이 기하급수적으로 늘어나기 때문에 비연결성을 유지합니다.
  • 그래서 리소스를 절약하기 위해 서버는 실제로 하나의 요청에 하나의 응답을 내리고 연결을 끊어버리고 있다고 생각하면 됩니다.

무상태(Stateless)

  • 서버가 클라이언트의 상태를 저장하지 않는다는 것입니다.
  • 연결을 끊는 순간 클라이언트와 서버의 통신이 끝나며 상태 정보는 유지하지 않는 특성이 있습니다.
  • 기존의 상태를 저장하는 것들도 마찬가지로 서버의 비용과 부담을 증가시키는 것이기 때문에 기존의 상태가 없다고 가정하는 프로토콜을 이용해 구현되어 있습니다.
  • 실제로 서버는 클라이언트가 직전에 혹은 그 전에 어떠한 요청을 보냈는지 관심도 없고 전혀 알지 못합니다.

쿠키와 세션을 사용하는 이유

그렇기 때문에 HTTP의 특성 때문에 약점을 보완하기 위해 쿠키 또는 세션을 사용합니다.

만약 쿠키와 세션이 없다면 다음과 같은 상황이 생길 수 있습니다.

 

쇼핑몰에서 옷을 구매하려고 로그인을 했음에도, 페이지를 이동할 때마다 계속 로그인을 해야 합니다.

하지만 쿠키와 세션을 사용했을 경우, 한 번 로그인을 하면 어떠한 방식에 의해서 그 사용자에 대한 인증을 유지하게 됩니다.

 

쿠키(Cookie)

쿠키란?

  • 쿠키는 클라이언트(브라우저) 로컬에 저장되는 키와 값이 들어있는 작은 데이터 파일입니다.
  • 사용자 인증이 유효한 시간을 명시할 수 있으며, 유효 시간이 정해지면 브라우저가 종료되어도 인증이 유지된다는 특징이 있습니다.
  • 쿠키는 클라이언트의 상태 정보를 로컬에 저장했다가 참조합니다.
  • 클라이언트에 300개까지 쿠키 저장 가능, 하나의 도메인당 20개의 값만 가질 수 있습ㄴ비다. 하나의 쿠키값은 4KB까지 저장가능합니다.
  • Response Header에 Set-Cookie 속성을 사용하면 클라이언트에 쿠키를 만들 수 있습니다.
  • 쿠키는 사용자가 따로 요청하지 않아도 브라우저가 Request시에 Request Header를 넣어서 자동으로 서버에 저장합니다.

쿠키의 장점

  • 기존 로그인 정보를 사용하기 때문에 인증을 위한 추가적인 데이터 저장이 필요합니다.
  • 쿠키는 서버가 아닌 클라이언트 웹 브라우저에 위치한다.

쿠키의 단점

  • 사용자의 주요 정보를 매번 요청에 담기 때문에 보안상 문제가 있다.
  • 클라이언트에서 쿠키 정보를 쉽게 변경, 삭제할 수 있고 가로채기 당할 수 있다.
  • 쿠키 사이즈가 커질수록 네트워크 부하가 심해진다.

쿠키의 구성요소

  • Name(이름) : 쿠키를 구별하는데 사용되는 키(중복불가)
  • Value(값) : 쿠키의 값
  • Domain(도메인) : 쿠키가 저장된 도메인
  • Path(경로) : 쿠키가 사용되는 경로
  • Expires(만료기한) : 쿠키의 만료기한

쿠키의 동작 방식

  • 클라이언트가 페이지를 요청
  • 서버에서 쿠키를 생성
  • HTTP 헤더에 쿠키를 포함시켜 응답
  • 브라우저가 종료되어도 쿠키 만료 기간이 있다면 클라이언트에서 보관하고 있음
  • 같은 요청을 할 경우 HTTP 헤더에 쿠키를 함께 보냄
  • 서버에서 쿠키를 읽어 이전 상태 정보를 변경 할 필요가 있을 때 쿠키를 업데이트 하여 변경된 쿠키를 HTTP 헤더에 포함시켜 응답

로그인 시 쿠키 인증 방식

서버가 '특정 유저가 로그인 되었다'는 상태를 저장하는 방식 인증과 관련된 아주 약간의 정보만 서버에 가지게 됩니다.

인증과 관련된 최소한의 정보만 저장해서 로그인을 유지시킨다는 개념입니다.

  • 사용자가 로그인 요청을 보냅니다.
  • 서버는 DB의 유저 테이블을 뒤져서 아이디 비밀번호를 대조하여 사용자를 확인
  • 사용자가 로그인을 하면, 서버는 ID, PW 정보를 쿠키에 담아 브라우저로 다시 보냅니다.
  • 이후 브라우저가 요청할때마다 로그인 정보가 담긴 쿠키를 함께 서버로 보냅니다. 브라우저에서 매번 요청할때마다 서버 입장에서는 로그인 정보가 담긴 쿠키를 받게 됩니다.

쿠키 사용의 예

  • 방문 사이트에서 로그인 시, "아이디와 비밀번호를 저장하시겠습니까?"
  • 쇼핑몰의 장바구니 기능
  • 자동로그인, 팝업에서 "오늘 더 이상 이 창을 보지 않음" 체크

세션(Session)

세션이란?

  • 세션은 쿠키를 기반하고 있지만, 사용자 정보 파일을 브라우저에 저장하는 쿠키와 달리 세션은 서버 측에서 관리합니다.
  • 서버에서는 클라이언트를 구분하기 위해 세션 ID를 부여하며 웹 브라우저가 서버에 접속해서 브라우저를 종료할때까지 인증상태를 유지합니다.
  • 물론 접속 시간에 제한을 두어 일정시간 응답이 없다면 정보가 유지되지 않게 설정이 가능합니다.
  • 사용자에 대한 정보를 서버에 두기 때문에 쿠키보다 보안에 좋지만, 사용자가 많아질수록 서버 메모리를 많이 차지하게 됩니다.
  • 즉 동접자 수가 많은 웹사이트인 경우 서버에 과부하를 주게 되므로 성능 저하의 요인이 됩니다.
  • 클라이언트가 Request를 보내면, 해당 서버의 엔진이 클라이언트에게 유일한 ID를 부여하는데 이것이 세션 ID입니다.

세션의 동작 방식

  • 클라이언트가 서버에 접속 시 세션 ID를 발급 받음
  • 클라이언트는 세션 ID에 대해 쿠키를 사용해서 저장하고 가지고 있음
  • 클라이언트는 서버에 요청할 때, 이 쿠키의 세션 ID를 같이 서버에 전달해서 요청
  • 서버는 세션 ID를 전달 받아서 별다른 작업없이 세션 ID로 세션에 있는 클라이언트 정보를 가져와서 사용
  • 클라이언트 정보를 가지고 서버 요청을 처리하여 클라이언트에게 응답

세션의 특징

  • 각 클라이언트에게 고유 ID를 부여한다.
  • 세션 ID로 클라이언트를 구분해서 클라이언트의 요구에 맞는 서비스를 제공
  • 보안면에서 쿠키보다 우수
  • 사용자가 많아질수록 서버 메모리를 많이 차지하게 됨

세션의 사용 예

  • 로그인 같이 보안상 중요한 작업을 수행할 때 사용

쿠키와 세션의 차이

  • 쿠키와 세션은 비슷한 역할을 하며, 동작원리도 비슷합니다. 그 이유는 세션도 결국 쿠키를 사용하기 때문입니다.
  • 가장 큰 차이점은 사용자의 정보가 저장되는 위치입니다.
    • 쿠키는 서버의 자원을 전혀 사용하지 않으며
    • 세션은 서버의 자원을 사용합니다.
  • 보안 면에서 세션이 더 우수하며, 요청 속도는 쿠키가 세션보다 더 빠릅니다. 그 이유는 세션은 서버의 처리가 필요하기 때문입니다.
  • 보안, 쿠키는 클라이언트 로컬에 저장되기 때문에 변질되거나 request에서 스니핑 당할 우려가 있어서 보안에 취약하지만 세션은 쿠키를 이용해서 sessionid만 저장하고 그것으로 구분해서 서버에서 처리하기 때문에 비교적 보안성이 좋습니다.
  • 라이프 사이클, 쿠키도 만료시간이 있지만 파일로 저장되기 때문에 브라우저를 종료해도 계속해서 정보가 남아 있을 수 있습니다. 또한 만료기간을 넉넉하게 잡아두면 쿠키삭제를 할 때까지 유지될 수도 있습니다.
  • 반면에 세션도 만료시간을 정할 수 있지만 브라우저가 종료되면 만료시간에 상관없이 삭제됩니다. 예를 들어, 크롬에서 다른 탭을 사용해도 세션이 공유됩니다. 다른 브라우저를 사용하게 되면 다른 세션을 사용할 수 있습니다.
  • 속도, 쿠키에 정보가 있기 때문에 서버에 요청시 속도가 빠르고 세션은 서버에 있기 때문에 처리가 요구되어 비교적 느린 속도를 가집니다.

표로 다시 정리를 해보겠습니다.

  쿠키(Cookie) 세션(Session)
  클라이언트에 저장될 목적으로 생성한 작은 정보를 담은 파일 서버에 일정시간 동안 클라이언트 상태를 유지하기 위해 사용
저장 위치 클라이언트(웹 브라우저) 웹 서버
요청 속도 쿠키가 더 빠름 세션은 서버의 처리가 필요하기 때문에 쿠키보다 느림
보안 취약
(클라이언트에서 쿠키 정보를 쉽게 변경, 삭제 및 가로채기 당할 수 있음)
비교적 안전
(서버에 저장되기 때문에 상대적으로 안전)
만료시점 쿠키 저장 시 만료일시 설정 가능
(브라우저 종료시도 유지 가능)
다음 조건 중 하나가 만족될 경우 만료됨
1. 브라우저 종료 시까지
2. 클라이언트 로그아웃시까지
3. 서버에 설정한 유지시간까지 해당 클라이언트의 재요청이 없는 경우
용량 제한 브라우저 별로 다름(크롬 기준)
- 하나의 도메인 당 180개
- 하나의 쿠키당 4KB(= 4096byte)
개수 제한 없음
(단, 세션 저장소 크키 이상 저장 불가능)
사용 예 - 방문 사이트에서 로그인 시, "아이디와 비밀번호를 저장하시겠습니까?"
- 쇼핑몰의 장바구니 기능
- 자동로그인, 팝업에서 "오늘 더 이상 이 창을 보지 않음" 체크, 쇼핑몰의 장바구니
- 로그인 같이 보안상 중요한 작업을 수행할 때 사용

세션이 아닌 쿠키를 사용하는 이유

세션의 서버의 자원을 사용하기 때문에 무분별하게 만들다보면 서버의 메모리가 감당할 수 없어질 수가 있고 속도가 느려질 수 있기 때문에 쿠키가 유리한 경우가 있다.

 

쿠키/세션은 다릅니다.

  • 캐시는 이미지나 css, js파일 등을 브라우저나 서버 앞 단에 저장해놓고 사용하는 것입니다.
  • 한 번 캐시가 저장되면 브라우저를 참고하기 때문에 서버에서 변경이 되어도 사용자는 변경되지 않게 보일 수 있는데 이런 부분을 캐시를 지워주거나 서버에서 클라이언트로 응답을 보낼 때 header에 캐시 만료시간을 명시하는 방법등을 이용할 수 있습니다.
  • 라이프사이클이 다릅니다.
    • 쿠키 : 만료시간에 따라 브라우저를 종료해도 계속해서 남아있을 수 있습니다.
    • 세션 : 만료시간을 정할 수 있지만 브라우저가 종료되면 만료시간에 상관없이 삭제됩니다.

 

'CS' 카테고리의 다른 글

CORS(Cross Origin Resource Sharing)  (1) 2024.01.02
NoSQL과 RDBMS의 특징과 장단점  (0) 2024.01.01
기본키(Primary Key), 외래키(Foreign Key)  (1) 2024.01.01
HTTP Method  (1) 2024.01.01
N+1문제의 발생이유와 해결방법  (0) 2023.12.27
CORS(Cross Origin Resource Sharing)에 대해 설명해주세요.
CORS란 교차 출처 리소스 공유로 추가 HTTP 헤더를 사용하여, 한 Origin에서 실행 중인 웹 어플리케이션이 다른 Origin의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에서 알려주는 체제입니다. 웹어플리케이션은 리소스가 자신의 Origin과 다를 때 COR HTTP 요청을 실행합니다. CORS는 HTTP요청을 보낼때 요청 헤더에 Origin 담아 보냅니다. 서버는 응답해더에 Access-Control-Allow-Origin을 담아 클라이언트로 전달합니다. 이때 Origin을 비교하는 로직은 브라우저에 구현이 되어있기 때문에 서버의 응답은 CORS정책 위반 여부에 관여하지 않습니다. 클라이언트에서는 자신이 보냈던 요청의 Origin과 서버가 보내준 Access-Control-Allow-Origin을 비교하여 차단을 할지말지 결정합니다. 만약 유효하지 않다면 그 응답을 사용하지 않고 버립니다. CORS 작동방식으로 예비요청, 단순요청, 인증정보를 포함한 요청이 있습니다. 예비요청은 본 요청을 보내기 전 브라우저 스스로 안전한 요청인지 확인하는 것으로 메소드는 OPTIONS요청이 사용됩니다. 예비요청의 장점은 실제 요청을 보내기 전 미리 권한을 확인할 수 있기 때문에 리소스 측면에서 효율적입니다. 단순요청은 예비요청을 보내지 않고 바로 서버에 직행으로 본 요청을 보낸 후, 서버가 이에 대한 응답의 헤더에 Access-Control-Allow-Origin과 같은 값을 보내주면 브라우저가 CORS정책 위반 여부를 검사하는 방식입니다. 하지만 단순요청은 3가지 조건을 만족해야 합니다. GET, HEAD, POST 요청 중 하나여야 하며 자동으로 설정된 헤더외에 Accept, Accept-Language, Content-Language, Content-Type 헤더의 값만 수동으로 설정할 수 있습니다. Content-Type헤더에는 application/x-www-form-urlencoded multipart/form-data text/plain 값만 허용됩니다. POST요청의 경우 대부분 application/json으로 통신하기 때문에 Content-Type에 위반되어 대부분 예비요청으로 이루어집니다. 인증정보를 포함한 요청은 요청 헤더에 인증 정보를 담아 보내는 방식으로 인증과 관련된 정보를 credentials 옵션값을 설정하고 서버로 보내게 됩니다. Credentials 옵션을 사용하여 요청에 인증정보가 담겨있는 상태에서 다른 출처의 리소스를 요청하게 되면 브라우저는 CORS정책 위반 여부를 검사하는 룰에 다음 두가지를 추가하여 검사합니다. *Access-Control-Allow-Origin 에는 모든 요청을 허용하는 * 을 사용할 수 없으며, 명시적인 URL이여야 한다. * 응답헤더는 반드시 Access-Control-Allow-Credentails :true가 존재해야 한다. 결국 인증된 요청 역시 예비요청이 먼저 일어나게 되는 것입니다.

 

 

CORS란

CORS는 Cross-Origin Resource Sharing의 줄임말로 '교차 출처 리소스 공유' 라고 해석한다.

추가 HTTP 헤더를 사용하여, 한 Origin에서 실행 중인 웹 어플리케이션이 다른 Origin의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에서 알려주는 체제이다. 웹 어플리케이션은 리소스가 자신의 Origin(도메인, 프로토콜, 포트)와 다를 때 교차 출처 HTTP 요청을 실행한다.

 

Origin/ Cross-Origin 이란 무엇인가?

Origin과 비슷한 개념으로 도메인(domain)이 있다.

  • 도메인(domain) : naver.com
  • 오리진(origin): https://www.naver.com/PORT

Origin의 URL구조에서 살펴본 Protocol, Host, Port를 합친 것

 

SOP (Same Origin Policy)

SOP는 같은 출처에서만 리소스를 공유할 수 있다라는 규칙을 정한 정책이다.

즉 같은 프로토콜, 호스트, 포트를 사용한다면 다른 요소는 다르더라도 같은 Origin로 인정된다.

반대로 리소스가 자신의 출처와 다를경우 브라우저는 Cross Origin(교차출처)를 요청한다.

 

Origin를 비교하는 로직은 서버에서 구현된 스펙이 아닌 브라우저에서 구현된 스펙이다.

만약 CORS정책을 위반하는 요청에 서버가 정상적으로 응답을 하더라도 브라우저가 이 응답을 분석해서 CORS정책에 위반되면 그 응답은 처리하지 않게 된다.

정리하자면 프로토콜, 호스트, 포트 하나라도 일치하지 않으면 Cross Origin이 된다.

표를 보고 이것은 SOP인지 COR인지 비교해보자. 

 

예) https://etloveguitar.tistory.com

 

 

다시 한 번 CORS에 대한 개념을 상기시켜보자.

 

추가 HTTP 헤더를 사용하여, 한 Origin에서 실행 중인 웹 어플리케이션이 다른 Origin의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에서 알려주는 체제이다. 

 

CORS 에러는 CORS를 허용해서 아무런 문제 없이 다른 Origin 리소스를 공유해달라는 권고사항 같은 것이다.

 

CORS 기본 동작과정

1. 클라이언트에서 HTTP요청의 헤더에 Origin을 담아 전달한다.

다른 Origin의 리소스 요청시 클라이언트는 HTTP요청을 보낸다.

이 때 요청헤더의 Origin필드에는 요청을 보내는 Origin을 담아 보낸다.

 

2. 서버는 응답헤더에 Access-Control-Allow-Origin을 담아 클라이언트로 전달한다.

서버가 응답을 보낼때, 허락하는 Origin을 클라이언트에게 전달한다.

3. 클라이언트에서, 자신이 보냈던 요청의 Origin과 서버가 보내준 Access-Control-Allow-Origin을 비교한다.

자신이 보낸 Origin과 서버가 보내준 Access-Control-Allow-Origin을 비교하여 차단할지 말지를 결정한다.

만약 유효하지 않다면, 그 응답을 사용하지 않고 버린다.

서버의 응답은 CORS정책 위반 여부에 관여하지 않는다.
CORS정책에 의해 Origin을 비교하는 로직은 브라우저에 구현되어 있다.
그래서 서버에서 정상적인 응답을 하여 상태코드가 200이 나오더라도 브라우저가 응답을 CORS정책 위반이라고 분석하면 그 응답은 사용하지 않는다.
브라우저가 CORS정책 위반을 분석하는 시간은 서버의 응답이 도착한 이후이다.
즉, CORS정책을 위반하는 리소스 요청때문에 에러가 발생하더라도 서버 쪽 로그에서는 정상응답을 했다는 로그만 남기 때문에, CORS를 정확히 이해해야만 CORS에러를 해결할 수 있다.

 

CORS 작동방식

 

1. 예비요청(Preflight Request)

브라우저는 요청을 한번에 보내지 않고, 예비요청과 본 요청을 나누어 서버에 전달한다.

이때 브라우저가 예비요청을 보내는 것을 preflight라고 부르며, 이 예비요청의 메소드는 GET이나 POST가 아닌 OPTIONS라는 요청이 사용된다.

예비요청의 역할은 본 요청을 보내기 전에 브라우저 스스로 안전한 요청인지 확인하는 것이다.

 

  • 브라우저는 서버로 예비요청을 먼저 보낸다.
  • 서버는 이 예비요청에 대한 응답으로 어떤 것을 허용하고 어떤 것을 금지하고 있는지에 대한 정보를 담아서 브라우저에게 다시 보내준다.
  • 이후 브라우저는 보낸 요청과 서버가 응답해준 정책을 비교하여 해당 요청이 안전한지 확인하고 본 요청을 보내게 된다.
  • 이후 서버가 본 요청에 대한 응답을 하면 최종적으로 이 응답 데이터를 자바스크립트로 넘겨준다.
  • 만약 요청을 보낸 출처가 접근 권한이 없다면 브라우저에서 CORS 에러를 띄우게 되고, 실제 요청은 전달하지 않는다.

예비요청(Preflight Request) 장점

  • 실제 요청을 보내기 전에 미리 권한 확인을 할 수 있기 때문에, 실제 요청을 처음부터 통째로 보내는 것보다 리소스 측면에서 효율적이다.
  • CORS에 대비가 되어있지 않는 서버를 보호할 수 있다. CORS 이전에 만들어진 서버들은 SOP 요청만 들어오는 상황을 고려하고 만들었기 때문에 CORS에 대한 대비가 되어있지 않다.

2. 단순 요청(Simple Request)

단순요청은 예비요청을 보내지않고 바로 서버에 직행으로 본 요청을 보낸 후, 서버가 이에 대한 응답의 헤더에 Access-Control-Allow-Origin과 같은 값을 보내주면 브라우저가 CORS정책 위반 여부를 검사하는 방식이다.

 

 

단순요청은 예비요청을 생략하는 뜻인데 3가지 조건을 만족해야만 가능하다.

조건

  • GET, HEAD, POST 요청 중 하나여야 한다.
  • 자동으로 설정되는 헤더 외에, Accept, Accept-Language, Content-Language, Content-Type  헤더의 값만 수동으로 설정할 수 있다.
  • Content-Type 헤더에는 application/x-www-form-urlencoded multipart/form-data text/plain 값만 허용된다.

위의 조건으로 인해 단순요청이 일어나는 상황을 만드는 것은 쉽지 않다.

POST요청은 대부분 application/json으로 통신하기 때문에 Content-Type에 위반된다. 

결국 대부분 예비요청으로 이루어진다고 생각하면 된다.

 

3. 인증정보를 포함한 요청(Credentialed Request)

요청 헤더에 인증 정보를 담아 보내는 방식이다. 기존 예비 요청에서 보안을 더 강화하고 싶을때 사용한다.

출처가 다를 경우에는 별도의 설정을 하지 않으면 쿠키를 보낼 수 없는데 이것과 관련된 옵션이 있다.

인증과 관련된 정보(쿠키)를 담을 수 있게 해주는 옵션이 있는데 Credentials 옵션이다. 이 옵션은 총 3가지 값을 사용할 수 있다.

same-origin(기본값) 같은 출처 간 요청에만 인증 정보를 담을 수 있다.
include 모든 요청에 인증 정보를 담을 수 있다
omit 모든 요청에 인증 정보를 담지 않는다

만약 Credentials 옵션값인 same-origin이나 include와 같은 옵션을 사용하여 리소스 요청에 인증정보가 포함된다면, 브라우저는 다른 Origin의 리소스를 요청할 때 Access-Control-Allow-Origin만 확인하는 것이 아니라 다른 조건을 추가로 검사하게 된다.

 

예를 들어, Credentials 옵션을 사용하여 요청에 인증정보가 담겨있는 상태에서 다른 출처의 리소스를 요청하게 되면 브라우저는 CORS정책 위반 여부를 검사하는 룰에 다음 두가지를 추가하게 된다.

  • Access-Control-Allow-Origin 에는 모든 요청을 허용하는 * 을 사용할 수 없으며, 명시적인 URL이여야 한다.
  • 응답헤더는 반드시 Access-Control-Allow-Credentails :true가 존재해야 한다.

결국 인증된 요청 역시 Preflight 요청이 먼저 일어난다.

 

 

Reference


https://velog.io/@dae_eun2/CORS

https://etloveguitar.tistory.com/83

https://velog.io/@dae_eun2/CORS

https://velog.io/@sangbin2/CORS-%EB%8F%99%EC%9E%91-%EB%B0%A9%EC%8B%9D

 

'CS' 카테고리의 다른 글

쿠키(Cookie) 세션(Session)  (0) 2024.01.10
NoSQL과 RDBMS의 특징과 장단점  (0) 2024.01.01
기본키(Primary Key), 외래키(Foreign Key)  (1) 2024.01.01
HTTP Method  (1) 2024.01.01
N+1문제의 발생이유와 해결방법  (0) 2023.12.27
NoSQL과 RDBMS의 특징과 차이점에 대해서 장, 단점을 들어 설명해주세요.

 

RDBMS는 관계형 데이터베이스 관리 시스템으로 관계모델, 스키마, ACID 특성을 가지고 있습니다. 테이블 형식으로 저장하며 테이블은 관계를 나타내고 있습니다. 데이터의 구조는 미리 정의된 스키마에 따라야 하며 트랜젝션의 원자성, 일관성, 고립성, 지속성을 보장합니다. 장점으로는 ACID 특성으로 데이터의 일관성 복잡한 쿼리를 다루는데 효과적입니다. 단점으로는 확장이 어렵기 때문에 성능 저하가 발생할 수 있습니다. NoSQL은 비관계형 데이터베이스로 데이터가 동적으로 정의되기 때문에 스키마가 느슨합니다. 비정형 데이터로 다양한 형식의 데이터를 저장할 수 있으며 대규모 데이터를 분산 저장하고 처리할 수 있습니다. 장점으로는 확장성과 유연성이 있습니다. 수평적 확장이 용이하며 대용량 데이터를 다루기에 적합합니다. 또한 유연성으로 다양한 형태의 데이터를 다룰 수 있습니다. 단점으로는 일관성을 보장받기 어렵고 복잡한 쿼리와 조인을 처리하는 RDBMS보다 쿼리 제약이 있을 수 있습니다. 결국 애플리케이션의 요구사항에 따라서 선택을 해야하며 일관성이 더 중요한 경우 RDBMS가 적합하고 NoSQL은 대규모 확장과 유연성이 필요한 경우 더 적합합니다.

'CS' 카테고리의 다른 글

쿠키(Cookie) 세션(Session)  (0) 2024.01.10
CORS(Cross Origin Resource Sharing)  (1) 2024.01.02
기본키(Primary Key), 외래키(Foreign Key)  (1) 2024.01.01
HTTP Method  (1) 2024.01.01
N+1문제의 발생이유와 해결방법  (0) 2023.12.27
Primary Key, Foreign Key에 대해 설명해주세요.

 

기본키(Primary Key)는 관계형 데이터베이스 관리 시스템 테이블에서 모든 행을 고유하게 식별하는 필드 또는 필드의 집합입니다. 데이터베이스 테이블 내에서 각 레코드는 오직 하나의 값만 존재해야하고 기본키를 구성하는 어떤 속성도 널 값을 가질 수 없는 개체 무결성 제약조건이 있습니다. 따라서 기록을 삭제하거나 업데이트 하는 경우 데이터 무결성을 확인하기 위해 지정한 조치가 수행됩니다. 기본키는 식별자 역할을 하며 빠른 검색을 가능하게 하며 상위 테이블에 대한 삭제 또는 업데이트 작업을 거부하려면 제한 작업이 수행됩니다. 외래키(Foreign Key)는 두 테이블 간의 관계를 생성하는 열입니다. 외래키는 참조 무결성 제약조건을 가지고 있어 데이터의 일관성을 보장합니다. 참조하는 티이블(자식 테이블)의 값이 참조되는 테이블(부모 테이블)의 칼럼의 값에 존재하면 되는 것으로 외래키는 NULL 값이거나 또는 부모 테이블의 기본키 or 고유 키 값과 동일해야 합니다.

 

데이터베이스 키(Key)

키는 관계(테이블)에서 행(튜플)을 식별하는데 도움이 되는 속성입니다. 이를 통해 두 테이블 간의 관계를 찾을 수 있다.

키를 사용하면 해당 테이블에 있는 하나 이상의 열을 조합하여 테이블의 행을 고유하게 식별할 수 있습니다. 데이터베이스 키는 테이블에서 고유한 레코드나 행을 찾는 데에도 유용하다.


기본키(Primary Key)

관계형 데이터베이스 관리 시스템의 테이블에 있는 모든 행을 고유하게 식별하는 필드 또는 필드의 집합이다.

 

개체 무결성 제약 조건 

  • 기본키를 구성하는 어떤 속성도 널 값을 가질 수 없으며, 오직 하나의 값만 존재해야 한다 ( UNIQUE + NOT NULL )
  • 기본키는 테이블에 저장된 행 데이터를 임의로 식별하기 위한 것이며, 하나의 테이블에 하나의 기본 키 제약을 정의할 수 있다.
  • 추가적으로 기본키 설정 시, 자동으로 기본 키에 해당하는 컬럼으로 인덱스가 생성된다.

 

  • 데이터베이스 테이블의 모든 레코드를 식별한다.
  • Primary Key는 테이블에서 기본적인 식별자 역할을 하며, 빠른 검색을 가능하게 합니다.
  • 기록을 삭제하거나 업데이트하는 경우 데이터 무결성을 확인하기 위해 지정한 조치가 수행된다.
  • 상위 테이블에 대한 삭제 또는 업데이트 작업을 거부하려면 제한 작업을 수행한다.
  • DBMS 테이블을 물리적으로 구성할 때마다 데이터는 클러스터형 인덱스의 순서로 구성된다.

외래키(Foreign key)

외래키는 두 테이블 간의 관계를 생성하는 열이다. 외래키의 목적은 데이터 무결성을 유지하고 엔티티의 서로 다른 두 인스턴스 간 탐색을 허용하는 것이다. 이는 다른 테이블의 기본키를 참조하므로 두 테이블 간의 상호 참조 역할을 합니다.

 

  • 외래키는 상위 테이블의 기본키를 사용하여 엔티티를 마이그레이션하는데 도움이 된다.
  • 외래키를 사용하면 두 개 이상의 테이블을 함께 연결 할 수 있다.
  • 데이터의 일관성을 보장한다.
  • 외래키는 상위 테이블의 기본키와 열 또는 열 조합을 일치시키는데 사용될 수 있다.
  • SQL 외래키 제약 조건은 데이터 상위의 참조 무결성이 하위 테이블의 값과 일치하는지 확인하는데 사용

참조 무결성 제약조건

  • 자식 릴레이션의 외래 키의 값은 참조된 부모 릴레이션의 기본 키 값과 같아야 하며, 자식 릴레이션의 값이 변경될 때 부모 릴레이션의 제약을 받는다는 조건입니다.
  • RDBMS에서는 컬럼의 값에 따라 테이블끼리 연결하는데 값을 참조하는 쪽의 테이블을 자식 테이블, 값을 가진 컬럼을 외래 키 라고 합니다.
  • 참조되는 쪽의 테이블을 부모 테이블, 값을 가진 컬럼을 부모 키 라고 부르며 부모 키는 기본 키 또는 고유 키여야 합니다.
  • 즉, 참조하는 테이블 (자식 테이블)의 값이 참조되는 테이블 (부모 테이블)의 컬럼의 값에 존재하면 된다는 것입니다.
    (외래 키는 NULL 값이거나 또는 부모 테이블의 기본 키 or 고유 키 값과 동일해야 한다)


기본키 외래키
기본 키 제약 조건은 테이블의 모든 행을 고유하게 식별하는 열 또는 열 그룹
관계형 데이터베이스 관리 시스템
외래키는 두 테이블 간의 관계를 생성하는 열
테이블의 레코드를 고유하게 식별하는데 도움이 됩니다. 다른 테이블의 기본키인 테이블의 필드
기본키는 null 값을 허용하지 않습니다 외래키는 여러개의 null 값을 허용할 수 있습니다.
기본키는 클러스터형 인덱스이며, DBMS 테이블의 데이터는 클러스터형 인덱스의 순서에 따라 물리적으로 구성된다. 외래키는 클러스터형 또는 비클러스터형 인덱스를 자동으로 생성할 수 없다.
테이블에는 단일 기본키가 있을 수 있다. 한 테이블에 여러 개의 외래키를 가질 수 있다
기본 키 값은 상위 테이블에서 제거할 수 없다. 외래 키 값은 하위 테이블에서 제거될 수 있다.
임시 테이블에 기본 키를 암시적으로 정의할 수 있다. 로컬 또는 전역 임시 테이블에 외래 키를 정의할 수 없다.
기본 키는 클러스터형 인덱스 기본적으로 클러스터형 인덱스가 아니다
두 행은 기본키에 대해 동일한 값을 가질 수 없다 외래키에는 중복된 값이 포함될 수 있다.
테이블 열에 값을 삽입하는데 제한이 없다. 외래키 테이블에 값을 삽입하는 동안 해당 값이 기본키 열에 있는 지 확인해야 한다.

 

 

 

Reference


https://www.guru99.com/ko/difference-between-primary-key-and-foreign-key.html

https://shuu.tistory.com/68

 

'CS' 카테고리의 다른 글

CORS(Cross Origin Resource Sharing)  (1) 2024.01.02
NoSQL과 RDBMS의 특징과 장단점  (0) 2024.01.01
HTTP Method  (1) 2024.01.01
N+1문제의 발생이유와 해결방법  (0) 2023.12.27
SpringSecurity와 인증, 인가, JWT의 구조, 동작 과정  (1) 2023.12.27
HTTP 메서드에 대해 설명해주세요.

 

HTTP 메소드는 클라이언트와 서버 사이에 이루어지는 요청과 응답 데이터를 전송하는 방식으로 서버에 주어진 리소스에 수행하길 원하는 행동과 서버가 수행해야 할 동작을 지정하는 요청을 보내는 방식입니다. 주요 메소드로는 GET, POST, PUT, PATCH 메소드가 있습니다. GET 메소드는 리소스를 조회할때 사용하며 POST는 요청 데이터를 처리하고 등록하는데 주로 사용되는 메소드로 메시지 바디(body)를 통해 서버로 요청 데이터 전달합니다. PUT메소드는 리소스를 대체하며 해당 리소스가 없으면 생성하는 메소드입니다. 일부의 리소스를 변경을 할때 PATCH메소드를 사용합니다. DELETE 메소드는 리소스를 제거할때 사용하며 GET, PUT, DELETE는 메소드를 계속 호출해도 결과가 똑같기 때문에 멱등성을 보장하지만 POST나 PATCH는 멱등하다고 볼 수 없습니다.
또한 GET 메소드는 계속 호출을 해도 리소스를 변경하지 않기 때문에 안전한 속성을 가지고 있습니다.
그 외 메소드로는 HEAD, OPTIONS, CONNECT, TRACE 메소드가 있으며 HEAD는 상태줄과 헤더만 반환하고 TRACE는 대상 리소스에 대한 경로를 따라 메시지 루프백을 수행해 일종의 검사용 메소드로 사용합니다. OPTIONS는 대상 리소스에 대한 통신 가능 옵션을 설명하며 주로 CORS에서 사용합니다. CONNECT는 대상 자원으로 식별되는 서버에 대한 터널을 설정하는 메소드입니다.

HTTP Method 종류

 

HTTP 메서드란 클라이언트와 서버 사이에 이루어지는 요청(Request)과 응답(Response) 데이터를 전송하는 방식

으로 서버에 주어진 리소스에 수행하길 원하는 행동, 서버가 수행해야 할 동작을 지정하는 요청을 보내는 방법이다.

 

주요 메소드

  • GET : 리소스 조회
  • POST : 요청 데이터 처리, 주로 등록에 사용
  • PUT : 리소스를 대체(덮어쓰기), 해당 리소스가 없으면 생성
  • PATCH : 리소스 부분 변경 ( PUT이 전체 변경, PATCH는 일부 변경 )
  • DELETE : 리소스 삭제

기타 메소드

  • HEAD : GET과 동일하지만 메시지 부분(body 부분) 제외하고, 상태 줄과 헤더만 반환
  • OPTIONS : 대상 리소스에 대한 통신 가능 옵션(메서드)을 설명(주로 CORS에서 사용)
  • CONNECT : 대상 자원으로 식별되는 서버에 대한 터널을 설정
  • TRACE : 대상 리소스에 대한 경로를 따라 메시지 루프백 테스트를 수행

 

GET

  • 리소스 조회 메소드(Read)
  • 만일 틀서버에 전달하고 싶은 데이터는 쿼리스트링을 통해 전달
    • ex) member/100?username=jugmin
  • 쿼리스트링 외에 메시지 바디를 사용해서 데이터를 전달할 수 있지만, 서버에서 따로 구성해야 되기 때문에 지원하지 않는 곳이 많아서 권장하지 않음.
  • 조회할 때 POST도 사용할 수 있지만, GET 메서드는 캐싱이 가능하기에 GET을 사용하는 것이 유리하다.

정적 데이터 조회과정

 

1. 클라이언트에서 /members/100 으로 100번 멤버를 조회해서 정보를 달라고 GET 요청

2. 서버에서는 요청 메시지를 분석해 내부의 유저정보를 조회한 뒤 결과를 Response를 만든다.

3. 서버에서 클라이언트로 응답을 해준다. 클라이언트에서 정상적으로 받으면 200 OK status를 가지며, 회원정보를 얻게 된다.


동적 데이터 조회 과정

  • 주로 검색, 게시판 목록에서 검색어로 이용
  • 쿼리 파라미터 사용해서 데이터를 전달
  • 쿼리 파라미터는 key1=value&key2=value2 구조로 되어있음.
  1.  요청 URL 뒤에 ?q=hello&hl=ko 쿼리 파라미터를 줘서 상세한 조회 데이터를 얻는다.


HTML Form 데이터 조회 과정

  • HTML Form 태그 문서로 사용자와 UI로 상호작용하여 서버와 통신
  • HTML Form 전송은 GET, POST만 지원
  1. 웹문서에서 폼 입력칸에 데이터를 적고 전송 버튼을 누른다.

 

2. 지정한 GET 메서드 동작에 따라 input 태그안에 들어간 값들이 쿼리스트링으로 서버 전송된다.


POST

  • 전달한 데이터 처리/생성 요청 메서드(Create)
  • 메시지 바디(body)를 통해 서버로 요청 데이터 전달하면 서버는 요청 데이터를 처리하여 업데이트
  • 전달한 데이터로 주로 신규 리소스 등록, 프로세스 처리에 사용
  • 만일 데이터를 GET 하는데 있어, JSON으로 조회 데이터를 넘겨야 하는 애매한 경우 POST를 사용

JSON 데이터 전송 과정

  1. 클라이언트는 body에 등록한 회원 정보를 JSON 형태로 만들어 담고 서버로 전송한다.

2. 서버에서 받은 메시지를 분석해 로직대로 처리한다. 예를 들어 데이터베이스에 등록하고 신규 아이디어를 생성한다.

3. 신규회원에 대한 데이터를 바디에 담아서 클라이언트로 응답한다.

  • 신규 자원 생성은 200이나 201로 응답을 보낸다.
  • Location은 자원이 신규로 생성된 URL 경로를 의미한다.


HTML Form 데이터 전송과정

  • HTML Form 태그 문서로 사용자와 UI로 상호작용하여 서버와 통신
  • 회원가입, 상품 주문, 데이터 변경에 이용
  • HTML Form 전송은 GET, POST만 지원
  1. 웹문서에서 폼 입력칸에 데이터를 적고 전송버튼을 누른다.
  2. 지정한 POST 메서드 동작에 따라 input 태그안에 들어간 값들이 쿼리스트링으로 서버로 전송한다.


[ Content-Type 헤더 종류 ]

 

Content-Type : application/x-www-form-urlencoded

  • Form의 내용을 HTTP 메시지 바디를 통해서 전송(key=value, 쿼리 파라미터 형식)
  • 전송 데이터를 url encoding 처리
  • 예) abc김 -> abc%EA%B9%80

Content-Type : multipart/form-data

  • 파일 업로드 같은 바이너리 데이터 전송 시 사용
  • 다른 종류의 여러 파일과 Form의 내용 함께 전송 가능, 그래서 이름이 multipart이다.

Content-Type : application/json

  • TEXT, XML, JSON 데이터 전송 시 사용

PUT

  • 리소스를 대체(수정)하는 메소드(Update)
  • 만일 요청 메시지에 리소스가 있으면 덮어쓰고, 없으면 새로 생성한다.
    • /members/100 데이터가 존재하면 기존에 것을 완전 대체 한다.
    • /members/100 데이터가 없으면 대체 할게 없으니까 POST와 같이 새로 생성한다.
    • /members/100 일부 데이터만 변경을 보낼 경우 해당 데이터가 완전히 대체되어 이름 데이터가 삭제된다. (이때는 PATCH 메소드 사용)
  • 데이터를 대체해야 하니, 클라이언트가 리소스의 구체적은 전체 경로를 지정해 보내주어야 한다.
    • POST /members : 멤버 새로 추가
    • PUT /members/100 : 100번째 멤버 수정

PATCH

  • 리소스 일부 부분을 변경하는 메소드(Update)
  • 만일 PATCH를 지원하지 않는 서버에서는 대신에 POST를 사용할 수 있다.

DELETE

  • 리소스 제거하는 메소드(Delete)
  • 상태코드는 대부분은 200을 사용하고 상황에 따라 204를 사용한다.

HEAD

  • GET과 동일하지만 서버에서 Body를 Return 하지 않음
  • 응답의 상태 코드만 확인할때와 같이 Resource를 받지 않고 오직 찾기만 원할때 사용 (일종의 검사 용도)
  • 서버의 응답 헤더를 봄으로써 Resource가 수정되었는지 확인 가능

TRACE

  • 이 메서드도 일종의 검사용
  • 서버에 도달했을때의 최종 패킷의 요청 패킷 내용을 응답 받을 수 있다.
  • 요청의 최종 수신자는 반드시 송신자에게 200(OK) 응답의 내용(Body)로 수신한 메시지를 반송해야 한다.
  • 최초 Client의 요청에는 Body가 포함될 수 없다.
클라이언트의 요청 패킷이 방화벽, Proxy 서버, Gateway 등을 거치면서 패킷의 변조가 일어날 수 있는데,  TRACE 메서드를 통해 요청했던 패킷 내용과 응답 받은 패킷 내용을 비교하여 변조 유무를 확인 할 수 있다.

 


OPTION

  • 예비 요청(Preflight)에 사용되는 HTTP메소드
  • 예비 요청이란 본 요청을 하기 전에 안전한지 미리 검사하는 것이라고 보면 된다.
  • 서버의 지원 가능한 HTTP 메서드와 출처를 응답 받아 CORS 정책을 검사하기 위한 요청이다.

 


HTTP 메소드의 속성

 

  1. 안전(Safe Methods)메소드를 호출해도 리소스를 변경해지 않는다는 뜻, 주요 메소드중에는 GET 메소드가 안전하다고 볼 수 있다.
  2. 멱등(Idempotent Methods)
    1. 메소드를 계속 호출해도 결과가 똑같다는 뜻이다. GET, PUT, DELETE는 멱등하다고 볼 수 있지만 POST PATCH는 멱등하다고 볼 수 없다.
  3. 캐시가능(Cacheable Methods)
    1. 캐싱을 해서 데이터를 효율적으로 가져올 수 있다는 뜻이다. GET, HEAD, POST, PATCH가 캐시가 가능하지만 실제로는 GET과 HEAD만 주로 캐싱이 쓰이고 있다.

Reference


https://inpa.tistory.com/entry/WEB-%F0%9F%8C%90-HTTP-%EB%A9%94%EC%84%9C%EB%93%9C-%EC%A2%85%EB%A5%98-%ED%86%B5%EC%8B%A0-%EA%B3%BC%EC%A0%95-%F0%9F%92%AF-%EC%B4%9D%EC%A0%95%EB%A6%AC

https://velog.io/@haron/HTTP-%EB%A9%94%EC%84%9C%EB%93%9C%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%84%EB%8A%94%EB%8C%80%EB%A1%9C-%EB%A7%90%ED%95%B4%EC%A3%BC%EC%84%B8%EC%9A%94

 

N+1 문제의 발생 이유와 해결 방법에 대해 설명해주실 수 있을까요? 해결 방법은 3가지 이상 말씀해주시면 좋습니다.

 

N+1 문제란?

 

N+1 문제는 데이터베이스 쿼리를 실행할 때 발생할 수 있는 성능 문제 중 하나로, 쿼리 실행 시 추가적인 N개의 쿼리가 발생하여 성능저하를 초래할 수 있습니다. 

이는 주로 ORM(Object-Relation Mapping)를 사용하는 경우 발생하며, 한 번의 부모 쿼리로 N개의 자식 쿼리를 가져오는 방식에서 문제가 발생합니다.

Lazy Loading(지연 로딩) : 연관된 데이터가 실제로 필요할때만 로드되도록 설계된 방식이지만, 이를 잘못 사용할 경우 여러번의 쿼리가 발생하여 N+1 문제가 발생할 수 있습니다. 

Eager Loading(즉시 로딩) : Eager 전략으로 데이터를 조회하는 경우 N+1 문제가 발생할 수 있습니다.

 

 

Eager(즉시 로딩)인 경우

  • JPQL에서 만든 SQL을 통해 데이터를 조회
  • 이후 JPA에서 Fetch 전략을 가지고 해당 데이터의 연관 관계인 하위엔티티를 추가 조회시 N+1 문제 발생

Lazy(지연 로딩)인 경우

  • JPQL에서 만든 SQL을 통해 데이터를 조회
  • JPA에서 Fetch 전략을 가지지만, 지연 로딩이기 때문에 추가 조회는 하지 않음
  • 하지만, 하위 엔티티를 가지고 작업하게 되면 추가 조회가 발생하기 때문에 결국 N+1 문제가 발생하게 된다.

해결방법

  • Join Fetch 사용 : 조인을 통해 필요한 모든 데이터를 한 번에 가져오는 방식으로 문제를 해결할 수 있습니다. 
  • 캐싱 사용 : 자주 사용되는 데이터를 캐싱하여 데이터베이스 쿼리 횟수를 줄여 성능을 향상시킬 수 있습니다.
  • Batch Fetching 사용 : 데이터베이스에 배치 쿼리를 보내 여러 엔티티를 한 번에 가져오는 방식으로 성능을 향상 시킬 수 있습니다.

 

 


N+1문제란 1번의 쿼리를 날렸을 때 의도하지 않은 N번의 쿼리가 추가적으로 실행되는 것을 의미하며 Jpa Repository를 활용해 인터페이스 메소드를 호출할 때 1:N또는 N:1 관계를 가진 엔티티를 조회할 때 발생합니다. 즉시로딩인 경우 JPQL에서 만든 SQL을 통해 데이터 조회 시 Fetch 전략을 가지고 해당 데이터의 연관 관계인 하위 엔티티들을 추가로 조회할 때 발생하게 되고, 지연로딩인 경우 조회 시 Fetch 전략을 가지지만 추가 조회는 하지 않지만 하위 엔티티를 가지고 작업을 하게 되면 추가 조회가 발생하기 때문에 결국 N+1 문제가 발생하게 됩니다. N+1의 해결방법은 Join Fetch 사용하거나, 캐싱을 사용하거나, Batch Fetching 사용하여 문제를 해결 할 수 있습니다. Join Fetch는 Join을 통해 필요한 모든 데이터를 한 번에 가져오는 방식으로 문제를 해결 할 수있으며 자주 사용되는 데이터를 캐싱하여 데이터베이스 쿼리 횟수를 줄여 성능을 향상시킬 수 있습니다. 마지막으로 데이터베이스에 배치 쿼리를 보내 여러 엔티티를 한 번에 가져오는 방식을 성능을 향상 시킬 수 있습니다.

 

 

Reference


https://velog.io/@coco_116/N1-%EB%AC%B8%EC%A0%9C%EC%9D%98-%EB%B0%9C%EC%83%9D-%EC%9D%B4%EC%9C%A0%EC%99%80-%ED%95%B4%EA%B2%B0-%EB%B0%A9%EB%B2%95%EC%97%90-%EB%8C%80%ED%95%B4-%EC%84%A4%EB%AA%85%ED%95%B4%EC%A3%BC%EC%8B%A4-%EC%88%98-%EC%9E%88%EC%9D%84%EA%B9%8C%EC%9A%94-%ED%95%B4%EA%B2%B0-%EB%B0%A9%EB%B2%95%EC%9D%80-3%EA%B0%80%EC%A7%80-%EC%9D%B4%EC%83%81-%EB%A7%90%EC%94%80%ED%95%B4%EC%A3%BC%EC%8B%9C%EB%A9%B4-%EC%A2%8B%EC%8A%B5%EB%8B%88%EB%8B%A4

'CS' 카테고리의 다른 글

기본키(Primary Key), 외래키(Foreign Key)  (1) 2024.01.01
HTTP Method  (1) 2024.01.01
SpringSecurity와 인증, 인가, JWT의 구조, 동작 과정  (1) 2023.12.27
Web Server & WAS  (0) 2023.12.23
MVC 모델이란  (0) 2023.12.21

+ Recent posts