728x90
반응형

📌 MCP 서버란 무엇인가?
MCP 서버는 데이터베이스, 외부 API, 로컬 파일 시스템과 같은 다양한 외부 리소스를 AI 모델이 쉽게 접근할 수 있도록 표준화된 인터페이스를 제공합니다. MCP를 통해 AI는 외부 데이터를 조회하거나 특정 작업을 직접 수행할 수 있어, 반복적이고 수동적인 업무를 크게 줄이고 생산성을 높일 수 있습니다.

MCP 서버는 표준 JSON 인터페이스를 통해 AI 모델과 통신하며, 직관적인 방식으로 다양한 외부 시스템과 연동할 수 있도록 도와줍니다.

🔧 MCP 서버의 주요 유형과 선택 방법
MCP 서버는 용도에 따라 다양한 유형으로 구분됩니다. 대표적인 MCP 서버의 종류는 다음과 같습니다:

PostgreSQL MCP 서버: AI 모델이 PostgreSQL 데이터베이스의 데이터를 직접 조회하고 분석할 수 있도록 돕습니다.
Filesystem MCP 서버: 로컬 파일 시스템 내 문서와 데이터를 AI 모델이 접근하여 활용할 수 있게 지원합니다.
API MCP 서버: AI 모델이 외부 API를 직접 호출하여 데이터를 가져오고 처리할 수 있도록 돕습니다.
이외에도 GitHub MCP 서버, Google Drive MCP 서버와 같이 여러 특화된 MCP 서버가 존재하므로, 필요한 작업과 환경에 맞는 MCP 서버를 선택하여 설정할 수 있습니다.

 
 
⚙️ Cursor IDE와 MCP 서버 연동하기
MCP 서버를 Cursor IDE와 연결하여 실질적으로 활용해 봅니다.

연동 전 준비 사항
Node.js와 npm을 미리 설치합니다.
PostgreSQL 데이터베이스가 로컬이나 원격 서버에 준비되어 있어야 합니다.
설치 확인
터미널(명령 프롬프트 또는 PowerShell)에서 Node.js 설치 여부를 확인합니다:

node -v
npm -v
Cursor IDE에 MCP 서버 추가하기
Cursor Setting에서 "MCP" 탭으로 이동합니다.
MCP Servers 섹션에서 "Add new global MCP server" 버튼을 클릭합니다.
mcp.json 파일을 아래처럼 작성합니다.
{
  "mcpServers": {
    "postgres": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-postgres",
        "postgresql://username:password@localhost:5432/dbname"
      ]
    }
  }
}
여기서 각 항목은 다음과 같이 입력합니다:

username: 데이터베이스 접속 사용자 이름
password: 데이터베이스 사용자 암호
localhost: 데이터베이스 서버의 주소 (원격 서버일 경우 IP 주소 또는 도메인 사용)
5432: PostgreSQL 서버 포트 번호 (기본값)
dbname: 연결할 데이터베이스 이름
정보를 모두 입력한 후 MCP Servers 목록에 "postgres"가 추가되었는지 확인합니다.
MCP Servers  목록에서 "postgres"가 활성 상태(초록색 점)로 표시되는지 확인합니다. (초록색 표시가 될때까지 몇초정도 걸릴 수 있음)
✅ MCP 서버와의 연동 상태 확인하기
MCP 서버가 정상적으로 연동되었는지 실제로 확인해 봅니다.

연동 테스트 수행
Cursor IDE의 AI 챗 패널에서 다음과 같은 간단한 요청을 입력해 봅니다:
데이터베이스에 저장된 테이블 이름들을 보여줘.
예시 명령:
정상적으로 데이터베이스의 테이블 목록이 표시되면 MCP 서버와의 연동이 성공적으로 완료된 것입니다.
만약 오류가 발생하거나 결과가 나오지 않는다면, 서버 로그와 입력한 연결 정보를 다시 점검해 보세요.

출처https://gsroot.tistory.com/95

 

728x90
반응형
728x90
반응형

🛠️ 1단계: Cursor IDE 설치 및 환경 구성하기
먼저 AI 지원 통합 개발 환경(IDE)인 Cursor IDE를 설치합니다. Cursor IDE는 코드 작성부터 디버깅까지 효율적으로 관리할 수 있게 도와줍니다.

설치 방법
Cursor IDE 공식 웹사이트에 접속합니다.
메인 페이지에서 사용 중인 운영체제(Windows)를 선택하여 설치 파일을 다운로드합니다.
다운로드된 설치 파일을 실행하고 화면에 나타나는 설치 마법사를 따라 설치를 진행합니다.
설치 완료 후 Cursor IDE를 처음 실행하면 자동으로 최신 버전 여부를 체크하고, 필요한 경우 업데이트가 진행됩니다.
🔑 2단계: Anthropic API 키 발급받기
Claude 모델을 Cursor IDE에서 사용하기 위해서는 Anthropic의 API 키가 필요합니다. 이 API 키를 통해 안전하게 모델에 접근할 수 있습니다.

API 키 발급 방법
Anthropic 공식 홈페이지를 방문하여 "Sign up" 또는 "Login"을 통해 계정을 생성하거나 기존 계정으로 로그인합니다.
로그인 후 계정 관리 페이지나 대시보드에서 "API Keys" 메뉴를 선택합니다.
"Create API Key" 버튼을 클릭하여 새로운 API 키를 생성합니다.
생성된 API 키는 민감한 정보이므로, 복사하여 암호화된 파일이나 안전한 비밀 관리 도구에 저장합니다.
주의: API 키는 개인 정보를 담고 있어 공개되거나 외부 접근되지 않도록 특별히 주의해야 합니다.

⚙️ 3단계: Cursor IDE에서 Claude 모델 활성화하기
발급받은 API 키를 Cursor IDE에서 설정하여 Claude 모델을 활성화합니다.

모델 활성화 절차
Cursor IDE를 실행한 후, 명령 팔레트를 열어 Cursor Setting 메뉴에 접근합니다. (명령 팔레트의 단축키는 Ctrl + Shift + P 또는 Cmd + Shift + P)
Cursor Setting 메뉴에서 "Models" 항목을 선택합니다.
사용 가능한 AI 모델 목록 중 "claude-"로 시작하는 모델들을 찾아 활성화 버튼을 클릭하여 모델을 활성화합니다.
Anthropic API Key에 앞서 복사한 API 키를 입력합니다.
모든 정보를 정확하게 입력한 후 변경사항을 저장하거나 적용 버튼을 눌러 설정을 마무리합니다.
✅ 4단계: 연동 상태 확인하기
모델 연동 설정이 정상적으로 완료되었는지 확인하는 테스트를 진행합니다.

테스트 방법
명령 팔레트를 열어  Cursor IDE의 AI 챗 패널(우측)을 활성화합니다.
간단한 코드 샘플을 작성하거나 기존에 작성된 코드를 엽니다.
AI 챗 패널에 "Explain this code" 또는 "Summarize this code"와 같은 간단한 명령을 입력하여 실행합니다.
Claude 모델이 정상적으로 요청한 설명이나 요약을 제공하는지 확인합니다.
만약 정상적인 응답을 받았다면 Claude 모델과의 연동이 성공적으로 이루어진 것입니다.

 출처https://gsroot.tistory.com/95

 

728x90
반응형
728x90
반응형

🚀 MCP(Model Context Protocol)란 무엇인가?
MCP(Model Context Protocol)는 Anthropic이 주도하여 개발한 개방형 표준 프로토콜로, 다양한 외부 리소스(데이터베이스, 파일 시스템, 외부 API 등)를 Claude와 같은 대형 언어 모델(LLM)과 연결해주는 통합된 규격입니다. 기존에는 개별 시스템 간의 통합이 복잡하고 시간이 오래 걸렸지만, MCP는 표준화된 프로토콜을 통해 쉽고 빠르게 다양한 도구와 데이터를 연동할 수 있도록 돕습니다.

MCP의 강점은 표준화된 인터페이스 덕분에 다양한 애플리케이션과 AI 시스템 간의 원활한 소통을 지원한다는 점입니다. 각기 다른 시스템이 서로 상이한 데이터 처리 방식과 도구를 사용하더라도 MCP를 활용하면 통합의 비용과 복잡성을 크게 줄일 수 있습니다.

📌 MCP의 핵심 구성 요소 3가지
MCP는 세 가지 중요한 구성 요소로 이루어져 있습니다.

1. 리소스(Resource)
리소스는 AI 모델이 읽기 전용으로 접근할 수 있는 데이터 소스를 의미합니다. AI 모델은 이를 통해 외부 시스템에서 데이터를 얻고 작업의 맥락을 이해하여 보다 정확한 작업을 수행할 수 있습니다.

예시:
데이터베이스 내 테이블과 컬럼 정보
문서 파일(PDF, Markdown 등)
외부 API의 JSON 응답 데이터
2. 툴(Tool)
툴은 AI 모델이 직접 호출하여 외부 시스템과 상호작용하는 데 사용됩니다. 이를 통해 AI 모델은 데이터를 가져오거나 특정 연산을 수행하는 등 보다 능동적인 작업을 할 수 있습니다.

예시:
SQL 쿼리 실행
날씨 조회, 위치 정보 등 외부 API 호출
파일 시스템 내 특정 파일 검색
3. 프롬프트(Prompt)
프롬프트는 사용자가 정의해 놓은 질문이나 지시사항의 템플릿입니다. AI 모델은 프롬프트를 통해 사용자의 요구사항을 정확히 이해하고 효율적으로 작업을 수행할 수 있습니다.

예시:
특정 형식의 코드 생성 요청
데이터 분석 질의
반복적으로 수행하는 작업 자동화
🛠️ MCP의 작동 방식과 구조
MCP의 시스템 구조는 크게 세 가지 주요 역할로 나눌 수 있습니다.

호스트(Host): 사용자와 AI 모델 간 인터페이스를 제공하는 주체로 Cursor IDE나 Claude Desktop과 같은 애플리케이션입니다.
클라이언트(Client): 호스트 내에서 MCP 서버와의 통신을 담당합니다. 클라이언트는 호스트가 MCP 서버에서 데이터를 가져오거나 도구를 호출할 때 요청과 응답을 처리합니다.
서버(Server): DB, API, 파일 시스템 등 외부 리소스를 MCP 규격에 따라 노출하는 독립적인 프로세스입니다. 클라이언트가 서버를 통해 데이터를 접근할 수 있도록 도와줍니다.
Cursor IDE는 클라이언트 역할을 하며 MCP 서버와의 연동을 통해 외부 데이터를 효과적으로 활용할 수 있도록 지원합니다.

💡 Cursor IDE에서 MCP를 활용해야 하는 이유
Cursor IDE에 MCP를 활용하면 다음과 같은 주요 장점이 있습니다.

생산성 향상
AI 모델이 반복적인 데이터베이스 조회나 API 호출 작업을 대신 수행하여 개발자의 업무 부담을 줄여줍니다.

정확성 향상
실시간 데이터를 기반으로 작업하기 때문에 AI가 제공하는 결과물의 정확성과 신뢰성이 높아집니다.

유연한 확장성
표준화된 프로토콜 덕분에 신규 데이터 소스나 도구의 추가와 확장이 쉽고 효율적입니다.

이러한 이점을 통해 개발자들은 단순 반복 작업에서 벗어나 창의적이고 복잡한 문제 해결에 집중할 수 있게 됩니다.

🔍 MCP를 활용한 실제 시나리오
실제 개발 환경에서는 다음과 같은 다양한 시나리오에서 MCP를 활용할 수 있습니다.

데이터 분석: 특정 테이블이나 데이터셋의 정보를 AI가 직접 데이터베이스에서 조회하고 분석 결과를 제공합니다.
애플리케이션 개발: 날씨 정보와 같은 외부 API 데이터를 MCP를 통해 AI가 직접 호출하여, 최신의 데이터를 반영한 코드를 즉각 작성할 수 있습니다.
코드 리팩토링: 기존 코드나 문서를 MCP 리소스로 제공하여 AI가 직접 문서를 읽고 이해한 후, 개선된 코드나 문서 내용을 제안하도록 할 수 있습니다.

 출처https://gsroot.tistory.com/95

 

728x90
반응형
728x90
반응형
public static String format(String format, Object... args);
public static String format(Locale l, String format, Object... args);

String 의 static 메서드인 format 메서드는 문자열의 형식을 설정하는 메서드입니다.

 

  1. %d (10진수 형식)
  2. %s (문자열 형식)
  3. %f (실수형 형식)
  4. Locale 설정
  5. %t (날짜시간 형식)
  6. %c (유니코드 문자 형식)
  7. %o, %x(8진수, 16진수 형식)

1. %d (= Integer Formatting)

10진수 integer의 형식을 설정할 때 이용합니다.

int i = 23;

System.out.println(String.format("%d_", i));
System.out.println(String.format("%5d_", i));
System.out.println(String.format("%-5d_", i));
System.out.println(String.format("%05d_", i));
23_
   23_
23   _
00023_

%5d 와 같이 %와 d 사이에 정수를 설정하면, 글자 길이를 설정할 수 있습니다.
기본적으로 오른쪽 정렬이고, -를 붙일 경우 왼쪽정렬입니다.(ln 4~5)
표현할 숫자인 i의 길이가 5보다 작을 경우 0을 붙입니다.(leading 0s) (ln 6)

※ %d 와 %-5d의 구분을 위해 맨 마지막에 _ 을 포함시켰습니다.

 

int i = 123456789;

System.out.println(String.format("%,d_", i));
System.out.println(String.format("%,15d_", i));
System.out.println(String.format("%,-15d_", i));
System.out.println(String.format("%,015d_", i));
123,456,789_
    123,456,789_
123,456,789    _
0000123,456,789_

% 바로 뒤에 , 를 붙이면 3자리 단위로 쉼표를 찍어줍니다.


2. %s (= String Formatting)

문자열의 형식을 설정할 때 이용합니다.

String str = "tete";

System.out.println(String.format("%s_", str));
System.out.println(String.format("%12s_", str));
System.out.println(String.format("%-12s_", str));
System.out.println(String.format("%.2s_", str));
System.out.println(String.format("%-12.2s_", str));
System.out.println(String.format("%12.2s_", str));
tete_
        tete_
tete        _
te_
te          _
          te_

%s는 문자열을 그대로 출력하고,
%s 앞에 숫자(N)를 설정할 경우, str.length()가 N보다 작을 경우 공백을 추가합니다. (ln 4~5)
- 를 붙일 경우, 왼쪽 정렬. (default는 오른쪽 정렬) (ln 5)
.숫자(N)를 설정할 경우, 최대 N길이 만큼만 출력 (ln 7~8)


3. %f (= Floating point Formatting)

실수형 숫자 형식을 설정할 때 이용합니다.

double n = 123.45678;

System.out.println(3.4);
System.out.println(n);
System.out.println();

System.out.println(String.format("%f_", 3.4));
System.out.println(String.format("%f_", n));
System.out.println(String.format("%.6f_", n));
System.out.println(String.format("%15f_", n));
System.out.println(String.format("%-15f_", n));
System.out.println(String.format("%.3f_", n));
System.out.println(String.format("%.2f_", n));
System.out.println(String.format("%15.2f_", n));
System.out.println(String.format("%-15.2f_", n));
System.out.println(String.format("%015f_", n));
System.out.println(String.format("%015.2f_", n));
3.4
123.45678

3.400000_
123.456780_
123.456780_
     123.456780_
123.456780     _
123.457_
123.46_
         123.46_
123.46         _
00000123.456780_
000000000123.46_

floating point 표현법의 기본 설정인 %f는 %.6f 와 같습니다.(ln 7~9)
%15.2f 는 글자 길이 15, 소수점 아래 2자로 나타내라는 의미로, .도 글자길이에 포함됩니다.(ln 12~15)
소수점 아래는 반올림하여 출력됩니다.
%d와 마찬가지로, 숫자 %뒤의 정수부 앞에 0을 붙이면, 왼쪽에 공백으로 표시될 부분을 0으로 채워줍니다(ln 16~17)


4. Locale 설정

String.format(포맷, 값);
위에서는 String.format 메서드에 2개의 인자값을 넣어 실습을 해보았습니다.

같은 메서드명의 overloading 된 String.format(Locale, 포맷, 값); 메서드를 이용하면 국가별 포맷 설정이 가능합니다.
아래의 예시를 봅시다.

int money = 35000;
Date today = new Date();

System.out.println(String.format("₩ %,d", money));
System.out.println(String.format(Locale.GERMANY, "%,d €", money));
System.out.println(String.format("%tp", today));
System.out.println(String.format(Locale.ENGLISH, "%tp", today));
₩ 35,000
35.000 €
오후
pm

Locale을 설정하지 않을 경우, 기본적으로는 OS에 설정되어있는 값이 default로 적용됩니다.
GERMANY에서 사용하는 금액 단위인 유로화는 3자리 구분자를 .을 이용하기 때문에 3자리수 단위로 .이 표기되며,

 


오전 오후를 표시하는 포맷인 %tp의 경우에도 기본값으로는 '오후'를, Locale.ENGLISH에서는 'pm'을 출력합니다.


5. %t (= DateTime Formatting)
  • y: 연, year
  • M: 월, month
  • d: 일, day of month
  • H: 시, 24-hour
  • h: 시, 12-hour
  • M: 분, minute
  • s: 초, second
Date n = new Date();
System.out.println(n +"\n");
System.out.println(String.format("%%tF(yyyy-MM-dd): %tF", n));
System.out.println(String.format("%%tT(02H:02m:02s): %tT, %%tR(02H:02m): %tR", n, n));
System.out.println(String.format("%%ty(2y): %ty, %%tY(4y): %tY", n, n));		
System.out.println(String.format("%%tm(02M): %tm", n));		
System.out.println(String.format("%%td(02d): %td, %%te(d): %te", n, n));

System.out.println(String.format("%%tH(02H): %tH", n));
System.out.println(String.format("%%tM(02m): %tM", n));
System.out.println(String.format("%%tS(02s): %tS", n));

System.out.println(String.format("%%tZ(time zone): %tZ, %%tz(time zone offset): %tz", n, n));
Thu Mar 05 14:07:09 KST 2020

%tF(yyyy-MM-dd): 2020-03-05
%tT(02H:02m:02s): 14:07:09, %tR(02H:02m): 14:07
%ty(2y): 20, %tY(4y): 2020
%tm(02M): 03
%td(02d): 05, %te(d): 5
%tH(02H): 14
%tM(02m): 07
%tS(02s): 09
%tZ(time zone): KST, %tz(time zone offset): +0900

기본적으로 시간 및 날짜 형식에는 leading-0s를 붙입니다.
가장 많이 이용될 포맷 형식은 %tF %tT로, 날짜와 시각을 연-월-일 시:분:초 로 나타냅니다.
연월일을 yyMMdd 형태로 출력(leading-0s 포함)하고 싶을 때엔 %ty%tm%d
시분초를 HH:mm:ss 형태로 출력(leading-0s 포함)하고 싶을 때엔 %tH%tM%tS

※ 포맷에 %문자를 쓰고 싶다면 %% 와 같이 % 문자를 2번 쓰면 됩니다.

 

++ 더보기

그 밖에 다양한 포맷형식을 제공하는데, 아래를 참고하여 원하는 포맷을 이용하면 됩니다.

System.out.println(String.format("%%tA(day of Week, Full name): %tA, %%ta: %ta", n, n));
System.out.println(String.format("%%tB(month, Full name): %tB, %%tb: %tb", n, n));
System.out.println(String.format(Locale.ENGLISH, "%%tB(month, Full name): %tB, %%tb: %tb", n, n));
System.out.println(String.format("%%tc(= %%ta %%tb %%td %%tT %%tZ %%tY): %tc", n));
System.out.println(String.format("%%tD(MM/dd/yy): %tD", n));
System.out.println(String.format("%%td(02d): %td, %%te(d): %te", n, n));
System.out.println(String.format("%%tF(yyyy-02M-02d): %tF", n));
System.out.println(String.format("%%tH(02H, 00-23): %tH, %%tk(H, 0-23): %tk", n, n));
System.out.println(String.format("%%tI(02h, 01-12): %tI, %%tl(h, 1-12): %tl", n, n));
System.out.println(String.format("%%tj(day of Year, 001-366): %tj", n));
System.out.println(String.format("%%tp(오전 또는 오후): %tp", n));
%tA(day of Week, Full name): 목요일, %ta: 목
%tB(month, Full name): 3월, %tb: 3월
%tB(month, Full name): March, %tb: Mar
%tc(= %ta %tb %td %tT %tZ %tY): 목 3월 05 14:07:09 KST 2020
%tD(MM/dd/yy): 03/05/20
%td(02d): 05, %te(d): 5
%tF(yyyy-02M-02d): 2020-03-05
%tH(02H, 00-23): 14, %tk(H, 0-23): 14
%tI(02h, 01-12): 02, %tl(h, 1-12): 2
%tj(day of Year, 001-366): 065
%tp(오전 또는 오후): 오후

참고로, %tB와 %tb는 한글로는 똑같이 출력되는데 영어에서는 February, Feb 이렇게 표현됩니다.


6. %c (= Unicode char Formatting)

숫자를 유니코드로 변환해줍니다.

System.out.println("Unicode 코드 → 문자");
System.out.println(String.format("48 → %c, 57 → %c", 48, 57));
System.out.println(String.format("65 → %c, 90 → %c", 65, 90));
System.out.println(String.format("97 → %c, 122 → %c", 97, 122));
System.out.println(String.format("44032 → %c, 55203 → %c", 44032, 55203)); //  U+AC00, U+D7A3
Unicode 코드 → 문자
48 → 0, 57 → 9
65 → A, 90 → Z
97 → a, 122 → z
44032 → 가, 55203 → 힣

U+AC00 = (163 * 10)+(162 * 12) = 44032
U+D7A3 = (163 * 13)+(162 * 7)+(16 * 10)+3 = 55203


7. %o, %x (= Octal/Hex Formatting)
int n = 100;
System.out.println(String.format("10진수(%d) : 2진수(%s), 8진수(%o), 16진수(%x)", n, Integer.toBinaryString(n), n, n));
10진수(100) : 2진수(1100100), 8진수(144), 16진수(64)

1100100(2) = 1/100/100 → 1/22/22 = 144(8)
1100100(2) = 110/0100 → 22+21/22 = 64(16)

728x90
반응형
728x90
반응형

parameter에 대한 적절한 설정은 좋은 performance를 내는 데 중요한 요인이 된다. 

 

이들 parameter에 대한 자세한 이해를 통해 효과적인 lob segment를 생성할 수 있다. 

참고로 lob에 대한 자세한 정보를 보려면 dba/all/user_lobs를 조회하면 알 수 있다.

 

/***************************************************************************************************** 

    (column list)
    [physical attributes]
    [storage clause]
    [LOB (<lobcol1> [, <lobcol2>...])
        STORE AS
            [<lob_segment_name>]
            (
                [TABLESPACE <tablespace_name>]
                [{ENABLE | DISABLE} STORAGE IN ROW]
                [CHUNK <chunk_size>]
                [PCTVERSION <version_number>]
                [ { CACHE | NO CACHE [{LOGGING | NOLOGGING}]
                          | CACHE READS [{LOGGING | NOLOGGING}]
                  }
                ]
                [<storage_clause_for_LOB_segment>]
                [INDEX [<lob_index_name>] [physical attributes] [<storage_for_LOB_index>] ]
            )
    ]
    [LOB (<lobcol1> [, <lobcol2>...]) ... ]

*****************************************************************************************************/

 

CREATE TABLE demolob ( A NUMBER, B CLOB )
    STORAGE (INITIAL 256 NEXT 256) 
    TABLESPACE user_data 
    LOB(b) STORE AS demolob_seg ( 
        TABLESPACE lob_tb
        STORAGE (INITIAL 6144 NEXT 6144) 
        CHUNK 4
        PCTVERSION 20
        NOCACHE LOGGING
        ENABLE STORAGE IN ROW 
        INDEX demolob_idx (
            TABLESPACE lob_tb
            STORAGE ( INITIAL 256 NEXT 256 ) 
            ) 
        );
 


1) TABLESPACE와 storage parameter

- lob, lob index에 대한 tablespace를 지정하지 않는 경우, 해당 table이 저장되는 tablespace에 같이 저장되게 된다. 

  lob 컬럼, lob index, table 에 대해 tablespace를 각기 지정하는 것이 contention을 줄일 수 있어 보다 효과적이다. (최소한      lob 컬럼과 다른 컬럼들을 구분하여 별개의 tablespace에 저장하도록 지정하는 것이 바람직하다.)

- lob index는 lob 컬럼의 내부적 저장 위치를 연결시켜주는 indicator를 저장한 index이다. 

  default로 제공받는 index명은 이해하기 어렵기 때문에 lob index명을 지정하여 사용하는 것이 편하다.

- lob index에 대한 parameter 변경은 alter index문을 이용하지 않고, alter table문을 이용하여야 한다. 단, index명을 바꿀 

  수는 없다.


2) PCTVERSION


- 데이타를 변경할때는 read consistency를 위해 undo 정보를 저장할 필요가 있다. 

  그러나 LOB 데이타인 경우, 그 크기가 크기때문에 undo 정보 유지하기에는 많은 어려움이 따르기 때문에, 

  대신에 old version 데이타를 유지하는 방법으로 read consistency를 제공하고 있다. 

  pctversion은 old version lob data가 차지하는 percentage를 의미한다. 

 

  예를들어 default value가(10) 적용되었다면, 새로운 lob data가 old version의 10%가 저장될때 까지는 old version을 간직  

  하고 있다가, 이 이상 크기가 되면 바로 old version data를 reclaim하고, 이 space를 재사용 즉, overwrite 하게 된다. 

- pctversion을 큰 값을 지정한 경우, old version을 저장하기 위해 보다 많은 space가 필요하게 된다. 

  하지만 update가 많은 작업인 경우에는 이 값을 높게 잡아 다음과 같은 에러를 피할 수 있을 것이다.

    ORA-01555: snapshot too old: rollback segment number with name "" too small
    ORA-22924: snapshot too old

- 만약 lob data가 read-only인 경우라면, pctversion은 0으로 설정할 수 있다.
  * 읽기 요청이 많으면서 동시에 LOB 변경(20% 이상)
  * 읽기 요청이 대부분이며 변경이 거의 없음(5% 이하)


- pctversion 변경 

SQL> ALTER TABLE demolob MODIFY LOB(b) (PCTVERSION 10);

3) CACHE/NOCACHE

- 자주 access되는 경우라면, cache를 선택하여 사용한다. default는 nocache이다.

- in-line lob은 영향을 받지 않는다. 즉, in-line lob은 다른 데이타와 마찬가지로 buffer cache에서 바로 읽혀지기 때문이다.

- CACHE_SIZE_THRESHOLD limit이 적용되지 않기 때문에 cache할 때는 주의해야 한다. 

- cache/nocache 변경 
    

SQL> ALTER TABLE demolob MODIFY LOB (b) ( CACHE/NOCACHE );

4) CHUNK(디폴트 block size)


- lob data를 access하는 단위로써, db_block_size의 배수로 설정한다.
  lob 데이타가 저장될 initial extent, next extent는 chunk의 배수로 설정하는 것이 좋다. 

  만약 db_block_buffer가 2K이고, chunk를 3K로 설정했다면 chunk는 4K로 조정 되어 적용된다.


- chunk는 in-line lob에는 영향을 주지 않고, out-line lob에만 영향을 준다. 

  예를들어 chuk를 32K로 설정하고, disable storage in row를 설정했다면 1K의 데이타를 저장할때도 32K가 lob segment에 

  할당된다. 


- lob table이 생성된 이후에는 변경할 수 없다. 


5) LOGGING/NO LOGGING


- redo 정보를 생성할 것인지 여부를 결정하는 parameter이다. 


- cache option을 사용하는 경우는 무조건 logging을 의미한다.


- logging, nologging에 상관 없이 undo 정보는 lob index에 대해서만 생성되고고, lob 데이타에 대해서는 생성하지 않는다.


- logging인 경우는 redo 정보를 생성하고, bulk load나 대량의 insert를 하는 경우 nologging을 설정하여 redo 정보를 생성 

  하지 않도록 할 수 있다.


- logging/no logging 변경
    

SQL> ALTER TABLE demolob MODIFY LOB(b) (NOCACHE NOLOGGING);

6) ENABLE/DISABLE STORAGE IN ROW

- 4k 이하의 data를 in-line에 저장할 지 여부를 결정한다.


- enable인 경우 (default)

  4k 이하의 lob은 in-line으로, 즉 테이블에 저장하고, 4k 보다 큰 경우에는 out-line 즉, lob segment에 저장된다. 

  이때 4K는 control 정보를 포함한 크기로써, 실제 in-line으로 저장할 수 있는 최대 크기는 3964 byte이다. 

  4K 이상의 데이타는 lob segment에 저장되지만, 36 - 84 bytes의 information 정보는 in-line에 남게 된다. 


- disable인 경우
  모든 datas는 out-line으로 저장된다. 20 byte lob locator만 in-line으로 저장되어 lob index에서 해당 lob block을 찾을 수
  있도록 해준다.


- in-line lob인 경우에는 다른 데이타 타입처럼 REDO, UNDO 정보가 기록된다. 그러나 out-line인 경우에는 column locator

  와 LOB INDEX가 변경되는 경우에만 UNDO 정보를 기록한다. 즉, lob segment에 대해서는 undo 정보를 만들지 않는다.


- lob 컬럼에 대한 access가 많지 않은 경우는 disable을 설정하는 것이 바람직하다. High Water Mark를 작게 유지될 수 있기    때문에 특히, full table scan을 자주 하는 table인 경우 유용하다.


- lob table이 생성된 이후에는 변경할 수 없다.

 

 

 

 

<LOB 생성시 주의사항>


LOB은 데이터의 속성상, 다른 데이터타입에는 없는 다양한 옵션들이 존재한다. 

부주의하게 사용할 경우 많은 성능문제를 야기할 수 있다. LOB 생성시 다음과 같은 사항들에 주의해야 한다.

 

1. enable storage in row 옵션을 사용하는 경우 4000 bytes 보다 작은 LOB 데이터는 로우와 같은 블록에 저장된다. 
    따라서 Row chaining을 유발할 가능성이 높다. 
    4000 bytes보다 큰 LOB 데이터는 disable storage in row 옵션을 사용한 것과 같은 효과가 있다. 
    LOB 데이터의 크기를 고려하여 만일 Row chaining이 발생할 가능성이 높다고 판단되면 disable storage in row 옵션을 

    사용하는 것이 좋다. 

    로우와 같은 블록에 저장되는 LOB 데이터를 In-line LOB이라고 부르며, LOB 세그먼트에 저장되는 경우에는 Out-of-line 

    LOB이라고 부다.

 

2. disable storage in row 옵션을 사용하는 경우 LOB 데이터는 별도의 LOB 세그먼트에 저장되며 Row 내에는 20 bytes의 
    LOB Locator 정보만 저장된다. 이 경우 언두 데이터는 LOB Locator에 대해서만 생성된다. LOB 데이터에 대한 실제적인 
    언두 정보는 언두 테이블스페이스에 저장되지 않고 같은 LOB 세그먼트 내에 저장됨에 유의해야 한다. 

    LOB 세그먼트의 언두는 PCTVERSION 옵션에 의해 제어되는데, 가령 PCTVERSION이 50이면 LOB Segment의 공간 중          50%가 언두 정보를 저장하는데 사용된다. 

    따라서 PCTVERSION을 낮게 주는 경우 예기치 않은 ORA-01555 : snapshot too old 에러가 생길 수 있다. 
    LOB 세그먼트의 언두 영역 부족에 따른 snapshot too old 에러의 경우 rollback segment name이 공백으로 나온다. 
    PCTVERSION이 너무 작으면 ORA-01555 에러가 발생할 확률이 높아지고, PTCVERSION이 너무 높으면 공간의 낭비가 

    심해진다. 
    이 문제를 해결하는 방법은 일반 롤백 세그먼트에서의 ORA-01555 에러의 경우와 동일하다. 

    PCTVERSION을 적절히 유지하고 불필요한 커밋을 줄인다. LOB 세그먼트의 확장공간을 적절히 확보해주는 것도 중요하다.

 

3. CACHE / NOCACHE, LOGGING / NOLOGGING : 만일 LOB 데이터의 크기가 크고 자주 액세스되지 않거나, 무작위적으로 
    액세스된다면 NOCACHE 옵션을 사용하는 것이 바람직하다. NOCACHE 옵션을 사용하는 경우 리두를 생성할 지의 여부도      지정할 수 있다. 

    만일 반드시 복구가 될 필요가 없는 데이터라면 Nologging 옵션을 사용함으로써 성능개선효과를 얻을 수 있다. CACHE 

    옵션을 사용하는 경우에는 반드시 Logging 속성을 지니게 된다. NOCACHE 옵션을 사용하는 경우 버퍼 캐시를 경유하지

    않기 때문에 direct path read(lob), direct path write(lob) 이벤트를 대기하게 된다. 하지만 CACHE 옵션을 사용하는 경우에

    는 버퍼 캐시를 경유하기 때문에 db file sequential read 와 latch: cache buffers chains 대기를 유발할 수 있다.

 

4. 청크(chunk)의 크기 : Out-of-line LOB인 경우 청크 단위로 LOB 데이터를 저장하게 된다. 

    큰 청크 사이즈의 문제는 공간이 낭비될 가능성이 높다는 것이다. 만일 청크가 8K로 되어있는데, 1K 크기의 LOB 데이터가      삽입된다면 나머지 7K의 공간은 사용할 수 없게 된다. 따라서 청크 사이즈를 결정할 때는 대상이 되는 LOB 데이터의 크기      를 고려해서 결정해야 다. 

    청크의 크기 단위는 기본적으로 블록 사이즈의 배수가 된다. 

    만일 블록 사이즈가 8K인 경우 청크의 크기를 5000 bytes로 주면 오라클은 암묵적으로 8192 bytes로 변환한다. 청크의 

    크기를 지나치게 작게 하는 경우에는 연속적으로 청크를 할당받는 과정에서 오버헤드가 발생하게 된다.

728x90
반응형

+ Recent posts