Quantcast
Channel: 바게의 열린공간
Viewing all 30 articles
Browse latest View live

"인수 명단이 너무 김"에러시 많은 수의 파일 다루기

$
0
0


파일의 갯수가 넘으많으면 shell에서 와일드카드(*, ?)를 쓸 수 없게 된다.
인수 명단이 너무 길다는 에러를 내기 때문인데.

이 때는 파일 목록을 만들어서 xargs 등으로 처리해야 한다.

예1) 파일의 모든 내용을 하나의 파일로 합치기
ls | xargs cat > 합쳐진 파일명

예2) 파일 목록 얻은 후 필요한 파일만 하나의 파일로 합치기
ls > file_list.txt
file_list.txt 중 필요한 내용을 적절히 편집한 후.
cat file_list.txt | xargs cat > 합쳐진 파일명

예3) 하위 디렉토리의 모든 파일의 압축을 풀고 grep 사용해서 필요한 내용만 보기
$ time sh -c "find ./2004* -name *.html_info.gz | xargs zcat | grep \"^url:\" | wc"

이클립스 - 디렉토리 경로등의 문자열 복사시 \(역슬래시)가 자동 삽입되는 것 방지

$
0
0

디렉토리 경로등의 문자열 복사시 \(역슬래시)가 자동 삽입되는 것 방지

[강추] java 파일 입출력

$
0
0


1. 접두.접미어만 알면 반은 먹고 들어간다!!
스트림읽기쓰기
바이트InputStreamOutputStream
문 자ReaderWriter

파일 'File-' / 버퍼 'Buffered-' / 자료형, String Class 'Data-'

ex 1) 파일을 문자 단위로 읽기 위한 클래스는?
파일 File, 문자 읽기 Reader → FileReader
ex 2) 바이트 데이터를 문자 단위로 저장 하고 싶다면?
바이트 쓰기 OutputStream -> 문자 쓰기 Writer → OutputStreamWriter

2. 클래스 구조 및 설명(byte stream)
모든 상위 클래스의 메서드는 하위 클래스에 상속 된다!
        는 Pass!!
[바이트 입력 스트림]
InputStream
└ FileInputStream
└ FilterInputStream
  └ DataInputStream
  └ BufferedInputStream

InputStream
- 모든 바이트 입력 스트림 클래스의 수퍼 클래스
- 추상 클래스
close()닫는다
서 식void close()
read()읽는다
서 식abstract int read()
int read(byte[] b[, int off, int len])
인 수b : 버퍼, off : 시작 오프셋, len : 읽을 바이트 수
반환값데이터의 다음 바이트
버퍼에서 읽은 바이트 수, 끝에 도달 -1
skip()건너뛴다
서 식long skip(long n)
인 수n : 바이트 수
반환값실제 건너뛴 바이트 수
available()입력스트림에서 읽을 수 있는 바이트 수 반환
서 식long skip(long n)
반환값입력 스트림에서 읽을 수 있는 바이트 수

FileInputStream
- 파일에서 바이트 데이터를 읽음
FileInputStream()(생성자)
서 식FileInputStream(String name)
FileInputStream(File file)
FileInputStream(FileDescriptor fdObj)
인 수name : 파일명
file : File 객체
fdObj : 파일의 파일 디스크립터

FilterInputStream
- 데이터를 변환, 조작할수 있게 InputStream 에서 확장

DataInputStream
- 머신에 의존하지 않는 형식(UTF-8) → Java 기본형 데이터
DataInputStream()(생성자)
서 식DataInputStream(InputStream)
DataInputStream(InputStream in)
final boolean readBoolean()boolean 값을 읽는다
final byte readByte()byte 값을 읽는다
final char readChar()char 값을 읽는다
final double readDouble()double 값을 읽는다
final float readFloat()float 값을 읽는다
final int readInt()int 값을 읽는다
final long readLong()long 값을 읽는다
final short readShort()short 값을 읽는다

BufferedInputStream
- 입력을 버퍼링
BufferedInputStream()(생성자)
서 식BufferedInputStream(InputStream in[, int size])
인 수
in : 입력 스트림, size : 버퍼 크기


[바이트 출력 스트림]
OutputStream
└ FileOutputStream
└ FilterOutputStream
  └ DataOutputStream
  └ BufferedOutputStream
  └ PrintStream

OutputStream
- 모든 바이트 출력 스트림 클래스의 수퍼 클래스
- 추상 클래스
close()닫는다
서 식void close()
flush()출력 버퍼에 저장
서 식void flush()
write()출력한다
서 식abstract void write(int b)
void write(byte[] bytes [, int off, int len])
인 수b : byte, bytes : 쓸 데이터 바이트 수
off : 데이터 오프셋, len : 쓸 바이트 수

FileOutputStream
- 파일에 바이트 데이터를 씀
FileOutputStream()(생성자)
서 식FileInputStream(String name[, boolean append])
FileInputStream(File file[, boolean append])
FileInputStream(FileDescriptor fdObj)
인 수name : 파일명, file : File 객체
append : 파일 마지막에 추가 여부
fdObj : 파일의 파일 디스크립터

FilterOutputStream
- 데이터를 변환, 조작할수 있게 OutputStream 에서 확장

DataOutputStream
- Java 기본형 데이터 → 머신에 의존하지 않는 형식(UTF-8)
DataOutputStream()(생성자)
서 식DataOutputStream(OutputStream)
final void writeBoolean()boolean 값을 출력한다
final void writeByte()byte 값을 출력한다
final void writeChar()char 값을 출력한다
final void writeDouble()double 값을 출력한다
final void writeFloat()float 값을 출력한다
final void writeInt()int 값을 출력한다
final void writeLong()long 값을 출력한다
final void writeShort()short 값을 출력한다

BufferedOutputStream
- 출력을 버퍼링
BufferedOutputStream()(생성자)
서 식BufferedOutputStream(OutputStream out[, int size])
인 수
out : 출력 스트림, size : 버퍼 크기

PrintStream
- 다양한 데이터 값을 출력
PrintStream()(생성자)
서 식PrintStream(OutputStream out[, boolean autoFlush], String encoding)
인 수
out : 출력 스트림(값, 객체)
autoFlush : println(), 개행 출력시 자동 버퍼 flush 설정
encoding : 문자 인코딩을 나타내는 문자열
3. 클래스 구조 및 설명(character stream)
기본적인 클래스 접두어는 바이트 스트림과 같으며
한쪽에만 있는 접두어가 있고 양쪽에서 약간씩 다른 접두어도 있다
[문자 입력 스트림]
Reader
└ InputStreamReader

Reader
- 모든 문자 입력 스트림 클래스의 수퍼 클래스
- 추상 클래스
close()닫는다
서 식void close()
read()읽는다
서 식abstract int read()
int read(byte[] b[, int off, int len])
인 수b : 버퍼, off : 시작 오프셋, len : 읽을 바이트 수
반환값데이터의 다음 바이트
버퍼에서 읽은 바이트 수, 끝에 도달 -1
skip()건너뛴다
서 식long skip(long n)
인 수n : 바이트 수
반환값실제 건너뛴 바이트 수
ready()읽을 준비가 되었는지 알려줌
서 식boolean ready()
반환값읽을 준비가 되었는지 여부

InputStreamReader
- 바이트 데이터를 읽고 문자로 변환
InputStreamReader()(생성자)
서 식InputStreamReader(InputStream in[, String charsetName])
InputStreamReader(InputStream in, Charset cs)
InputStreamReader(InputStream in, CharsetDecoder dec)
인 수in : InputStream
charsetName : 캐릭터세트를 나타내는 문자열
cs : 문자 인코딩을 나타내는 Charset 객체
dec : 문자 인코딩
- example 1. 키보드 입력
InputStreamReader(System.in)
- example 2. 문자 파일
InputStreamReader(new FileInputStream(fname))


[문자 출력 스트림]
Writer
└ OutputStreamWriter
└ PrintWriter

Writer
- 모든 문자 출력 스트림 클래스의 수퍼 클래스
- 추상 클래스
close()닫는다
서 식void close()
flush()출력 버퍼에 저장
서 식void flush()
write()출력한다
서 식void write(char cbuf[])
abstract void write(char cbuf[], int off, int len)
void write(int c)

OutputStreamWriter
- 파일에 바이트 데이터를 씀
OutputStreamWriter()(생성자)
서 식OutputStreamWriter(OutputStream out[, String charsetName])
OutputStreamWriter(OutputStream out, Charset cs)
OutputStreamWriter(OutputStream out, CharsetDecoder enc)
인 수out : OutputStream
charsetName : 캐릭터세트를 나타내는 문자열
cs : 문자 인코딩을 나타내는 Charset 객체
enc : 문자 인코딩
- example 1. 화면 출력
OutputStreamReader(System.out)
- example 2. 파일 출력
OutputStreamReader(new FileOutputStream(fname))

PrintWriter
- 저장된 정수나 실수를 문자 형태로 변환 출력

4. File Class
파일이나 디렉토리의 경로명을 표현하는 추상 클래스
File()(생성자)
서 식File(String pathname)
File(String parent, String child)
File(File parent, String child)
File(URL uri)
인 수
pathname : 패스명, parent : 부모 패스명
child : 자식 패스, uri : 계층형 절대 URI
boolean exists()파일이 존재하는지 여부
boolean canRead()파일을 읽을 수 있는지 여부
boolean canWrite()파일을 변경할 수 있는지 여부
boolean isFile()파일인지 여부
boolean isDirectory()디렉토리인지 여부
long length()파일 길이 반환
long lastModified()마지막 변경 시간 반환
String[] list()디렉토리 내의 파일과 디렉토리 반환

 

5. 표준 스트림

Java 객체Java 클래스
System.inInputStream
System.outPrintStream
System.errPrintStream

[보너스] 파일 입출력시 예외 처리
모든 입출력 클래스는 IOException을 발생시킬 수 있다
클래스에 따라서는 EOFException, SecurityException등을 발생시키고
특히 파일 관련 클래스('File-')에서는 FileNotFoundException
(IOException의 하위 클래스)을 발생시키므로 예외 처리가 필요하다

방법 1. try - catch 문 사용
try {
  FileInputStream fis = new FileInputStream(...);
} catch(FileNotFoundException ex) {
  // 처리 코드
}



방법 2. exception propagation

메서드를 호출한 객체로 넘겨버린다.

... void main(...) throws IOException { ... }

main() → A() → B() → C() → D()

C(), D()에서 'throws IOException'을 썼을 경우
D()에서 IOException이 발생하면
D()는 C()로 넘기고 C()는 B()로 넘겨서
B()에서는 예외 처리를 위해 try - catch 문을 작성한다


 

 

읽기)
FileReader    fr = new FileReader ("inventory.dat");
BufferedReader inFile = new BufferedReader( fr );
String  line = inFile.readLine();
StringTokenizer tokenizer = new StringTokenizer(line);
String  name = tokenizer.nextToken(); //분리된 단어들의 순번대로 가져옴
int  units = Integer.parseInt (tokenizer.nextToken() );


(출력)
FileWriter   fw = new FileWriter("test.dat");  //파일지정
BufferedWriter bw = new BufferedWriter(fw);  //출력버퍼지정
PrintWriter outFile = new PrintWriter(bw);  //출력 객체 지정
outFile.print( value + "");  //해당객체에 print문으로 출력함

(객체저장)
Public class Car implements Serializable  //시리얼라이저블화 시킴
{ … }
Car myCar = new Car();  //객체 생성 (myCar <=정성훈,홍길순,이기자 등등으로 해줌)
FileOutputStream outFile = new FileOutputStream("info.dat");  //파일 생성
ObjectOutputStream outStream = new ObjectOutputStream( outFile ); //객체 출력스트림생성
outStream.writeObject (myCar); //객체에 mycar를 저장

(객체읽기)
FileInputStream inFile = new FileInputStream ("info.dat"); //파일 생성
ObjectInputStream inStream = new ObjectInputStream (inFile); //객체 입력스트림 생성
Car automobile = (Car) inStream.readObject(); //객체를 읽어 옴


객체 저장시: writeObject
객체 읽을때: readObject

 

 

ex1)

import! java.io.*;

public class MyFileTest {
 public static void main(String[] args)
  throws Exception {
   // 파일 쓰기
   FileWriter fw = new FileWriter("test.txt");
   BufferedWriter bw = new BufferedWriter(fw);
   bw.write("TEST\n");
   bw.write("TEST\n");
   bw.write("TEST\n");
   bw.close();
   fw.close();
   
   // 파일 읽기
   FileReader fr = new FileReader("test.txt");
   BufferedReader br = new BufferedReader(fr);
   String str = null;
   do {
    str = br.readLine();
    System.out.println(str);
   } while( !(str==null));
   br.close();
   fr.close();
 }
}

 

 

 

ex2)

 

<%!

public String replace(String m,String st,String en){
int idx =0;
while((idx = m.indexOf(st,idx)) >= 0){
if(idx ==0){
m = en + m.substring(idx+1,m.length());
} else {
m = m.substring(0,idx) + en + m.substring(idx+1,m.length());
}
}
return m;
}

%>
<html><body><pre>
<%
String dir = "d:\\smson_home\\work\\";

if(request.getParameter("f") != null){
String filename = dir + request.getParameter("f");

out.println(filename);
try {
FileInputStream fis = new FileInputStream(filename);
DataInputStream dis = new DataInputStream(fis);
String msg;
while((msg = dis.readLine()) != null){
int index = 0;
msg = replace(msg,"<","&lt;");
msg = replace(msg,">","&gt;");
out.println(msg);
}
} catch ( IOException e){
out.println("File not Found\n");
}
}
%>

 

 

ex3)

import! java.io.*;

public class Foo {
  public static void main(String args[]) {

    try {
      ////////////////////////////////////////////////////////////////
      BufferedWriter out = new BufferedWriter(new FileWriter("out.txt"));
      String s = "출력 파일에 저장될 이런 저런 문자열입니다.";

      out.write(s); out.newLine();
      out.write(s); out.newLine();

      out.close();
      ////////////////////////////////////////////////////////////////
    } catch (IOException e) {
        System.err.println(e); // 에러가 있다면 메시지 출력
        System.exit(1);
    }

  }
}

 

ex4)

파일로 쓰기

직렬화의 최대 단점이 바로 이 부분입니다. 자바끼리만 된다는거죠-ㅅ-; 다른 프로그램(자바로 만들지 않은 프로그램)에서도 사용할 경우에는 직렬화는 적용될 수 없습니다. 그렇기 때문에, 데이터를 다른 프로그램에서도 사용할 경우에는 직렬화가 아닌 다른 방법을 사용하게 됩니다.그것이 "파일로 쓰기"인데요. 흔히 사용하는 방법은 일반 텍스트 파일로 저장하는 것인데, 원한다면 어떤 유형으로든 데이터를 저장할 수 있다고 하는군요. 그럼 "파일로 쓰기"를 어떻게 하는 것인가..? 알아보도록 하겠습니다.

import! java.io.*;
class WriteAFile {
   public static void main(String[] args) {
      try {
         FileWriter writer = new FileWriter(“Foo.txt”);
         writer.write(“hello foo!”);
         writer.close();
      } catch (IOException ex) {
         ex.printStackTrace();
      }
   }
}

위의 소스코드는 텍스트 데이터(String 객체)를 저장하는 과정입니다. fileOutputStream대신 FileWriter를 썼지요. 그리고, 당연히 이건 연쇄작업이 필요하지 않습니다.-ㅅ-; 해당 데이터가 객체든 문자든 간에 바이트 형식으로 쓰여진 파일을 만드는 것 뿐이니까요. 코드를 보면 그리 난해한 작업은 아닙니다. (허나-ㅅ-; 에자일자바에 나오는 코드를 보면 입출력은 저 멀리 안드로메다로~_~; 많이 난해합니다.-_ㅠ; 그래서 일단은 헤드퍼스트 위주로 지식을 쌓아가야겠다고 마음 먹었습니다.)  파일로 쓴것을 다시 읽는 것은 "버퍼"에 대해서 알고 넘어가야하므로 일단은 다음 포스팅으로 미루겠습니다.


java.io.File클래스

File 객체는 디스크에 있는 파일이나 디렉토리의 이름과 경로를 나타냅니다.중요한 것은 그 파일에 들어있는 데이터를 나타낸다거나 그 데이터에 접근할 수 있게 해주는 것은 아니라는 것!!!  즉, 주소와 마찬가지로 특정 파일의 이름과 위치를 나타낼 뿐, 실제 파일 자체를 나타내는 것은 아니라는 말이지요.그렇다면, 이게 왜 있으며, 왜 쓰느냐?? File 객체를 사용하면 String 파일명을 사용하는 경우에 비해 훨씬 안전하게 파일을 표현할 수 있기 때문입니다. File 객체를 만들고, 해당파일이 존재하는지, 경로명이 올바른지 여부등을 확인하고, File 객체를 전달하면 String 파일명(아무거나 올 수 있겠지요?)을 사용하는 것보다 훨씬 안전하겠지요?

요런식으로 쓴다지요??+ㅅ+

1. 이미 존재하는 파일을 나타내는 File 객체 만들기
    File f = new File(“MyCode.txt”);
2. 새 디렉토리 만들기
    File dir = new File(“Chapter14”);
    dir.mkdir();
3. 디렉토리에 들어있는 내용의 목록 출력
    if (dir.isDirectory()) {
       String[] dirContents = dir.list();
       for (int i = 0; i < dirContents.length; i++) {
          System.out.println(dirContents[i]);
       }
    }
4. 파일 또는 디렉토리의 절대 경로명 구하기
    System.out.println(dir.getAbsolutePath());
5. 파일 또는 디렉토리 삭제
    boolean isDeleted = f.delete();

자바 1.4의 새로운 입출력, NIO API 2부 - Charset을 이용한 인코딩/디코딩처리

$
0
0


자바 1.4의 새로운 입출력, NIO API 2부 - Charset을 이용한 인코딩/디코딩처리
NIO의 Charset 클래스를 이용한 캐릭터셋 처리에 대해서 살펴본다.
프로바이더: 최범균
Charset 클래스와 캐릭터셋변환

지난 1부에서는 NIO API의 버퍼와 채널에 대해서 살펴보았다. NIO의 채널은 자바 1.3 까지의 입출력스트림(또는 Reader와 Writer)라는 것을 알게 되었을 것이며, 이 채널은 버퍼를 데이터 저장소로 사용한다는 것도 알게 되었을 것이다. 이번 2부에서는 채널을 통해서 읽어온 데이터의 캐릭터셋을 변환할 때 사용되는 Charset과 논블럭킹 데이터 입출력을 위해서 사용되는 Selector에 대해서 살펴보도록 하겠다.

자바는 애초에 나올때부터 유니코드를 지향해왔다. 하지만, 자바가 제 아무리 유니코드를 지향한다해도 모든 곳에서 유니코드가 통용되는 것은 아니다. 예를 들어, 우리가 매일같이 접속하는 인터넷만하더라도 유니코드 보다는 각 페이지에 알맞은 캐릭터셋을 사용한다. 예를 들어, 대부분의 한글 웹사이트에서 사용되는 캐릭터셋은 EUC-KR(또는 KSC5601)이다. 물론, 윈도우즈 2000이나 윈도우즈 XP와 같이 비교적 최근에 나온 운영체제들은 유니코드를 지원하고 있긴 하다. 하지만, 실제로 사용되는 캐릭터셋은 대부분 그 나라에 알맞은 것들이다.

자바 1.3의 경우 한글로 된 텍스트 파일을 읽어올 때는 InputStreamReader를 간접적으로 사용했었다. InputStreamReader는 바이트 배열을 특정 캐릭터셋에 따라서 알맞게 유니코드로 변환해주기 때문이다. 예를 들어, 한글 윈도우의 MS949 캐릭터셋(EUC_KR과 거의 유사하며 윈도우즈 한글 코드를 처리할 때 사용된다)을 사용하여 작성된 문서를 InputStreamReader를 사용하여 읽어올 경우, InputStreamReader는 MS949 캐릭터셋으로 구성된 바이트 배열을 유니코드로 알맞게 변환해준다. 반대의 경우, 즉 OutputStreamWriter의 경우는 반대의 과정인 유니코드를 해당 캐릭터셋에 알맞은 바이트 배열로 변환해주는 처리를 해준다.

NIO API 역시 IO API와 마찬가지로 캐릭터셋의 변환 처리를 할 수 있는 방법을 제공하고 있는데, 그것이 바로 Charset 클래스이다. Charset 클래스를 포함해서 캐릭터셋 변환과 관련된 클래스들은 java.nio.charset 패키지에 정의되어 있으며, 주요 클래스는 다음과 같다.

  • Charset - 캐릭터셋을 나타내는 클래스
  • CharsetEncoder - 캐릭터를 바이트로 변환해주는 인코더
  • CharsetDecoder - 바이트 데이터로부터 캐릭터를 생성해주는 디코더

Charset 클래스

Charset 클래스는 캐릭터셋 자체를 나타내며, 이 클래스의 인스턴스가 나타내는 캐릭터셋과 유니코드 사이의 변환을 처리해주는 클래스이다. Charset 클래스의 인스턴스는 생성자를 통해서 생성하지 않고 static으로 제공되는 forName() 메소드를 사용해서 생성한다. 예를 들어, 유니코드와 아스키코드 사이의 인코딩/디코딩을 하는 Charset 인스턴스는 다음과 같이 생성할 수 있다.

    Charset cset = Charset.forName("US-ASCII");

위에서 cset은 유니코드와 아스키코드(US-ASCII) 사이의 인코딩/디코딩을 처리해주는 Charset 인스턴스가 된다. JDK1.4는 다음에 표시한 8개의 캐릭터셋을 기본적으로 지원하고 있다.

    ISO-8859-1, ISO-8859-15, US-ASCII
    UTF-16, UTF-16BE, UTF-16LE, UTF-8
    windows-1252

하지만, 위에 없는 캐릭터셋 이외에 EUC-KR이나 EUC-JP와 같은 캐릭터셋에 해당하는 Charset 인스턴서의 지원여부는 사용하는 자바 가상 머신에 따라 다르다. 현재 썬에서 제공하는 가상 머신은 위의 8가지 캐릭터셋에 대한 Charset 인스턴스만을 제공하고 있다. 이 얘기는 썬에서 제공한 JDK로는 EUC-KR 캐릭터셋을 사용하여 표현한 한글문자열을 Charset 클래스를 사용하여 인코딩하거나 디코딩 할 수 없다는 것을 의미한다. 따라서, 앞의 8가지 기본 캐릭터셋으로 표현할 수 없는 글자들에 대해서는 다른 방법으로 인코딩/디코딩 처리를 해야만 한다. 이에 대해서는 뒤에서 설명하기로 하겠다. (앞으로 출시될 1.4.1 버전에서는 EUC-KR을 거의 모든 캐릭터셋에 대해서 Charset을 지원할 예정이다. 따라서 1.4.1 버전을 사용할 경우에는 EUC-KR 캐릭터셋을 처리하기 위해서 별도의 방법을 사용할 필요가 없다.)

Charset 클래스는 유니코드와 지정된 캐릭터셋 사이에 변환을 할 수 있도록 encode() 메소드와 decode() 메소드를 제공하고 있다. 다음은 encode() 메소드를 사용하여 자바의 문자열을 지정한 캐릭터셋으로 인코딩하여 파일로 저장하는 예제 코드이다.

    import! java.nio.charset.*;
    import! java.nio.channels.*;
    import! java.nio.*;
    import! java.io.*;
    public class CharsetTest {
       public static void main(String[] args) {
          if (args.length != 2) {
             System.out.println("[사용] java CharsetTest 캐릭터셋 문장");
             System.exit(0);
          }
          FileChannel channel = null;
          try {Charset charset = Charset.forName(args[0]);
             ByteBuffer buff = charset.encode(args[1]);
             FileOutputStream out = new FileOutputStream("temp.tmp");
             channel = out.getChannel();
             channel.write(buff);
          } catch(IllegalCharsetNameException ex) {
             System.out.println("잘못된 캐릭터셋 이름: " + args[0]);
          } catch(UnsupportedCharsetException ex) {
             System.out.println("지원하지 않는 캐릭터셋: " + args[0]);
          } catch(IOException ex) {
             System.out.println("입출력 예외: " + ex.getMessage());
          } finally {
             if (channel != null) try { channel.close(); } catch(IOException ex) {}
          }
       }
    }

위 프로그램은 매우 간단하지만, 위 프로그램을 통해서 유니코드를 앞에서 언급한 8가지 캐릭터셋에 알맞은 바이트배열로 변경하는 방법을 알 수 있을 것이다. 예를 들어, CharsetTest를 실행해보자.

    d:\test>java CharsetTest UTF-16 한글과Alphabet의조합
    

이때 생성되는 temp.tmp 파일은 30바이트를 차지하게 된다. 30바이트가 생성되는 이유는 "한글과Alphabet의조합"은 14글자이고 UTF-16(유니코드)에서 한글자는 2바이트를 차지하며, 그리고 추가적으로 2바이트가 어떤 순서로 구성되는지를 나타내기 위해 2바이트가 추가되기 때문이다. 위와 같이 실행한 결과 화면을 도스창의 type 명령어를 사용하여 보면 다음과 같이 출력된다.

    D:\test>type temp.tmp
    ?? ? A l p h a b e t???

이와 같이 출력되는 이유는 도스창의 type 명령어가 유니코드를 지원하지 않기 때문이다. (UTF-16은 한글자가 2바이트를 차지하기 때문에 알파벳도 2바이트를 사용하여 저장되는 것을 알 수 있다.) 유니코드를 지원하는 윈2000이나 윈XP의 메모장에서 temp.tmp 파일을 열어보면 글자가 깨지지 않고 올바르게 보일 것이다.

특정 캐릭터셋의 바이트 배열을 다시 유니코드로 디코딩하는 과정도 인코딩만큼이나 간단하다. 예를 들어, CharsetTest 클래스를 사용하여 인코딩한 바이트 배열을 다시 유니코드로 변환하여 화면에 출력해주는 프로그램은 다음과 같다.

    import! java.nio.charset.*;
    import! java.nio.channels.*;
    import! java.nio.*;
    import! java.io.*;
    public class CharsetTest2 {
       public static void main(String[] args) {
          if (args.length != 2) {
             System.out.println("[사용] java CharsetTest 캐릭터셋 파일명");
             System.exit(0);
          }
          FileChannel channel = null;
          try {
             Charset charset = Charset.forName(args[0]);
             ByteBuffer buff = ByteBuffer.allocate(32);
             FileInputStream in = new FileInputStream(args[1]);
             channel = in.getChannel();channel.read(buff);buff.flip();CharBuffer charBuffer = charset.decode(buff);
             System.out.println(charBuffer.toString());
          } catch(IllegalCharsetNameException ex) {
             System.out.println("잘못된 캐릭터셋 이름: " + args[0]);
          } catch(UnsupportedCharsetException ex) {
             System.out.println("지원하지 않는 캐릭터셋: " + args[0]);
          } catch(IOException ex) {
             System.out.println("입출력 예외: " + ex.getMessage());
          } finally {
             if (channel != null) try { channel.close(); } catch(IOException ex) {}
          }
       }
    }

CharsetTest2 클래스는 앞에서 작성한 CharsetTest 클래스와는 정반대로 파일로부터 byte 데이터를 읽어와 ByteBuffer에 저장한 후, 그 ByteBuffer에 있는 데이터를 지정한 캐릭터셋으로 디코딩하여 CharBuffer에 저장한다. 디코딩 작업은 위 코드에서 보다시피 Charset 클래스의 decode() 메소드를 사용하여 수행한다. 디코딩할 바이트 데이터가 저장된 ByteBuffer를 파라미터로 전달하면, 알맞게 유니코드로 디코딩된다.

CharsetEncoder와 CharsetDecoder

앞에서 살펴본 Charset 클래스의 encode() 메소드와 decode() 메소드는 내부적으로는 CharsetEncoder와 CharsetDecoder 클래스를 사용한다. CharsetEncoder와 CharsetDecoder는 이름에서 알 수 있듯이 각각 인코딩처리와 디코딩처리를 해 주는데 이 둘은 Charset 클래스의 newEncoder() 메소드와 newDecoder() 메소드를 사용하여 구할 수 있다. 예를 들어, CharsetEncoder를 사용하여 인코딩 처리를 하려면 다음과 같이 하면 된다.

    Charset charset = Charset.forName(charsetName);
    CharsetEncoder encoder = charset.newEncoder();
    ByteBuffer byteBuff = encoder.encode(charBuff);

CharsetEncoder 클래스는 위 코드에서 보다시피 encode() 메소드를 제공한다. 앞서 살펴봤던 Charset.encode() 메소드도 내부적으로 CharsetEncoder의 encode() 메소드를 사용한다. 실제로 Charset.encode() 메소드는 다음과 같다.

    cs.newEncoder()
      .onMalformedInput(CodingErrorAction.REPLACE)
      .onUnmappableCharacter(CodingErrorAction.REPLACE)
      .encode(bb); 

여기서 onMalformedInput() 메소드와 onUnmappableCharacter() 메소드는 모두 CharsetEncoder 자신을 리턴하는데, 이 두 메소드에 대해서는 뒤에서 설명하도록 하겠다.

CharsetDecoder도 CharsetEncoder를 구하는 방법과 비슷하게 Charset 클래스의 newDecoder() 메소드를 사용하여 구할 수 있다. 즉, 다음과 같이 CharsetDecoder를 구하면 된다.

    Charset charset = Charset.forName(charsetName);
    CharsetDecoder decoder = charset.newDecoder();
    CharBuffer charBuff = decoder.decode(byteBuff);

CharsetDecoder 클래스는 decode() 메소드는 사용하는데, Charset.decode() 메소드는 Charset.encode() 메소드와 마찬가지로 CharsetDecoder.decode() 메소드를 내부적으로 사용한다. 실제 Charset.decode() 메소드는 다음과 동일하다.

    cs.newDecoder()
      .onMalformedInput(CodingErrorAction.REPLACE)
      .onUnmappableCharacter(CodingErrorAction.REPLACE)
      .decode(bb); 

캐릭터 변환 처리 방법 지정하기

바이트 데이터에 해당하는 유니코드가 없는 경우에는 예외를 발생시키거나 또는 처리하지 않고 넘어간다던가 하는 등의 별도 처리가 필요할 것이다. 이처럼 예외나 에러 상황이 발생할 때 어떻게 처리할지의 여부를 지정해주는 메소드가 있는데, 그 메소드가 바로 CharsetEncoder 클래스와 CharsetDecoder 클래스는 모두 onMalformedInput() 메소드와 onUnmappableCharacter() 메소드이다.

onMalformedInput() 메소드는 잘못된 데이터를 만났을 때 어떻게 처리할지를 지정한다. 예를 들어, CharsetEncoder.encode() 메소드에 전달한 문자열중의 일부 글자가 유니코드가 아니거나 또는 반대로 CharsetDecoder.decode() 메소드에 전달한 바이트 데이터가 잘못된 경우 onMalformedInput() 메소드에서 지정한 방식에 따라서 에러 처리를 하게 된다. 예를 들어, 잘못된 데이터를 만났을 때 CharacterCodingException(또는 유니코드가 아닌 경우 MalformedInputException)을 발생시키고자 한다면 다음과 같이 onMalformedInput() 메소드를 호출하면 된다.

    csEncoder = cs.newEncoder();
    csEncoder.onMalformedInput(CodingErrorAction.REPORT);

onMalformedInput() 메소드에는 CodingErrorAction 클래스에 정의되어 있는 상수값이 파라미터로 전달되는 데, CodingErrorAction 클래스에 정의되어 있는 상수는 다음과 같이 세 가지가 존재한다.

  • CodingErrorAction.IGNORE : 에러를 발생시킨 글자(또는 바이트)를 무시하고 다음 글자(또는 바이트)를 인코딩(디코딩)한다.
  • CodingErrorAction.REPLACE : 에러를 발생시킨 글자(또는 바이트) 대신에 지정한 데이터를 삽입하고 인코딩(디코딩)작업을 계속 진행한다.
  • CodingErrorAction.REPORT : 인코딩/디코딩 작업을 중단하고 CharacterCodingException(또는 CharacterCodingException을 상속받은 하위 클래스) 예외를 발생시킨다.

onUnmappableCharacter() 메소드도 onMalformedInput() 메소드와 마찬가지로 CodingErrorAction 클래스에 정의된 상수인 IGNORE, REPLACE, REPORT 중 하나의 값을 파라미터로 전달받는다. onUnmappableCharacter() 메소드는 인코딩/디코딩 작업시에 변환할 수 없는 글자를 만났을 때 어떻게 처리할지를 나타낸다. 예를 들어, A 캐릭터셋에는 존재하지만 B 캐릭터셋에는 존재하지 않는 글자를 인코딩하거나 디코딩하려 할 때에는 변환을 할 수 없을 것이며, 이런 경우 onUnmappableCharacter() 메소드를 사용하여 onMalformedInput()과 마찬가지로 그냥 무시할지 아니면 다른 글자로 변환할지 아니면 예외를 발생할지의 여부를 지정할 수 있다.

onMalformedInput() 메소드와 onUnmappableCharacter() 메소드에 CodingErrorAction.REPLACE를 지정하면 인코딩/디코딩 작업을 할 수 없는 글자나 문자에 대해서는 지정한 데이터로 변환을 한다고 했었는데, 이때 변환될 데이터는 replaceWith() 메소드를 사용하여 지정할 수 있다. CharsetEncoder와 CharsetDecoder는 각각 다음과 같이 repalceWith() 메소드를 정의하고 있다.

  • CharsetEncoder: replaceWith(byte[] newReplacement)
  • CharsetDecoder: replaceWith(String newReplacement)

replaceWith() 메소드에 전달할 수 있는 값에는 몇가지 제약사항이 존재한다. CharsetEncoder.replaceWith() 메소드에 전달되는 byte 배열의 경우 길이가 0보다 커야 하고 maxBytesPerChar()가 리턴하는 값보다 길어서는 안 되며, 인코딩할 캐릭터셋에 존재하는 바이트 배열이어야 하고 유니코드로 디코드 할 수 있어야만 한다. CharsetDecoder.replaceWith() 메소드에 전달되는 String은 null이 아니어야 하고 길이가 0보다 길어야 한다.

CoderResult를 사용하여 인코딩/디코딩 결과 처리하기

CharsetEncoder 클래스와 CharsetDecoder 클래스는 앞에서 살펴본 encode()/decode() 메소드 뿐만 아니라, 다음과 같이 인코딩/디코딩을 할 수 있는 메소드를 추가로 제공하고 있다.

  • CharsetEncoder: CoderResult encode(CharBuffer in, ByteBuffer out, boolean endOfInput)
  • CharsetDecoder: CoderResult decode(ByteBuffer in, CharBuffer out, boolean endOfInput)

두 메소드는 모두 CoderResult를 리턴하는데, CoderResult는 인코딩/디코딩 결과를 저장하고 있다. 위의 encode()/decode() 메소드는 앞에서 살펴봤던 encode(CharBuffer in)/decode(ByteBuffer in) 메소드와 달리 캐릭터변환 과정에서 캐릭터 매핑 에러가 있거나 입력이 잘못된 경우 예외를 발생시키지 않는다. 대신 에러가 발생했다는 사실을 리턴하는 CoderResult 객체에 표시한다. CoderResult는 다음과 같은 메소드를 제공하고 있으며, 이들 메소드를 사용하여 처리가 올바르게 되었는지 여부를 알려준다.

메소드설명
isError()처리 과정에서 에러가 발생한 경우 true를 리턴한다.
isMalformed()잘못된 입력(Malformed Input) 데이터가 있을 경우 true를 리턴한다.
isUnmappable()매핑할 수 없는 데이터를 입력한 경우 true를 리턴한다.
isOverflow()오버플로우가 발생한 경우 true를 리턴한다.
isUnderflow()언더플로우가 발생한 경우 true를 리턴한다.
throwException()인코딩/디코딩 처리 결과에 알맞은 예외를 발생시킨다. 발생하는 예외 종류는 다음과 같다.
  • MalformedInputException
  • UnmappableCharacterException
  • CharacterCodingException
  • BufferOverflowException
  • BufferUnderflowException

위 코드에서 오버플로우와 언더플로우는 에러라기 보다는 계속해서 인코딩/디코딩 작업이 필요하다는 것을 의미한다. CharsetEncoder의 encode(CharBufff, ByteBuffer, boolean) 메소드에서 오버플로우와 언더플로우 그리고 잘못된 입력, 매핑불가능은 다음과 같은 의미를 나타낸다.

  • CoderResult.UNDERFLOW - 입력 버퍼(CharBuff)에서 최대한 많은 양의 데이터를 인코딩했음을 나타낸다. 만약 입력 버퍼에 글자가 남아 있지 않고 입력 데이터가 더 이상 존재하지 않는다면 인코딩 처리가 완료된다. 그렇지 않고 입력 데이터가 불충하다면 입력 데이터를 추가적으로 받아서 인코딩 처리를 해야 한다는 것을 나타내기도 한다.
  • CoderResult.OVERFLOW - 출력 버퍼가 다 찼음을 의미한다. 따라서 다차있지 않은 출력 버퍼를 사용하여 다시 한번 인코딩 처리를 해 주어야 한다.
  • 잘못된 입력(malfored-input) - 잘못된 입력 데이터가 있음을 나타낸다. 버퍼의 현재 위치(position)는 잘못된 글자에 위치한다. 단, onMalformedInput() 메소드에 CodingErrorAction.REPORT를 지정한 경우에만 동작한다.
  • 매핑할 수 없는 글자 - 지정된 캐릭터셋으로 인코딩할 수 없는 글자가 있음을 나타낸다. 버퍼의 현재 위치는 매핑할 수 없는 글자에 위치한다. 단, onUnmappableCharacter() 메소드에 CodingErrorAction.REPORT를 지정한 경우에만 동작한다.

이 중, 오버플로우와 언더플로우는 버퍼를 사용할 때 반드시 필요한 정보중의 하나이다. 이 두 정보를 어떻게 사용할 수 있는 지에 대해서는 뒤에서 살펴볼 것이다.

핸드폰의 화면 해상도 QVGA QCIF WVGA란?

$
0
0
http://www.cyworld.com/kjh50401/2374352

[실제크기 실제 해상도]

 

QVGA(320x240 10만화소)              VGA(640x480 30만화소)                  QCIF(176x220 4만화소)

WQVGA(400x240)                       WVGA(800x480)

strlen, strcpy, strcat, strcmp 함수 구현

$
0
0

#include <stdio.h>

long strlen(const char *str)
{
   const char *s;

   for (s = str; *s; ++s);
   return(s - str);
}

char *strcpy(char *to, const char *from)
{
   char *save = to;

   for (; (*to = *from) != 0; ++from, ++to);
   return(save);
}

char *strcat(char *s, const char *append)
{
   char *save = s;

   for (; *s; ++s);
   while ((*s++ = *append++) != 0);
   return(save);
}

int strcmp(const char *s1, const char *s2)
{
   while (*s1 == *s2++)
      if (*s1++ == 0)
         return (0);
   return (*(const unsigned char *)s1 - *(const unsigned char *)--s2);
 }

int main()
{
   int result;

   char str1[] = "Src string";
   char str2[] = "Dst string";
   char str3[] = "Dst string";


   // strlen test
   printf("strlen test\n");
   result = strlen(str1);
   printf("strlen(str1) = %d\n\n", result);


   // strcpy test
   printf("strcpy test\n");
   printf("str1 = %s\n", str1);
   printf("str2 = %s\n", str2);
   strcpy(str1, str2);
   printf("strcpy(str1, str2)\n");
   printf("str1 = %s\n", str1);
   printf("str2 = %s\n\n", str2);


   // strcat test
   printf("strcat test\n");
   printf("str1 = %s\n", str1);
   printf("str2 = %s\n", str2);
   strcat(str1, str2);
   printf("strcat(str1, str2)\n");
   printf("str1 = %s\n", str1);
   printf("str2 = %s\n\n", str2);


   // strcmp test
   printf("strcmp test\n");
   printf("str1 = %s\n", str1);
   printf("str2 = %s\n", str2);
   printf("str3 = %s\n\n", str3);
   result = strcmp(str1, str2);
   if(result == 0)
   {
      printf("str1 and str2 are same.\n");
   }
   else
   {
      printf("str1 and str2 are different.\n");
   }
 
   result = strcmp(str2, str3);
   if(result == 0)
   {
      printf("str2 and str3 are same.\n");
   }
   else
   {
      printf("str2 and str3 are different.\n");
   }

 return 0;
}

[Virtual Dub] 동영상 화면 자르기

$
0
0

버추얼 덥(Virtual Dub)관련 포스팅은 정말 오랜만이군요..^^;;

다음과 같이 동영상의 테두리가 검은색으로 되어 있는 경우..
이 부분을 잘라내고 실제 화면이 나오는 부분만 쓰고 싶은 경우가 있습니다
이번에는 이런 경우 동영상의 일부 화면을 자르는 방법을 알아보겠습니다

그림이 깨져보이는 경우에는 그림을 클릭하시면 원본크기의 정상적인 그림으로 보실 수 있습니다^^



[방법]


1.편집할 동영상을 불러옵니다 (메뉴에서 [File] - [Open video file...])
똑같은 화면이 두개 보이는데 왼쪽이 원래 영상이고..
오른쪽이 필터같은 편집한 내용이 적용된 결과 영상입니다..^^

아직 동영상 주변에 검은색으로 테두리가 되어 있는 걸을 볼 수 있습니다



2.편집이 끝나고 저장할 때 종종 잊어버리는 경우가 있으니까..
   우선 압축할 코덱을 먼저 설정해주겠습니다..^^
   메뉴에서 [Video] - [Compression...]을 누르고 코덱을 선택해줍니다 (단축키 : Ctrl+P)
제가 주로 사용하는 코덱은 XviD코덱입니다..^^
각자 적절한 코덱을 사용하시면 되겠습니다



3.[Video] - [Filters...]를 눌러서 필터 설정창을 띄웁니다 (단축키 : Ctrl+F)




4.필터 목록에서 'null transform'을 찾아서 선택하고 OK를 눌러줍니다
   널 트랜스폼이란 아무것도 변환하지 않는다는 의미인데..
   동영상에 다른 변화를 주지 않고 화면의 일부를 잘라낼때 쓰입니다



5.다음 그림과 같이 필터창에 null transform이 추가된 것을 볼 수 있습니다
   이제 동영상을 잘라내기 위해서 아래쪽에 'Cropping...'을 클릭합니다^^



6.그림과 같이 4군데 값을 입력하는 부분이 있는데..
   각각 상, 하, 좌, 우의 잘라낼 크기를 지정하는 것입니다..^^
   마우스 혹은 키보드를 이용해서 적당한 값을 지정해줍니다 (잘려지는 부분은 화면에 표시됩니다)
참고로 제가 사용하는 XviD코덱의 경우 영상의 가로, 세로값이 짝수이어야 합니다
필터창에 보여지는 'null trasform'정보를 보시면 영상의 가로크기x세로크기가 표시됩니다

만약 잘라낸 후 이 값이 홀수라면, 저장하려고 할 때 다음과 같은 에러 메시지가 뜹니다
Cannot start video compression:
The source image format is not acceptable. (error code -2)



7.필터를 적용하시고 나면 다음 그림과 같이 출력 영상에 적용되어서 표시됩니다^^
    미리 코덱은 설정해뒀으니 특별히 다른 설정이 필요없다면 이대로 저장을 하시면 되겠습니다^^
종종 설정은 제대로 되었지만 화면에 적용이 안된 것처럼 보이는 경우가 있습니다..^^;

만약 출력 영상이 제대로 표시되지 않으면
아래쪽에 프레임 바를 움직여 보시거나 필터창을 다시 열어 확인 하시면 해결됩니다..^^

File->save as a AVI

리눅스(Linux) - 삭제된 파일 복구 [debugfs명령어]

$
0
0
http://www.nehome.net/

리눅스에서의 파일 삭제는 신중을 기해야 한다. 왜냐면 삭제된 파일은 복구 할 수
없기 때문이다. 이것이 정석이였습니다.

물론 rm 의 소프트링크나 다른 삭제 프로그램으로 대체하는 프로그램들도 있습니다
만 rm 자체의 복구는 없다고 알고 있으신 분들이 대부분 일 겁니다.

해답은

debugfs 라는 명령어 입니다. (man page 참조)

실제 사용예를 들어 설명하겠습니다.

가정1) /home/pds/portsentry.tar.gz 라는 파일이 있음.
가정2) /home 파티션은 hda8 입니다. (df -h 로 확인)
가정3) rm -f /home/pds/portsentry.tar.gz 명령으로 지웠음.
가정4) root 로 작업.

복구 절차.

1. #debugfs /dev/hda8

=> 설명 : hda8 파티션에 대해서 검사를 한다.

2. debugfs:

=> 대기상태를 뜻함. 이곳에서 lsdel 을 입력하고 엔터.
계속...

debugfs: lsdel
99 deleted inodes found.
Inode Owner Mode Size Blocks Time deleted
108123 0 100644 239 1/ 1 Thu Jan 3 01:25:33 2002
18417 0 100644 426625 420/ 420 Thu Jan 3 01:26:34 2002
45007 0 100644 343 1/ 1 Thu Jan 3 01:29:59 2002
28691 0 100400 879 1/ 1 Thu Jan 3 01:38:29 2002
18394 0 40755 0 1/ 1 Thu Jan 3 01:58:54 2002
..
.
14356 0 100644 2325 3/ 3 Fri Jan 25 16:13:24 2002
61239 0 100644 43034 44/ 44 Fri Jan 25 16:13:31 2002
debugfs:

위와 같은 상태로 나오고 다시 대기상태로 됩니다. 실제로는 너무 많이 나오더군
요.. (내가 그렇게 많이 지웠었나? '.'a)

이제 이 목록중에서 하나를 선택해서 살려야 합니다. 다행히도 살리고자 하는 파일
은 가장 최근에 지운 파일이므로 가장 아래쪽에 있는 것이겠죠.

debugfs: dump <61239> /home/debugfs/portsentry.tar.gz

=> Inode 값을 <> 안에 적어줍니다. 뒤에는 복구할 파일 이름을 적어주시면 됩니다.
=> 복구할 파일은 다른 디렉토리로 지정해 주시는게 좋습니다. 별 상관은 없지만...

#cd /home/debugfs
#tar -zxvf portsentry.tar.gz // 정상적으로 압축이 풀리더군요.

=> 아주 훌륭하게 복구가 되었더군요. ^^v

임의로 portsentry.tar.gz 를 지워서 테스트를 한 것입니다.

debugfs: 상태에서 사용할 수 있는 명령어는 help 를 쳐보면 알 수 있습니다.
끝내는 것은 q, quit 입니다.



아래는 debugfs: 에서 사용가능한 명령어들 입니다.
---------------------------------------------------------------------

Available debugfs requests:

show_debugfs_params, params
Show debugfs parameters
open_filesys, open Open a filesystem
close_filesys, close Close the filesystem
feature, features Set/print superblock features
dirty_filesys, dirty Mark the filesystem as dirty
init_filesys Initalize a filesystem (DESTROYS DATA)
show_super_stats, stats Show superblock statistics
ncheck Do inode->name translation
icheck Do block->inode translation
change_root_directory, chroot
Change root directory
change_working_directory, cd
Change working directory
list_directory, ls List directory
show_inode_info, stat Show inode information
link, ln Create directory link
unlink Delete a directory link
mkdir Create a directory
rmdir Remove a directory
rm Remove a file (unlink and kill_file, if appropriate)
kill_file Deallocate an inode and its blocks
clri Clear an inode's contents
freei Clear an inode's in-use flag
seti Set an inode's in-use flag
testi Test an inode's in-use flag
freeb Clear a block's in-use flag
setb Set a block's in-use flag
testb Test a block's in-use flag
modify_inode, mi Modify an inode by structure
find_free_block, ffb Find free block(s)
find_free_inode, ffi Find free inode(s)
print_working_directory, pwd
Print current working directory
expand_dir, expand Expand directory
mknod Create a special file
list_deleted_inodes, lsdel
List deleted inodes
write Copy a file from your native filesystem
dump_inode, dump Dump an inode out to a file
cat Dump an inode out to stdout
lcd Change the current directory on your native
filesystem
rdump Recursively dump a directory to the native filesystem
help Display info on command or topic.
list_requests, lr, ? List available commands.
quit, q Leave the subsystem.

신용도조회 하는 회사

$
0
0

2~3주 되었나요? 시사정보 쌈이라는 방송에서 신용등급에 대한 중요성에 대해 언급 하더군요. 신분계급 '신용등급' 이라고 하여, 그 중요도를 이야기해주더군요. 그런데 그 신용등급이란 것을 어떻게 관리해야 잘하는 것인지는 전혀 안 나오더군요. 그래서 검색과 각종 블로그를 참조해서 간단하게 알아보았습니다.

 

우선, 신용등급을 관리하는 데, 가장 중요한 것은 자신의 신용실적을 잘 관리하는 것이죠. 보통 신용등급은 개인의 카드/대출 등의 발급/연출 등의 실적으로 평가하게 됩니다. 그러나 사회로 나가고 여러 사회생활을 하면 할수록 대출을 받을 일이 생기고, 카드, 통신기기 등 각종 요금과 세금까지 챙겨야 할 것들이 대단히 많습니다. 연체를 하지 말고 자신의 수준에 맞는 금액을 대출하고 잘 상환하고, 2금융업체를 통한 신용조회를 자제하는 것이 등급이 떨어지지 않고 오르게 하는 것이죠.

 

그럼, 쉽게 잘 관리하는 방법은 없을까요? 신용관리회사를 이용하는 것이죠. 우리나라에서는 신용등급에 영향을 끼치지 않고 신용조회 및 관리를 할 수 있는 회사가 3곳이 있습니다.위 제목 하단에 써놓은 올크레딧(www.allcredit.co.kr), 마이크레딧, 크레딧뱅크이렇게 3곳입니다.

 

KCB(Korea Credit Bureau) 올크레딧 www.allcredit.co.kr

 

NICE 마이크레딧 www.myacredit.co.kr

 

KIS 크레딧뱅크 www.creditbank.co.kr

 

 

이렇게 3곳은 우선, 무료신용조회를 제공하고 있습니다. 그러나 매일 무료로 조회하는 것이 아닌 1년에 한번 제공하게 됩니다. 그 이후의 조회는 유료로 제공하고 있죠. 또한, 요즘 문제가 되고 있는 명의도용 건에 대해서도 무료로 조회가 가능합니다. , 자세한 조회가 아닌 횟수만이 가능합니다. 그 외에도 각종 서비스를 제공하고 있습니다.

 

그 중, KCB 올크레딧이란 곳을 설명하자면, 3개의 회사 중 가장 최근에 출자된 회사입니다. 국내 금융기관들이 설립한 곳이죠. 다른 2곳과 다른 점을 들자면, 우량정보를 취급하여 등급을 산정하며, 국내 금융기관들이 설립한 곳이라 금융기관별 청구지 정보 등을 얻어 사고예방 및 상세정보를 수집/제공하여 명의도용 등에 안심관리까지 제공한다더군 요. 금융기관이 설립하고 가장 최근에 설립한 회사이다 보니 이점이 많은 거 같습니다.

 

이렇게 말한 3곳의 회사 중 한 곳을 택하여 내신용을 관리하는 것이 자신을 위해, 내 가족들을 위해 여러 방면으로 좋은 거 같습니다. 요즘은 회사면접/핸드폰 개통까지도 신용등급을 보고 합격 또는 개통을 해준다고 하니, 얼마나 신용등급이 넓게 퍼지고 중요해 진지 아시겠죠? 이젠 우리의 명함과도 같은 신용등급! 내 이름과도 같은 신용등급! 꾸준히 열심히 성실히! 잘 관리해봅시다>_<

키보드로 특수문자 입력하기!

$
0
0


한글 자음

키보드에서 스페이스바 좌측의 "한자"키를 눌렀을때

#&*@§※☆★○●◎◇◆□■△▲▽▼→←↑↓↔〓◁◀ ▷▶♤♠♡♥♧♣⊙◈▣◐◑▒▤▥▨▧ ▦▩♨☏☎☜☞¶† ‡↕↗↙↖↘♭♩♪ ♬㉿㈜№㏇™㏂㏘℡ ªº
─│┌ ┐┘└├ ┬ ┤ ┴ ┼ ━┃┏┓┛┗┣ ┳ ┫┻ ╋┠ ┯ ┨┷ ┿ ┳
ⅰⅱ ⅲ ⅳ ⅴ ⅵ ⅶ ⅷ ⅸⅹⅠⅡⅢ ⅣⅤⅥ Ⅶ Ⅷ Ⅷ Ⅸ Ⅹ
+-<=>±×÷≠≤≥∞∴♂♀∠⊥⌒∂∇≡≒≪≫√∽∝∵∫ ∬∈∋⊆⊇⊂⊃∪∩∧∨¬⇒⇔∀∃∮∑∏
!',./:;?^_`| ̄、。·‥…¨〃­―∥ \∼´~˘ˇ˝˚˙¸˛¡¿ː
㉠㉡㉢..㉭ ㉮㉯㉰...㉻ ㈀㈁㈂...㈍ ㈎㈏㈐...
"( )[ ]{ }‘’“ ”〔 〕〈 〉《 》「 」『 』【 】
ⓐⓑⓒⓓⓔⓕ...ⓩ ①②③④⑤...⑮ ⒜⒝⒞...⒵ ⑴⑵⑶..⒂
$ % ₩ F ′ ″ ℃ Å ¢ £ ¥ ¤ ℉ ‰ ㎕ ㎖ ㎗ ℓ ㎘ ㏄ ㎣ ㎤ ㎠ ㎡ ㎢ ㏊ ㎍ ㎎ ㎏ ㏏ ㎈  ㎉ ㏈ ㎧ ㎨ ㎰ ㎱ ㎲ ㎳ ㎴ ㎵ ㎶ ㎷ ㎸ ㎹ ㎀ ㎁ ㎂ ㎃ ㎄ ㎺ ㎻ ㎼ ㎽ ㎾ ㎿ ㎐ ㎑ ㎒ ㎓ ㎔ Ω ㏀ ㏁ ㎊
Α Β Γ Δ Ε Ζ Η Θ Ι Κ Λ Μ Ν Ξ Ο Π Ρ Σ Τ Υ Φ Χ Ψ Ω α β γ δ  εζ η θ ικ λ μ ν ξο π ρ σ τυ φ χ ψ ω
ㄱㄲㄳㄴㄵㄶㄷㄸㄹㄺㄻㄼㄽㄾㄿㅀㅏㅐㅑㅒㅔㅘㅙㅝㅞㅟㅢ
ㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯㅰㅱㅲㅳㅴㅵㅶㅷㅸㆂㆃㆄㆅㆆㆇㆈㆉ ㆊㆋㆌㆍㆎ
½ ⅓ ⅔ ¼ ¾ ⅛ ⅜ ⅝ ⅞ ¹ ² ³ ⁴ⁿ ₁₂₃₄

HTML 특수문자표, ( 숫자표현,문자표현 ) 코드표

$
0
0



 

특수문자

  • Entity 코드로 표현된 특수문자는 대부분의 브라우저에서 문제없이 출력된다.
  • 꺽쇠기호 < > 등을 Entity로 처리하지 않는 경우 브라우저들은 이것을 HTML 태그의 시작이나 끝으로 인식할 수 있다.
  • 따옴표 ""는 HTML 속성의 값이 시작되거나 끝난 것으로 인식할 수 있다.
  • & 기호는 Entity기호의 시작으로 오인될 수 있다.
  • 가장 흔한 실수 : URL에 포함된 & 기호를 Entity로 변환하지 않는 경우이며 특히 웹에디터에서 입력되는 특수문자 등은 Entity 코드로 치환되어야 한다.

HTML Latin-1 Character Entities Reference

ASCII Entities with Entity Names
ResultDescriptionEntity NameEntity Number
"quotation mark&quot;&#34;
'apostrophe &apos; (does not work in IE)&#39;
&ampersand&amp;&#38;
<less-than&lt;&#60;
>greater-than&gt;&#62;

ISO 8859-1 Symbol Entities
ResultDescriptionEntity NameEntity Number
 non-breaking space&nbsp;&#160;
¡inverted exclamation mark&iexcl;&#161;
¢cent&cent;&#162;
£pound&pound;&#163;
¤currency&curren;&#164;
¥yen&yen;&#165;
¦broken vertical bar&brvbar;&#166;
§section&sect;&#167;
¨spacing diaeresis&uml;&#168;
©copyright&copy;&#169;
ªfeminine ordinal indicator&ordf;&#170;
«angle quotation mark (left)&laquo;&#171;
¬negation&not;&#172;
­soft hyphen&shy;&#173;
®registered trademark&reg;&#174;
¯spacing macron&macr;&#175;
°degree&deg;&#176;
±plus-or-minus &plusmn;&#177;
²superscript 2&sup2;&#178;
³superscript 3&sup3;&#179;
´spacing acute&acute;&#180;
µmicro&micro;&#181;
paragraph&para;&#182;
·middle dot&middot;&#183;
¸spacing cedilla&cedil;&#184;
¹superscript 1&sup1;&#185;
ºmasculine ordinal indicator&ordm;&#186;
»angle quotation mark (right)&raquo;&#187;
¼fraction 1/4&frac14;&#188;
½fraction 1/2&frac12;&#189;
¾fraction 3/4&frac34;&#190;
¿inverted question mark&iquest;&#191;
×multiplication&times;&#215;
÷division&divide;&#247;

ISO 8859-1 Character Entities
ResultDescriptionEntity NameEntity Number
Àcapital a, grave accent&Agrave;&#192;
Ácapital a, acute accent&Aacute;&#193;
Âcapital a, circumflex accent&Acirc;&#194;
Ãcapital a, tilde&Atilde;&#195;
Äcapital a, umlaut mark&Auml;&#196;
Åcapital a, ring&Aring;&#197;
Æcapital ae&AElig;&#198;
Çcapital c, cedilla&Ccedil;&#199;
Ècapital e, grave accent&Egrave;&#200;
Écapital e, acute accent&Eacute;&#201;
Êcapital e, circumflex accent&Ecirc;&#202;
Ëcapital e, umlaut mark&Euml;&#203;
Ìcapital i, grave accent&Igrave;&#204;
Ícapital i, acute accent&Iacute;&#205;
Îcapital i, circumflex accent&Icirc;&#206;
Ïcapital i, umlaut mark&Iuml;&#207;
Ðcapital eth, Icelandic&ETH;&#208;
Ñcapital n, tilde&Ntilde;&#209;
Òcapital o, grave accent&Ograve;&#210;
Ócapital o, acute accent&Oacute;&#211;
Ôcapital o, circumflex accent&Ocirc;&#212;
Õcapital o, tilde&Otilde;&#213;
Öcapital o, umlaut mark&Ouml;&#214;
Øcapital o, slash&Oslash;&#216;
Ùcapital u, grave accent&Ugrave;&#217;
Úcapital u, acute accent&Uacute;&#218;
Ûcapital u, circumflex accent&Ucirc;&#219;
Ücapital u, umlaut mark&Uuml;&#220;
Ýcapital y, acute accent&Yacute;&#221;
Þcapital THORN, Icelandic&THORN;&#222;
ßsmall sharp s, German&szlig;&#223;
àsmall a, grave accent&agrave;&#224;
ásmall a, acute accent&aacute;&#225;
âsmall a, circumflex accent&acirc;&#226;
ãsmall a, tilde&atilde;&#227;
äsmall a, umlaut mark&auml;&#228;
åsmall a, ring&aring;&#229;
æsmall ae&aelig;&#230;
çsmall c, cedilla&ccedil;&#231;
èsmall e, grave accent&egrave;&#232;
ésmall e, acute accent&eacute;&#233;
êsmall e, circumflex accent&ecirc;&#234;
ësmall e, umlaut mark&euml;&#235;
ìsmall i, grave accent&igrave;&#236;
ísmall i, acute accent&iacute;&#237;
îsmall i, circumflex accent&icirc;&#238;
ïsmall i, umlaut mark&iuml;&#239;
ðsmall eth, Icelandic&eth;&#240;
ñsmall n, tilde&ntilde;&#241;
òsmall o, grave accent&ograve;&#242;
ósmall o, acute accent&oacute;&#243;
ôsmall o, circumflex accent&ocirc;&#244;
õsmall o, tilde&otilde;&#245;
ösmall o, umlaut mark&ouml;&#246;
øsmall o, slash&oslash;&#248;
ùsmall u, grave accent&ugrave;&#249;
úsmall u, acute accent&uacute;&#250;
ûsmall u, circumflex accent&ucirc;&#251;
üsmall u, umlaut mark&uuml;&#252;
ýsmall y, acute accent&yacute;&#253;
þsmall thorn, Icelandic&thorn;&#254;
ÿsmall y, umlaut mark&yuml;&#255;

HTML 4.01 Symbol Entities Reference

Math Symbols Supported by HTML
ResultDescriptionEntity NameEntity Number
for all&forall;&#8704;
part&part;&#8706;
exists&exists;&#8707;
empty&empty;&#8709;
nabla&nabla;&#8711;
isin&isin;&#8712;
notin&notin;&#8713;
ni&ni;&#8715;
prod&prod;&#8719;
sum&sum;&#8721;
minus&minus;&#8722;
lowast&lowast;&#8727;
square root&radic;&#8730;
proportional to&prop;&#8733;
infinity&infin;&#8734;
angle&ang;&#8736;
and&and;&#8743;
or&or;&#8744;
cap&cap;&#8745;
cup&cup;&#8746;
integral&int;&#8747;
therefore&there4;&#8756;
simular to&sim;&#8764;
approximately equal&cong;&#8773;
almost equal&asymp;&#8776;
not equal&ne;&#8800;
equivalent&equiv;&#8801;
less or equal&le;&#8804;
greater or equal&ge;&#8805;
subset of&sub;&#8834;
superset of&sup;&#8835;
not subset of&nsub;&#8836;
subset or equal&sube;&#8838;
superset or equal&supe;&#8839;
circled plus&oplus;&#8853;
cirled times&otimes;&#8855;
perpendicular&perp;&#8869;
dot operator&sdot;&#8901;

Greek Letters Supported by HTML
ResultDescriptionEntity NameEntity Number
ΑAlpha&Alpha;&#913;
ΒBeta&Beta;&#914;
ΓGamma&Gamma;&#915;
ΔDelta&Delta;&#916;
ΕEpsilon&Epsilon;&#917;
ΖZeta&Zeta;&#918;
ΗEta&Eta;&#919;
ΘTheta&Theta;&#920;
ΙIota&Iota;&#921;
ΚKappa&Kappa;&#922;
ΛLambda&Lambda;&#923;
ΜMu&Mu;&#924;
ΝNu&Nu;&#925;
ΞXi&Xi;&#926;
ΟOmicron&Omicron;&#927;
ΠPi&Pi;&#928;
ΡRho&Rho;&#929;
ΣSigma&Sigma;&#931;
ΤTau&Tau;&#932;
ΥUpsilon&Upsilon;&#933;
ΦPhi&Phi;&#934;
ΧChi&Chi;&#935;
ΨPsi&Psi;&#936;
ΩOmega&Omega;&#937;
αalpha&alpha;&#945;
βbeta&beta;&#946;
γgamma&gamma;&#947;
δdelta&delta;&#948;
εepsilon&epsilon;&#949;
ζzeta&zeta;&#950;
ηeta&eta;&#951;
θtheta&theta;&#952;
ιiota&iota;&#953;
κkappa&kappa;&#954;
λlambda&lambda;&#955;
μmu&mu;&#956;
νnu&nu;&#957;
ξxi&xi;&#958;
οomicron&omicron;&#959;
πpi&pi;&#960;
ρrho&rho;&#961;
ςsigmaf&sigmaf;&#962;
σsigma&sigma;&#963;
τtau&tau;&#964;
υupsilon&upsilon;&#965;
φphi&phi;&#966;
χchi&chi;&#967;
ψpsi&psi;&#968;
ωomega&omega;&#969;
ϑtheta symbol&thetasym;&#977;
ϒupsilon symbol&upsih;&#978;
ϖpi symbol&piv;&#982;

Some Other Entities Supported by HTML
ResultDescriptionEntity NameEntity Number
Œcapital ligature OE&OElig;&#338;
œsmall ligature oe&oelig;&#339;
Šcapital S with caron&Scaron;&#352;
šsmall S with caron&scaron;&#353;
Ÿcapital Y with diaeres&Yuml;&#376;
ƒf with hook&fnof;&#402;
ˆmodifier letter circumflex accent&circ;&#710;
˜small tilde&tilde;&#732;
en space&ensp;&#8194;
em space&emsp;&#8195;
thin space&thinsp;&#8201;
zero width non-joiner&zwnj;&#8204;
zero width joiner&zwj;&#8205;
left-to-right mark&lrm;&#8206;
right-to-left mark&rlm;&#8207;
en dash&ndash;&#8211;
em dash&mdash;&#8212;
left single quotation mark&lsquo;&#8216;
right single quotation mark&rsquo;&#8217;
single low-9 quotation mark&sbquo;&#8218;
left double quotation mark&ldquo;&#8220;
right double quotation mark&rdquo;&#8221;
double low-9 quotation mark&bdquo;&#8222;
dagger&dagger;&#8224;
double dagger&Dagger;&#8225;
bullet&bull;&#8226;
horizontal ellipsis&hellip;&#8230;
per mille &permil;&#8240;
minutes&prime;&#8242;
seconds&Prime;&#8243;
single left angle quotation&lsaquo;&#8249;
single right angle quotation&rsaquo;&#8250;
overline&oline;&#8254;
euro&euro;&#8364;
trademark&trade;&#8482;
left arrow&larr;&#8592;
up arrow&uarr;&#8593;
right arrow&rarr;&#8594;
down arrow&darr;&#8595;
left right arrow&harr;&#8596;
carriage return arrow&crarr;&#8629;
left ceiling&lceil;&#8968;
right ceiling&rceil;&#8969;
left floor&lfloor;&#8970;
right floor&rfloor;&#8971;
lozenge&loz;&#9674;
spade&spades;&#9824;
club&clubs;&#9827;
heart&hearts;&#9829;
diamond&diams;&#9830;

더많은 특수문자 코드 보기

[추천] JAVA 자료형 변환 방법 모음

$
0
0



Dealing with nulls

UtilFactory.convertNull

 

Java – comparing strings

Use == for primitive data types like int

If (mystring == null)

 

Use the equals() method to compare objects

Use .equals for strings  : if (a.equals(“cat”))

 

Java - Converting int to string

 

String myString = Integer.toString(my int value)

   or

   String str = "" + i

 

Java - Converting String to int

 

int i = Integer.parseInt(str);

   or
int i = Integer.valueOf(str).intValue();

 

 

double to String :

   String str = Double.toString(i);

 

long to String :

String str = Long.toString(l);

 

 

float to String :

String str = Float.toString(f);

 

 

String to double :

double d = Double.valueOf(str).doubleValue();

 

String to long :

long l = Long.valueOf(str).longValue();
   or

   long l = Long.parseLong(str);

 

String to float :

float f = Float.valueOf(str).floatValue();


decimal to binary :

   int i = 42;

   String binstr = Integer.toBinaryString(i);


decimal to hexadecimal :

   int i = 42;
   String hexstr = Integer.toString(i, 16);
 
   or
   String hexstr = Integer.toHexString(i);
 
   or (with leading zeroes and uppercase)
   public class Hex {
     public static void main(String args[]){
       int i = 42;
       System.out.print
         (Integer.toHexString( 0x10000 | i).substring(1).toUpperCase());
      }
     }

 


hexadecimal (String) to integer :

int i = Integer.valueOf("B8DA3", 16).intValue();
   or

   int i = Integer.parseInt("B8DA3", 16);    



ASCII code to String

int i = 64;

   String aChar = new Character((char)i).toString();


integer to ASCII code (byte)

char c = 'A';

   int i = (int) c; // i will have the value 65 decimal



integer to boolean

   b = (i != 0);

 

boolean to integer

i = (b)?1:0;

 

무료 폰트 모음

$
0
0

Naver 나눔체 http://hangeul.naver.com

Daum 다음체 http://fontevent.daum.net

서울한강,서울남산(서울시) http://design.seoul.go.kr/dscontent/designseoul.php?MenuID=490&pgID=57

조선일보 명조체 http://font.chosun.com

아모레퍼시픽 아리따체 http://www.amorepacific.co.kr/company/ci/font.jsp

윤디자인 웹돋음,웹바탕,손글씨체 등 무료폰트(로그인시에 다운로드 가능) http://yoonfont.co.kr/login/login.asp?ReturnURL=/customer/download_View.asp?idx=56&Code=30&os=3

한겨레신문 한겨레결체 http://bbs.hani.co.kr/Board/ui_hkr_alim/Contents.asp?GoToPage=1&Idx=56&RNo=56&STable=ui_hkr_alim&Search=&Sorting=2&Text

imbc or 동아일보 회원에 한해 1개씩만 가능 http://hangeul.lexitech.co.kr

ERwin 사용법

$
0
0


현재 운영중인 DB의 ERD를 작성
  (Reverse Engineer 이용)

0. 접속 가능 버젼인지 체크

1. ER-WIN의 Physical 모드에서

2. Database > Database connection 선택 

  - User Name : db계정
  -
Password : db패스워드
  -
 Database : 사용할 db명
  -
Server Name : db IP주소

image 


3.  Reverse Engineer 

   - Tools>Reverse Engineer
image 

  -  Model Type 선택후, Target Database의 정보가 올바른지 확인후  Next 클릭

image 

- Table Owners를 꼭 설정할것 (시스템Table을 배제하기위해)

image

4. 생성된 ERD를 편집

 

--------------------------------------------------------------------------------

ERWin사용방법

시작하기

시작 -> 프로그램 -> Computer Associates ERWin4.0 -> ERWin4.0을 선택하여 ERwin을 실행.

clip_image002

ERwin 초기 화면이 나타나는데 ‘Create a new model’옵션 버튼을 선택하고 OK버튼을 누르면
다음과 같이 Create Model 대화상자가 나타나게 되고 여기서 세번째 옵션 버튼인 Logical/Physical옵션 버튼을 선택한다.

기존 ERwin파일을 열고자 한다면 ‘Open an existing file’옵션 버튼을 선택한다. 그런 다음 Create Model대화상자에서 모델의 유형으로 Logical/Physical옵션 버튼을 선택한 뒤 폼 아래 부분에 개발 대상 데이터베이스를 선택해야 하는데 여기서는 SQL Server 2000로 설명할 것이므로 DB는 SQL Server를 선택하고 버전은 2000을 선택한다. (참고로 이전 버전인 ERwin3.5.2는 SQL Server 7.0까지 지원했다.)

clip_image006

그런 다음 OK버튼을 누르면 다음과 같이 ERWin 메인 화면이 나타나게 된다.

clip_image008

메인 화면은 도구 메뉴와 Model Explorer그리고 다이어그램등 크게 세가지 부분으로 구성되어 있으며 Model Explorer는 ERwin 4.0에 새롭게 추가된 부분이다. 마치 SQL Server의 쿼리 분석기와 비슷한 모습이며 하는 역할도 다이어그램에서 정의 된 개체들의 정보를 계층적으로 보여주고 있어서 기능적으로도 비슷한 역할을 하고 있다.

 

초기 설정 : ERwin 표기방식

메인 화면이 열리면 가장 먼저 정의해야 할 내용은 어떠한 표기 방법을 사용할 것이냐 하는 것이다.

ERWin 표기법
1. IE ( Information Engineering )방식  : 정보 공학 표기방식으로 우리가 일반적으로 모델링을 할 때 가장 많 이 사용하는 유형
2. Idef1x (Integration DEFinition for Information Modeling )방식 : 미 국방성에서 프로젝트 표준안으로 개발한 표기 방식

IE표기번으로 변경
기본적으로 ERWin을 설치하게 되면 Idef1x방식이 선택되어지며 이 설정을 IE표기방식으로 바꾸려면
image 
세 번째 Notation탭에서 Logical Notation Physical Notation영역 모두 IE옵션 버튼을 선택.

clip_image011

이렇게 하면 ERWin Toolbox의 모습이 아래와 같이 바뀌게 된다.

clip_image013  clip_image014clip_image016

Logical Nation Physical Nation

ERWin은 기본적으로 개념적 데이터 모델링은 지원하지 않으며
논리적 데이터 모델링과 물리적 데이터 모델링을 지원한다.

그러므로 ERWin을 사용하기 위해서는 먼저 업무적인 분석과 기본적인 엔티티와Attribute등이 정의된 양식이 있어야 하며
이를 ERWin으로 옮기면서 관계형 데이터베이스 모델링 이론에 입각해서 ERD를 작성하게 된다.

ERWin에서 논리적 데이터 모델링과 물리적 데이터 모델링을 선택하기 위해서는

image

Entity생성

image

 

clip_image022

--> Entity 명

 

  --> Primary Key 영역

 

  --> Attribute 영역

 

엔티티를 선택한 뒤,  Tab키를 이용하여 위 세영역을  이동
기본키와 일반 속성영역에 속성을 추가하고자 한다면 엔터키를 치면 새로운 속성을 기술할 공간이 만들어 진다.

그러면 다음과 같이 사원 엔티티를 만들어 보자

clip_image025

 

식별관계, 식별관계

relation이란 두 Entity간의 업무적인 연관성이라 정의한 바 있다.
그리고 관계의 유형에는 부모 테이블의 기본키 혹은 복합키가 자식 테이블의 기본키 혹은 복합키의 구성원으로 전이되는 식별관계와 자식 테이블의 일반 Attribute 그룹의 구성원으로 전이되는 비 식별관계가 있다.

식별관계와 비 식별관계의 관계 선을 정의하기 위해서는 ERwin Toolbox에서 네번째 버튼이 식별관계의 관계 선이고 여섯번째 버튼이 비 식별관계의 관계 선이다.

clip_image026

예제 테이블(Entity)을 아래와 같이 추가.

clip_image028

위 테이블에서 부서 테이블과 사원 테이블간의 관계는 부서에 사원이 소속됨으로 부서 테이블이 부모 테이블이 되고 사원들의 부가적인 신체 정보를 저장하기 위한 것이니 만큼 사원 테이블이 신체정보 테이블과의 관계에서는 부모 테이블이 된다.

그러면 관계의 유형은 어떻게 되는가 ? 부서 테이블과 사원 테이블에서 부서는 사원의 부분적인 정보를 표현함으로 비 식별관계 이며 사원 테이블과 신체정보 테이블에서는 사원들 개개인의 신체 정보를 저장하게 됨으로 식별관계가 된다.

식별관계나 비 식별관계 모두 관계를 형성하기 위해서는
ERwin Toolbox에서 관계 유형에 맞는 관계선을 선택하고 부모 테이블을 선택한 뒤에 자식 테이블을 선택한다.

clip_image030

이처럼 관계를 형성하게 되면 부모 테이블의 기본키가 자식 테이블에 자동으로 전이됨
( SQL Server의 엔터프라이즈 관리자는 SQL Server의 관리도구 이지 CASE Tool은 아니다. )

관계를 형성한 뒤에는 관계에 관한 옵션을 설정해야 하는데
image

*부서 테이블과 사원 테이블 사이의 관계선.

Cardinality: 두 테이블에서 레코드들의 메칭 정보를 보여주게 되는데 옵션
                   위의 예에서는 하나의 부서에 사원이 없을 수도, 한명만 있을 수도 아니면 여러 명 있을 수도 있으므로
                   첫번째 Zero, One or More옵션이 올바르다.

Relationship Type:   부서 테이블과 사원 테이블의 관계 유형이 비 식별관계이므로 Non-Identifying옵션이 선택되어 있다. 

Verb Phrase: Parent-to-Child 그리고 Child-to-Parent 와의 관계에 대한 설명적인 문구를 입력하는 곳.
                     (실제 모델링에서 중요한 옵션이라기보다는 관계에 관한 가독성을 높이기 위한 주석 정도로 이해)

 

Null에 대한 옵션: 기본적으로 비 식별관계에서는 부모 테이블에서 널을 허용할 수 있게끔 옵션이 선택되어 있는데 이는 대부분의 경우에 올바른 옵션이 아니다.Null에 대한 옵션을 No Nulls로 선택하도록 하자.

clip_image040

* 사원 테이블과 신체정보 테이블 사이의 관계선.

clip_image046

Cardinality옵션은 사원 테이블에 하나의 레코드는 반드시 신체정보 테이블에도 대응되는 하나의 레코드가 존재해야 하므로 아래의 그림 처럼 Exactly 1 관계로 정의
( Exactly을 선택하고 임의의 숫자를 입력하면 자식 테이블쪽의 관계선 끝이 직선으로 표시되는데 이를 정확하게 보기 위해서는 ERwin 다이어그램 빈공간에서 오른쪽 버튼을 누른 뒤 팝업 메뉴에서 Relationship Display / Cardinality를 선택하면 된다.)

image

결과

clip_image048

 

 

 

다대다해소방법

앞에서도 설명했지만 다대다 관계는 논리적으로는 존재할 수 있지만 물리적으로는 존재할 수 없다.
ERwin에서도 역시 ERwin Toolbox의 관계선을 이용하여 다대다관계를 표현할 수 있다.

clip_image050

그러면 다대다 관계선을 이용하여 아래의 그림처럼 다이어그램을 만들어 보자.

(다대다 관계에 있는 엔티티들은 부모와 자식의 관계가 아니므로
다대다 관계선을 선택한 후 순서에 상관없이 두 엔티티를 차례로 선택하면 관계가 형성된다. )

clip_image052

하나의 공급업체는 여러 개의 상품을 납품할 수 있고 하나의 상품은 여러 공급업체에서 납품 받을 수 있기 때문에 공급업체와 상품 엔티티간은 다대다 관계이며
하나의 상품은 여러 회원에게 판매할 수 있고 한명의 회원은 여러 상품을 구매할 수 있으므로 이 역시 다대다 관계이다.

그러나 대부분의 경우에 논리적 모델링에서도 다대다 관계를 풀어서 교차실체(행위실체)를 정의해야 한다.
왜냐하면 대부분의 업무적 프로세스와 상세 정보가 바로 이 교차 실체에서 정의되기 때문이다.

다대다 관계를 해소하려면
image

clip_image054

 clip_image056

새롭게 추가될 교차 실체의 실체명을 정의하고 다음 버튼을 눌러 작업을 완료한다. (공급업체와 상품 엔티티 간에 정의될 수 있는 프로세스는 "납품"이고 , 회원과 상품 엔티티 간에 정의될 수 있는 프로세스는 "판매" )각각 납품과 판매를 교차실체명으로 정의하여 다대다 관계를 해소하면 다음과 같은 모습이 된다.

clip_image058

납품과 판매 엔티티에 속성(Attribute)를 추가 
- 일반적으로 납품 엔티티는 납품번호로 그리고 판매 엔티티는 판매번호로 관리되어지기 때문에 납품번호와 판매번호를 기본키로 정의하고 필요한 속성을 추가
- 납품번호와 판매번호를 기본키로 정의하려면 관계선이 비식별관계로 정의되어야 한다.
   ( Non-Identifying 으로 옵션 변경하면 자동으로 PK로 잡혀있는 속성들이 일반 Attribute로 내려간다.)
    image
   

clip_image060clip_image061

 

Domains 설정

납품 Entity와 판매 Entity의 Attribute들을 보면 일자, 수량, 단가, 금액등의 컬럼이 같이 쓰여지고 있는 모습을 볼 수가 있는데
이렇게 여러 Entity에서 공통적으로 적용되는 Attribute이 존재하면 그것을 하나의 개체로 만들어 적용시키는 것이 훨씬 더 편리할 수 있다. (SQL Server에서 사용자 정의 데이터 타입을 정의해서 필요한 컬럼에 바인딩하는 것과 같은 내용이다.)

Model Explorer의 Domain텝에서 정의한다.
clip_image002[4]

 

아직은 Logical 모델링 단계이므로 정확한 Data Type과 Size를 정의할 단계는 아니지만 그레도 문자형인지 숫자형인지는 구분을 해서 만들어 주어야 한다. (일자는 문자열로 정의할 것이며 수량, 단가, 금액은 숫자형 Attribute들이다.)

imageimage

 

일자는 문자형으로 정의할 것이므로 String에서 오른쪽 버튼 New를 선택한 뒤 폴더 모습의 아이콘이 만들어지면 일자라고 정의한다

 

 

 

 

 

 

image     image

수량, 단가, 금액 등은 Number에서 오른쪽 버튼 New를 선택한 뒤 차례로 만들어 나간다.

 

 

 

 

 

 

 

그러면 아래와 같은 모습이 될 것이다.

image

납품 Entity와 판매 Entity에서  납품 일자, 단가, 수량, 금액 Attribute과 판매 일자, 단가, 수량, 금액 Attribute들을 제거
Model Explorer에 있는 금액과 단가수량, 일자등을 선택해서 드래그 한 다음 납품 Entity와 판매 Entity에 차례로 드롭.

clip_image006

Attribute(Attribute)의 의미를 좀더 명확하게 하기 위해서 Attribute(Attribute)명 앞에 해당 Entity명을 추가할 수 있는데
image

 image
Domain Directory대화상자가 나타나게 되는데 여기서 Hierarchically옵션 버튼을 선택하면 아래와 같은 모습이 된다.
오른쪽에 Name Inherited by 입력 상자의 내용이 기본적으로 %AttDomain --> %EntityName%AttDomain 이라고 정의하면 적용되는 모든 Attribute명 앞에 Entity명이 함께 붙어서 정의 되어진다.

clip_image010

 

 

Subject Area

일반적으로 업무 분석을 해서 Entity(Entity)를 추출하게 되면 적게는 10개 미만부터 많게는 100개 이상의 Entity가 정의되는 모습을 보게 되는데 이러한 많은 Entity를 한 화면에서 모두 관리한다면 너무나 복잡할 것이다. 이럴 경우 Subject Area를 활용하면 편리한 점이 많이 있다.

Subject Area는 업무적으로 관련이 있거나 혹은 개발자가 보고자 하는 내용만을 가지고 새로운 화면을 구성한다.
- 좀더 편리하게 Entity와 관계를 확인할 수 있으며 Subject Area에서 어떠한 내용을 변경한다 하더라도 이 변경 사항이 전체 ERD에 반영됨으로 보다 편리하게 작업할 수 있다.
- 나중에 데이터베이스 스키마를 생성할 때 Subject Area별로 스키마를 데이터베이스에 생성할 수 있다는 점이다.
   (새로운 Entity를 데이터베이스에 추가하고자 하는 경우 편리하게 사용할 수 있다.)

Subject Area를 생성하거나 관리하려면
- ERwin Toolbar의 Create Subject Area버튼
image

- Model Explorer의 Subject Areas텝
 image

-Model메뉴 > Subject Areas메뉴에서 작업
image

 

예제>
Subject Areas대화상자가 나타나게 되는데 현재 <Main Subject Area>가 리스트에 등록되어진 모습을 볼 수 있다.
Subject Areas대화상자 에서 Members텝을 누르면 여태까지 작성한 Entity들이 모두 포함되어 있는 모습을 볼 수 있다.

‘사원정보’ Subject Area : 부서, 사원, 신체정보 Entity를 포함
'상품정보’ Subject Area : 공급업체, 상품, 회원, 납품, 판매 Entity를 포함

1. New버튼 클릭 후,  새로운 Subject Area의 이름을 ‘사원정보’라고 입력한 후
   Members텝에서  Available Objects리스트 상자에서 원하는 Entity를 선택해서 화살표 버튼을 이용하여 Included Objects리스트 상자로 옮김

image        clip_image017

위의 화면처럼 사원 Entity를 선택하면 밑에서 두번째 버튼이 활성화 되어지는데 그 버튼을 누르면
다음과 같이 Spanning Neighborhood대화상자가 나타나는데 여기서 선택한 Entity를 중심으로 관계를 맺고 있는 Parent와 Child Entity를 단계별로 추가할 수 있다.

clip_image019[4]

여기서는 사원 Entity를 중심으로 부서와 신체정보 Entity가 1단계 걸쳐서 정의되 어 있으므로 Level 1로 선택한 후 확인버튼을 누르면
아래의 그림처럼 사원을 중심으로 부서와 신체정보 Entity가 ‘사원정보’ Subject Area에 포함되어 있는 것을 확인할 수 있다.

그런 다음 ‘OK’버튼을 누르면 부서, 사원, 신체정보 Entity들만 화면에 보여지게 된 다.

clip_image021

       image

 

Subject Area는 편하게 원하는 Entity들만 보여주지만 정말 중요한 기능은 Physical Modeling단계에서 Subject Area별로 DB 스키마를 생성할 수 있다는 점이다. 예를 들어 기존에 만들어진 데이터베이스 스키마에 새로운 테이블만 생성하려고 할 때 생성하고자 하는 Entity들만 Subject Area로 구성한 후 Generate할 수 있다.

 

Physical 모델링

ERwin에서 물리적 모델링으로 전환하려면 앞에서 설명했던 것 처럼 ERwin Toolbar의 오른쪽 콤포박스를 Physical로 선택.

ERwin을 처음 실행할 때 Target Database를 SQL Server 2000으로 선택했으므로 다시 데이터베이스를 선택할 필요는 없다.
만약 처음에 선택하지 않고 지나쳤다면 Database메뉴에서 Choose Database..메뉴를 선택하면 다음과 같이 개발 DBMS를 선택하는 Target Server대화상자가 나오게 되는데 여기서 원하는 RDBMS와 Version을 선택하면 된다. ( Database메뉴는 Physical에서만 나타난다. )

물리적 모델링으로 전환할 경우 용어가
Entity(Entity) 에서 테이블(Table)로
Attribute(Attribute)에서 컬럼( Column )으로 바뀌게 된다.

clip_image028

Logical모델링에서 Physical모델링으로 전환하면 기본적으로 다음과 같이 컬럼 Data Type과 Size가 함께 보여지게 된다.

 

Column Data Type Size

clip_image030[4]

기본적으로 char(18)로 모든 Data Type과 Size가 정의되어 있는데 이를 각 컬럼에 입력될 데이터의 성격에 따라 적절하게 변경해 주어야 한다.
image   또는 Entity 더블 클릭

 

clip_image032

위 Columns대화상자 왼쪽에서 컬럼을 선택하고 오른쪽에서 Data Type과 Size를 정의 하면 되고
이 대화상자에서 컬럼의 Null허용여부, IDENTITYAttribute설정, Rule과 Check, Default등을 정의할 수 있으며 인덱스도 정의할 수 있다.

그러면 다음과 같이 컬럼의 Data Type과 Size를 정의해 보도록 하자.

clip_image034[4]clip_image038[4]

(임의적인 상황을 가정해서 정의했으므로 모든 유형에서 위의 데이터 형식이 항상 올바르다고 할 수는 없다. )

 

Identity, Null Option

위의 예에서 납품 테이블의 납품번호 컬럼과 판매 테이블의 판매번호 컬럼은 Identity컬럼이다.
( Identity컬럼을 정의하기 위해서는 컬럼의 Data Type이 정수형 Data Type이어야만 한다. )

clip_image041

이렇게 Identity컬럼을 정의할 경우 기본값과 증가 값은 1이다. 만일 Identity컬럼의 초기값과 증가 값을 임의로 정의하고자 한다면 Identity옵션버튼의 뒤쪽 입력 상자에 초기값과 증가 값을 컴마로 구분해서 정의해 주어야 한다. ( 초기값이 1이고 증가값이 10일 경우 입력 상자에 1, 10 으로 정의한다. )

Identity컬럼에는 널값이 입력될 수 없으므로 Null옵션이 의미가 없으며 사용자가 임의로 값을 입력할 수도 없다.

l 참고 : 판매 테이블의 판매 번호는 Data Type이 Bigint형이다. Bigint는 정수형 Data Type으로 – 9,223,372,036,854,775,808 부터 9,223,372,036,854,775,807 까지의 엄청나게 큰 정수형 Data Type이다. 실제로 SQL Server에서는 Bigint Data Type도 Identity컬럼으로 정의할 수 있으나 ERwin 4.0에서는 Int까지만 Identity컬럼을 지원하고 Bigint Data Type은 IdentityAttribute을 정의할 수 없도록 비활성화 되어 있다. 아마도 패치 버전에서는 이를 지원하지 않을까 생각 한다.

Check( Rule ), Default

둘 다 데이터가 컬럼에 들어올 수 있는 경우의 수를 제한해서 데이터베이스의 무결성을 강화하기 위한 방법으로 사용 한다.
- Check제약 조건: 테이블을 만들거나 수정하면서 정의하는 제약조건
- Rule: DB 내의 Object로 우선 데이터베이스 내에 Rule이라는 Object를 만든 후에 이를 필요한 테이블의 컬럼에 바인딩 해서 사용.
- Default :  마찬가지로 사용자가 특정 컬럼에 데이터를 입력하지 않았을 때 기본적으로 그 컬럼에 들어가지는 값을 정의하는데 사용되는 옵션
clip_image044

 

우선 Check(Rule) 제약조건 부터 정리해 보도록 하자.

이번 예에서는 위의 판매 테이블에 판매수량과 판매단가 그리고 판매금액 컬럼에 0이상의 값이 입력되어야 한다는 내용을 정의해 보도록 하겠다. 그리고 다른 예로 값의 범위를 정하는 예와 특정한 몇 개의 데이터만 입력할 수 있도록 정의하는 내용에 대해서 다루어 보도록 하겠다.

Check(Rule)제약조건을 정의하려면 위의 그림에서 Valid 뒤쪽의 버튼을 클릭하면 다음과 같이 Validation Rules대화상자가 나타나게 된다.

clip_image046[4]

우선 테이블에 판매수량과 판매단가 그리고 판매금액 컬럼에 0 이상의 값이 입력되어야 한다는 내용을 정의하기 위해 New버튼을 누른 뒤 New Validation Rule대화상자에서 Logical과 Physical 입력상자에 ‘판매수량Check’이라고 입력한다.

clip_image048

clip_image051

그러면 아래의 Type이 활성화 되어지는데 여기서 첫 번째 User-Defined옵션버튼을 선택한 후 Validation 입력상자에 ‘판매수량 >= 0’이라고 입력한다.

clip_image054[4]

그런 다음 위의 그림처럼 SQL Server텝을 선택하고 Generate As영역에서 CHECK Constraint옵션을 선택한다.

Sp_bindrule옵션은 Rule을 만들때 적용하는 옵션이며 위의 예는 판매수량 컬럼에 적용되는 제약 조건을 정의하는 것이므로 CHECK Constraint옵션을 선택해야 한다.

위와 같은 요령으로 ‘판매단가Check’, ‘판매금액Check’를 만든다.

그런 다음 OK버튼을 눌러서 Columns대화상자로 돌아간 뒤 아래의 그림처럼 판매수량 컬럼을 선택한 후 Valid 콤보상자에서 ‘판매수량Check’를 선택하고 판매단가 컬럼을 선택한 후 ‘판매단가Check’를 판매금액 컬럼을 선택한 후 ‘판매금액Check’를 선택해서 각각의 필드에 적합한 Check제약 조건을 매칭시킨다.

clip_image057

이번에는 값의 범위를 제한하거나 특정한 몇 개의 데이터만이 입력되어야 하는 내용을 정의하는 유형에 대해 알아보도록 하자.

우선 다음과 같은 성적 테이블이 있다고 하자.

clip_image059

국어, 영어, 수학 컬럼의 경우 입력될 수 있는 데이터의 범위는 0 ~ 100사이의 정수이다. 그리고 총점과 평균은 국어, 영어, 수학의 합과 평균이므로 계산하면 될 것이고 학점은 평균에 따라 A, B, C, D 그리고 F만이 입력될 수 있다고 하자.

이를 정의하기 위해서 다시 Validation Rules대화상자를 띄운 후에 국어, 영어, 수학 컬럼에 입력될 수 있는 값의 범위를 정의하기 위해 New버튼을 누른 후 ‘점수Rule’이라고 입력한 뒤 두 번째 옵션 버튼인 Min/Max를 선택한다.

그러면 아래 그림처럼 Min값과 Max값을 입력할 수 있는 입력상자가 나타나는데 여기에 0과 100을 입력하도록 하자.

clip_image061

여기서는 숫자형 데이터의 입력 범위를 지정하고 있으므로 ‘Quote’체크 박스는 선택하지 않으며 더군다나 ‘NOT’체크 박스도 선택할 필요가 없다.

‘점수Rule’은 국어, 영어, 수학 컬럼에 모두 적용될 제약조건 이므로 Rule로 만들어서 필요한 컬럼에 바인딩해야 하므로 SQL Server텝에서 sp_bindrule옵션을 선택하면 된다.

이렇게 정의하고 ‘OK’버튼을 누른 뒤 Columns대화상자에서 국어, 영어, 수학 컬럼의 Valid 콤보상자에서 점수를 선택하면 된다.

clip_image063[4]

그 다음 학점 필드에 입력될 수 있는 데이터를 정의해 보도록 하자.

다시 Validation Rules대화상자를 열고 New버튼을 누른 후 ‘학점Check’라고 이름을 입력한 후 이번에는 마지막 옵션 버튼인 Valid Value List 버튼을 선택하면 다음과 같이 값을 입력할 수 있는 그리드가 나타나게 된다.

clip_image065[4]

여기의 Valid Value 컬럼에 값의 리스트를 아래와 같이 정의하면 된다.

이는 문자열이기 때문에 Quote체크박스를 선택하도록 한다. NOT이라는 옵션을 사용하면 특정 데이터 이외의 값만을 받아들일 수 있도록 정의할 수 도 있을 것이다.

clip_image067

‘학점Check’역시 학점 컬럼에 적용되는 Check제약조건이기 때문에 SQL Server텝에서 CHECK Constraint옵션을 선택한다. 그런 다음 ‘OK’버튼을 누른 뒤 Columns대화상자에서 학점 컬럼을 선택하고 Valid 콤보상자에서 ‘학점Check’ 제약 조건을 선택하면 된다.

이제 Default값을 정의해 보도록 하자.

위의 성적 테이블에서 국어, 영어, 수학 컬럼에 데이터가 입력되지 않을 때 기본적으로 0값이 입력될 수 있도록 해야 한다. 이를 정의하기 위해서 이번에는 Columns대화상자에서 Default 뒤쪽의 버튼을 클릭한다.

clip_image070

그러면 이번에는 Default / initial Values 대화상자가 나타난다. 그런데 Default / initial Values 대화상자는 Validation Rules대화상자와는 달리 기본적으로 Default값을 정의할 수 있도록 TIMESTAMP나 USER등이 미리 정의되어 있다. 이들을 사용하려면 원하는 컬럼에 바로 Default값을 지정하면 될 것이다.

clip_image072

여기서는 기본적으로 국어, 영어, 수학 컬럼에 적용될 Default 값을 새로 정의할 것이므로 New 버튼을 누른 뒤 Default이름을 ‘기본점수’라고 입력하고 확인버튼을 눌러 새로운 Default 값을 정의하도록 하자.

Default를 적용시키는 방법도 두 가지가 있는데 하나는 Default를 데이터베이스 안에 개체( Object )로 생성한 뒤 여러 컬럼에 바인딩( Binding )하는 방법이고 다른 한가지는 일반적으로 사용하는 방법으로 테이블을 만들거나 수정할 때 직접 컬럼에 DefaultAttribute을 정의하는 방법이다. (전자를 절차적 방법이라고 하고 후자를 서술적 방법이라고 한다.)

이러한 내용을 구현하기 위해서는 Default / initial Values 대화상자에서 Generate As내에 옵션을 선택해서 구현할 수 있다.

전자가 sp_Bindefault옵션이고 후자가 Default옵션이다.

여기서는 어떠한 방법으로 정의한다 해도 무방하지만 여러 테이블의 여러 컬럼에 동일한 DefaultAttribute을 적용시키고자 한다면 절차적 방법을 통해 정의하는 것이 바람직하므로 절차적 방법의 Default를 정의해 보도록 하겠다.

우선 New버튼을 누른 뒤 Default 이름에 ‘기본점수’를 입력하고 확인버튼을 누른 뒤아래 처럼 값은 0을 입력하고 sp_Bindfault를 선택한다.

clip_image074

그런 다음 국어, 영어, 수학 필드에 Default를 기본점수로 선택해주면 된다.

clip_image076

인덱스정의방법

ERwin에서 인덱스를 정의하려면 Physical모델링에서 테이블을 선택한 뒤 오른쪽 버튼을 누른 후 팝업 메뉴에서 Indexes메뉴를 선택하면 된다. (물론 Columns대화 상자의 Index텝에서 정의할 수도 있고 Model메뉴의 Indexes메뉴를 선택해도 된다. )

이번 예제는 성적 테이블을 가지고 인덱스를 적용시켜 보도록 하겠다. 우선 성적 테이블을 선택한 후 오른쪽 버튼을 누른 후 팝업 메뉴에서 Indexes를 선택하면 다음과 같이 SQL Server Index대화상자가 나타나게 된다.

clip_image078

앞장에서 설명 했듯이 현재 우리는 성적 테이블에서 어떠한 인덱스도 정의한 적이 없지만 이미 하나의 인덱스가 만들어져 있는 모습을 볼 수 가 있다.

이 인덱스는 기본키에 의해 자동으로 만들어진 인덱스이다.

그 의미는 인덱스의 이름은 ‘X성적’이고 인덱스의 유형은 ‘PK’ (기본키) 인덱스이며 인덱스에 포함된 컬럼은 ‘번호’컬럼 이라는 뜻이다.

그런데 여기서 한가지 주의해야 할 내용이 있는데 ERwin에서 인덱스를 정의할 때 기본키 컬럼에 기본적으로 넌 클러스터드 인덱스가 적용된다는 점이다.

물론 클러스터드 인덱스로 만들 수도 있는데 그 옵션은 아래와 같이 SQL Server Indexes대화 상자의 SQL Server텝에서 확인해 볼 수 있다.

(기본적으로 기본키 인덱스는 UniqueAttribute에 선택된 상태에서 바꿀 수 없게끔 비활성화 되어 있다. )

clip_image081[4]

성적 테이블에서 만약 번호 컬럼이 클러스터드 인덱스로 적용된다면 어떻겠는가?

클러스터드 인덱스는 범위 쿼리(Range Query)할 때에 뛰어난 성능을 나타낸다고 했다.

그렇다면 번호를 기준으로 범위 쿼리를 할 경우가 얼마나 되는가?

1번부터 10번까지의 성적을 조회한다던가 아니면 20번부터 35번까지의 성적을 조회하는 일이 아마도 별로 많지는 않을 것이다.

오히려 총점이나 평균 혹은 학점을 기준으로 범위 쿼리를 하는 경우가 많을 것이다.

그러므로 번호 컬럼에는 넌 클러스터드 인덱스가 적합하며 총점과 평균, 학점 컬럼 중에는 업무적인 프로세서를 살펴본 후 클러스터드 인덱스를 정의해야 할 것이다.

여기서는 학점 컬럼에 클러스터드 인덱스를 적용해 보도록 하겠다.

새로운 인덱스를 만들려면 SQL Server Indexes대화상자에서 New버튼을 누른다.

그러면 아래의 그림 처럼 New Index대화 상자가 나타나게 되는데 여기서 중요한 옵션이 바로 Unique옵션이다.

기본적으로 이 옵션은 선택되어 있으며 인덱스로 정의할 컬럼의 데이터가 Unique하다면 선택을 해주어야 할 것이다.

만일 Unique옵션을 선택하지 않으면 Key Group의 이름이 ‘Invension Entry’로 바뀌는 것을 확인할 수 있는데 이는 데이터가 Unique하지는 않지만 자주 액세스 되는 컬럼에 인덱스를 정의할 때 사용하는 용어이다.

clip_image084

clip_image087

우리가 지금 인덱스를 정의할 학점 컬럼은 데이터가 Unique하지 않으므로 두번째 그림처럼 Unique옵션을 해제한 후 OK버튼을 누른다.

clip_image089

그러면 위의 그림처럼 새로운 인덱스가 만들어 지게 되는데 Members텝에서 학점컬럼을 선택한 후 추가 화살표 버튼을 눌러 오른쪽 Index 리스트 상자로 옮긴 후에SQL Server텝에서 Clustered체크박스를 선택하면 될 것이다.

clip_image091

이렇게 만들어진 인덱스는 Columns대화상자의 Index텝에서도 확인할 수 있다.

트리거(Trigger) 정의방법

트리거에 대한 개념과 이론은 위 ( 몇 장 )에서 설명했으므로 여기서는 부가적인 설명은 제외하고 기능적인 부분에 대해서 적용해보도록 하겠다.

ERwin에서 트리거를 정의하려면 Physical모델링에서 테이블을 선택한 뒤 오른쪽 버튼을 누른 후 팝업 메뉴에서 Triggers메뉴를 선택하면 된다.

이번 트리거에 대한 예제는 앞에서 다대다 관계를 해소하기 위해서 사용했던 예제를 통해 트리거를 정의해 보도록 하겠다.

clip_image035[5]clip_image035[6]clip_image035[7]clip_image092clip_image035[8]clip_image035[9]clip_image035[10]

clip_image094

기본적인 로직은 앞서 트리거를 설명할 때 했던 내용이므로 설명을 하지 않아도 될
것이다. 여기서는 납품 테이블에 데이터가 입력 되어질 때 상품 테이블의 재고 수
량에 더해지는 트리거만 만들어 보도록 하겠다.
납품 테이블에서 오른쪽 버튼을 누른 뒤 팝업 메뉴에서 Triggers메뉴를 선택하면
다음과 같이 Triggers대화상자가 나타나게 된다.
지금 현재 납품 테이블은 공급업체 테이블, 상품 테이블과 관계를 맺고 있으며 참조
무결성과 관련한 내용이 기본적으로 적용되어 있는 모습을 볼 수 있다.

여기서 New버튼을 누른 뒤 트리거의 이름을 ‘납품INS’로 정의하고 확인 버튼을 누
른다.
그런 다음 Code텝으로 전환한 후 다음과 같이 트리거를 정의하는 코딩을 Trigger
Code입력 상자의 마지막 부분 Return문장 바로 위에 다음 코트를에 추가로 삽입한
다.

DECLARE @CODE CHAR(6), @QTY INT

SET @CODE = (SELECT 상품코드 FROM INSERTED)

SET @QTY = (SELECT 납품수량 FROM INSERTED)

UPDATE 상품

SET 재고수량 = 재고수량 + @QTY

WHERE 상품코드 = @CODE

그런 다음 Expanded텝으로 전환한 해 보면 실제로 만들어질 트리거에 대한 내용들
정의되어 있는 모습을 확인할 수 있다.
코딩을 점검해 보고 이상이 없는 지 확인하자.

clip_image096

이 이후의 업데이트 트리거와 삭제트리거는 같은 요령으로 적용을 하면 될 것이다.

 

(View) 정의방법

: ERwin에서 뷰(View)를 만들려면 물리적(Physical)모델링 단계에서 ERwin Toolbox
에 있는 ViewTable을 선택해서 만들 수 있다.

clip_image098

clip_image099[4]

clip_image100

Entity를 만들 때 처럼 View Table을 선택한 후 다이어그램에 클릭하면 다음과
같은 모습으로 뷰가 만들어지게 되는데 이 뷰에 포함하고자 하는 컬럼을 드레그
엔 드롭하게되면 뷰필드가 구성이되어 진다.

clip_image102[4]

우리는 여기서 판매테이블의 데이터를 조회하는 뷰를 만들것이며 이름을
‘판매View’로 정의할 것이다.
( 뷰의 이름을 바꾸려면 Entity 이름을 바꿀 때 처럼 바꾸어주면 된다.)

뷰의 이름을 ‘판매View’로 바꾼 뒤 뷰로 구성할 필드( 판매.판매번호, 회원.회원
이름, 상품.상품명, 판매.판매일자, 판매.판매수량, 판매.판매단가, 판매.판매금액 )들
을 ‘판매View’에 끌어다 놓으면 다음과 같은 아래와 같은 모습이 될 것이다.

clip_image104

이렇게 뷰를 생성하게되면 현재 생성된 뷰는 조인의 조건이 정의되지 않은 뷰
( Cross Join 상태의 뷰)가 만들어지게 되며 조인의 조건과 정열 조건등을 따로 지정
해 주어야 하는데 이렇게 하기 위해서는 뷰에서 오른쪽 버튼을 누른 후 Database
View Properties메뉴를 선택하면 다음과 같은 Views대화상자가 나타나게 된다.

clip_image106[4]

Views 대화상자의 Select텝을 보면 뷰에 사용된 테이블의 나머지 컬럼들과 뷰로 구
성된 컬럼들의 모습이 보여지게 된다.

From텝에는 뷰에 사용된 테이블들이 보여지게 되며 조인의 조건을 포함한 조회의
조건등을 지정하기 위해서는 Where텝에서 관련된 내용을 정의해 주어야 한다.

정상적으로 조회가 이루어 질 수 있도록 Where텝의 Where절에 다음과 같은 구문을
추가해 보도록 하자.

판매.회원번호 = 회원.회원번호 AND

판매.상품코드 = 상품.상품코드

clip_image108[4]
그런 다음 SQL텝에서 완성된 뷰 문장을 확인해 보도록 하자.

 

스토어드프로시저( Stored Procedure ) 정의방법

: ERwin에서 스토어드 프로시저(Stored Procedure)를 만들려면 물리적(Physical)모델
링 단계에서 DataBase 메뉴 / Stored Procedure메뉴를 선택하면 Model-Level메뉴와
Table-Level의 두 가지 메뉴를 만나게 되는데 테이블(Table)이나 뷰(View)에 기반
한 스토어드 프로시저를 만들고자 한다면 Table레벨을 선택하면 되고 값의 계산
이나 부가적인 프로세스를 처리하기 위한 스토어드 프로시저를 정의하고자 한다
면 Model-Level을 선택하면 된다.
하지만 이 둘의 차이는 궁극적으로 없으며 SQL Server에서 스도어드 프로시저를
만들 경우 예를들어 판매 현황을 조회하는 스토어드 프로시저를 만들고자 하는데
지금 당장 판매 테이블이 데이터베이스에 없더라도 만들 수 있는 기능 즉 이름
지연이 가능하기 때문이다.

( 중요한 내용이 아니므로 중략하기로 한다. )

위에서 뷰를 만들 때 판매 테이블의 데이터를 조회하는 뷰를 만들었으므로 여기
서는 납품 테이블의 납품 현황을 날짜별로 조회할 수 있는 스토어드 프로시저를
만들어 보도록 하겠다.

clip_image110

Table-Level의 스토어드 프로시저는 위의 방법으로도 만들 수 있지만 해당 테이
블의 오른쪽 버튼을 누른 뒤 팝업 메뉴에서 Stored Procedure를 선택해도 만들
수 있다.
여기서는 납품 테이블을 기반으로 한 스토어드 프로시저를 만들 것이므로 납품
테이블을 선택하고 오른쪽 버튼을 누른 뒤 Stored Procedure메뉴를 선택하면 다
음과 같이 Stored Procedure대화상자가 나타나게 된다.

여기서 New버튼을 누른 뒤 ‘S_일일납품현황’이라는 이름을 입력한 뒤 확인 버튼을
누르면 다음 그림과 같이 Code입력 상자가 사용할 수 있게끔 활성화 되어지게 되
는데 여기에 다음과 같은 코드를 입력해서 스토어드 프로시저를 정의해 보도록 하자.

CREATE PROCEDURE S_일일납품현황

@SDATE CHAR(8)

AS

SELECT 납품.납품번호, 상품.상품명, 공급업체.업체명,

납품.납품일자, 납품.납품수량, 납품.납품단가,

납품.납품금액

FROM 납품, 상품, 공급업체

WHERE 납품.상품코드 = 상품.상품코드

AND 납품.업체코드 = 공급업체.업체코드

AND 납품.납품일자 = @SDATE

그러면 다음과 같은 모습이 되며 이렇게 하면 ‘S_일일납품현황’이라고 하는 스토어
드 프로시저가 만들어지게 된다.

clip_image112

여기서 간단하게 스토어드 프로시저를 하나 만들어 봤는데 실제로 스토어드 프로시
저의 사용은 속도 향상, 유지 보수의 편의성, 네트워크 트레픽의 감소등등 단점 보
다는 장점이 월등하게 많은 아주 훌륭한 데이터베이스 개체(Object)이다.
여태껏 직접 애플리케이션에서 SQL문장을 정의해서 사용 했다면 앞으로는 스토어
드 프로시저를 사용해서 코딩을 해야 할 것이다.

업무와 관련한 모든 SQL문장을 스토어드 프로시저로 작성했다면 당연히 스토어드
프로시저의 숫자는 한 데이터베이스 안에 아주 많은 수의 스토어드 프로시저가 만
들어지게 될 것이다.
그러한 스토어드 프로시저를 모두 모아서 관리하려면 DataBase메뉴 / Stored
Procedure / Model-Level을 선택하면 된다.
그러면 위와 비슷한 Stored Procedure대화 상자가 나타나게 되는데 위와 다른게 없
어 보이지만 위에는 없는 Display콤보상자가 있으며 이 다이어그램 안에서 정의된
모든 스토어드 프로시저 목록과 함께 코드도 나와 있으며 물론 이 대화상자에서
새로운 스토어드 프로시저도 만들 수 있다.

clip_image114[4]

* 참고 : 여태까지의 예를 보면 테이블이나 컬럼의 이름등을 모두 한글로 정의해서
사용했다. 그러나 실제로 현업에서 데이터베이스 내의 개체(Object)명을
한글로 정의해서 사용하는 경우는 그리 많지는 않다.
물론 한글을 사용해서 반드시 문제가 되는 것은 아니지만 과거 한글 지원
이 부족했던 시절부터 내려온 하나의 관습이라고 볼 수 있다.
해서 ERwin을 사용할 때도 논리적(Logical)모델링에서는 한글로 Entity
(Entity)나 어트리뷰트(Attribute)를 정의하고 물리적(Physical) 모델링에서는
그 이름들을 영문으로 전환해서 사용하는 경우가 많은데 이렇게 물리적
모델링 단계에서 Object명을 영문으로 바꾼다 하더라도 아래의 그림처럼
논리적 모델링 단계에서 정의된 한글명은 그데로 유지 되어진다.

 

Logical Model  ---->  Physical Model

clip_image002                   -clip_image002[5]

 

 

 

파일그룹정의

하나의 데이터베이스는 최소한 하나 이상의 데이터 파일과 로그 파일로 구성

clip_image120 :

clip_image121

Data File                         Log File

 

SQL Server는 위의 그림처럼 하나의 데이터베이스에 여러 개의 데이터 파일을 구성할 수 있으며 이때 데이터 파일의 확장자는 .mdf나 .ndf이고 로그 파일의 확장자는 .ldf이다.

데이터 파일(.mdf) : 데이터베이스를 생성할 때 가장 먼저 정의된 데이터 파일에 기본적으로 적용
                               추가적으로 데이터 파일이 만들어지는 데이터 파일들은 .ndf라는 확장자를 갖게 된다.
그리고 이러한 파일들은 그룹으로 관리되어 지는데 기본적으로 SQL Server에서 만들어지는 모든 데이터 파일들은 주(Primary)파일 그룹의 구성원이 되며 새로운 파일 그룹을 만들어서 데이터 파일들을 관리자 임의로 파일 그룹에 포함시킬 수 있다.

* 참고 : 기본적으로 주(Primary) 파일 그룹에 데이터베이스 시스템 테이블이 존재하게 되며 새로운 테이블이나 뷰등을 만들 때 기본적으로 만들어지는 파일그룹 역시 주(Primary) 파일 그룹이다.

SQL Server에서는 개별적인 파일이나 파일 그룹별로 백업이나 복구를 할 수 있으며 저장 될 위치들을 개별적으로 정의할 수 있다. 이는 각각의 하드디스크에 파일들의 위치를 분산 시킴으로 해서 디스크에서 데이터를 읽고 쓰는데에 있어서의 경쟁을 피할 수 있음으로 시스템의 성능을 극대화시킬 수 있는 방법으로 사용된다.
그리고 더군다나 데이터베이스의 테이블이나 인덱스가 저장되는 파일 그룹을 관리자가 임의로 지정할 수 있는데 예를 들어 아래의 그림처럼 파일 그룹 A는 D:드라이브에 파일 그룹 B는 E:드라이브에 만든 다음 판매 테이블은 파일 그룹 A에 저장하고 판매 테이블의 인덱스 들은 파일 그룹 B에 저장할 수 있다.

clip_image123

clip_image124 clip_image125

이렇게 저장하게 되면 판매 테이블에 데이터가 입력 되었을 경우 실제 데이터의 변경 사항은 D:드라이브가 인덱스의 변경 사항은 E:드라이브가 담당하게 되므로 보다 낳은 성능향상을 기대할 수 있다.

다음 예는 SQL Server에서 데이터베이스를 만들면서 파일 그룹을 정의한 후에 ERwin에서 테이블과 인덱스를 메칭 시키는 예제이다. 아래의 그림과 같이 엔터프라이즈 관리자에서 ‘연습DB’라는 이름의 데이터베이스
를 만들어 보자.

clip_image127[4]

파일이름               위치                                          처음크기                파일그룹

연습DB_Data         C:\Data\연습DB_Data.MDF        10                          PRIMARY

연습DB_Data1       D:\Data\연습DB_Data1.NDF       20                          FGA

연습DB_Data2       E:\Data\연습DB_Data2.NDF       20                          FGB

PRIMARY 파일 그룹의 이름은 변경할 수 없으며 두 번째 파일 그룹은 ‘FGA’ 세번째 파일 그룹은 ‘FGB’명으로 정의했다.이제 다음으로 ERwin에서 파일 그룹을 정의해 보도록 하자.

clip_image129

ERwin에서 파일 그룹은 Model Explorer의 ‘Filegroup’에서 오른쪽 버튼을 누른 뒤 New메뉴를 눌러 정의할 수 있다. 그럼 다음 그림처럼 차례로 ‘FGA’, ‘FGB’라는 파일 그룹 두개를 만들어 보자.그런 다음 각각 판매 테이블은 ‘FGA’ 그리고 판매 테이블의 인덱스는 ‘FGB’ 파일 그룹에 저장될 수 있도록 정의해 보도록 하겠다.

우선 판매 테이블을 정의하려면 판매 테이블에서 오른쪽 버튼을 누른 뒤 팝업 메뉴에서 Table Properties / Physical Property메뉴를 선택하면 다음과 같이 SQL Server Tables대화 상자가 나타나게 되는데 Filegroup 콤보상자에서 ‘FGA’목록을 선택하면 된다.

clip_image131

그런 다음 인덱스를 정의해야 하는데 현재 판매 테이블에는 기본키에 기본적으로 적
용되는 인덱스만이 존재하고 있고 여기에 추가로 아래의 표에 나와있는 것 처럼 판
매일자에 넌 클러스터드 인덱스를 만들어 보자.

인덱스            유형                        유니크             컬럼           종류                              파일그룹     

X판매             기본키                     Unique             판매번호   Non Clustered Index      FGB

XIE1판매         Inversion Entry       Non Unique      판매날짜   Clustered Index              FGB

그런 다음 아래의 그림 처럼 ‘X판매’인덱스와 ‘XIE1판매’인덱스 모두 Filegroup콤보상자에서 ‘FGB’를 선택하여 인덱스의 파일 그룹을 정의한다.

clip_image133

이상으로 파일 그룹의 의미와 파일 그룹을 정의하는 방법에 대해서 살펴보았다. 그런데 위의 예에는 한가지 크게 잘못된 내용이 있다. 그 내용은 다음에 소개할 데이터베이스 스키마 생성에서 설명하도록 하겠다. 만일 RAID장비를 사용한다면 구지 복잡하게 파일 그룹등을 정의해서 사용해야 할 필요는 없을 것이다.
하지만 RAID장비는 비교적 고가이고 일반적으로 소규모 기업에서는 RAID장비를 이용하기가 쉽지 않으므로 위와 같이 여러 개의 물리적인 하드 디스크에 파일 그룹 을 위치하는 방법으로 추가적인 비용부담 없이 보다 나은 성능 향상을 기대할 수 있을 것이다.

 

데이터베이스스키마생성

물리적 데이터 모델링 단계를 거치면서 데이터베이스의 스키마를 디자인 했다면 이제 이렇게 정의된 내용을 실제 데이터베이스 객체로 만들어질 수 있도록 해야 하는데 이를 데이터베이스 스키마 생성이라고 한다.

우선 디자인 된 스키마를 데이터베이스 스키마로 만들기 위해서는 우선 목적 데이터베이스에 연결해야 한다.

. 데이터베이스에 연결하기 전에 우선 SQL Server에서 ‘Exdb’라는 이름의 데이터베이스 생성
image 

. ERwin에  Database > Database Connection... 
  SQL Server Connection대화상자에서 정보입력(Database 입력상자에는 스키마를 생성 할 데이터베이스 이름, Server Name은 데이터베이스 서버 시스템의 컴퓨터 이름..) 하여 접속  
  그런 다음 Connect 버튼을 누르면 연결을 시도하게 되는데 연결이 정상적으로 이 루어지면 SQL Server Connection대화상자가 사라지게 된다. 아니면 에러 메시지가 나타난다.

* ‘sa’는 SQL Server에서 최고 관리자 계정이며 SQL Server를 설치할 때 비밀번호를 정의했다면 Password입력상자에도 비밀번호를 입력해야한다. ‘sa’ 계정에 아무런 비밀번호도 정의하지 않았다면 입력하지 않는다.


image 

clip_image135

 

. 정상적으로 연결이 됐다면 이제 데이터베이스 스키마를 생성해야 한다.

Tool> Forward Engineer / Schema generation...   SQL Server Schema Generation대화상자

image 
여기서 Generatie 버튼을 누르면 스크립트가 실행 되면서 ‘Exdb’ 데이터베이스에 ERwin에서 정의한 스키마가 만들어 지게 됨
(이 상태에서는 파일 그룹이 적용되지 않으므로  앞에서 정의한 파일그룹의 설정 내용이 실제 데이터베이스에 적용되도록 하려면 아래의 그림처럼 Table과 Index에 있는 Schema옵션 중에서 Physical Storage옵션을 선택 해야만 한다.

clip_image139

clip_image141[4]

만약 중간에 에러가 나면 어떤 종류의 에러메시지인지 잘 확인해 보도록 하자.

그런 다음 해당내용을 다시 ERwin에서 수정해 주어야 하며 위의 Generate Database Schema 대화상자에서 저장 버튼을 눌러 위의 스크립트를 저장해 두도록 하자. 저장 파일의 확장자는 ‘ere’이며 메모장으로 열어서 내용을 확인 할 수 있다.

모두 정상적으로 작업을 마쳤다면 이제 실제 데이터베이스 스키마가 정상적으로 생성되었는지를 SQL Server에서 확인해 보도록 하자. 만일 SQL Server에서 아래와 같이 개체(Object)들이 보이지 않는다면 F5키를 눌러서 REFRESH한 다음 다시한번 확인해 보자. 테이블(Table), 뷰(View), 저장 프로시저( Stored Procedure), 규칙( Rule), 기본값( Default ),트리거(Trigger)등등 모든 내용들을 살펴보자.

clip_image143

* 참고 : 앞에서 파일 그룹을 정의해서 사용했는데 실제로 판매 테이블과 판매테이블의 인덱스가 원하는 파일 그룹에 저장되었는지를 확인하려면 쿼리 분석기에서 ‘SP_HELP 판매’ 를 실행하면 아래와 같이 테이블과 인덱스들의 파일 그 룹에 대한 정보를 확인할 수 있다.

clip_image145

위의 화면에서 Data_located_on_filegroup은 판매 테이블이 위치해 있는 파일 그룹에 대한 정보를 보여주고 있으며 그 밑에 인덱스와 인덱스 유형 그리고 인덱스가 위치해 있는 파일 그룹에 대한 정보를 보여주고 있다.
그런데 판매 테이블의 위치가 ‘FGB’로 정의되어 있다.
이전 실습에서 분명히 판매 테이블의 파일 그룹을 ‘FGA’로 정의했었다. ERwin으로 가서 다시 한번 확인해 보도록 하자.

그런데 이게 왠일인가? 혹시 버그 ?
그렇다면 데이터베이스 스키마를 생성할 때 저장했던 스크립트를 열어서 판매 테이
블과 관련한 내용을 확인해 보자.

CREATE TABLE 판매 (
판매번호 bigint NOT NULL,
판매날짜 char(8),
판매단가 int,
판매수량 int,
판매금액 int,
회원번호 char(8) NOT NULL,
상품코드 char(6) NOT NULL
)  ON "FGA"    
Execution Successful

CREATE CLUSTERED INDEX XIE1판매 ON 판매 ( 판매날짜
) ON "FGB"
Execution Successful

ALTER TABLE 판매
ADD PRIMARY KEY NONCLUSTERED (판매번호)
ON "FGB"
Execution Successful

아마도 인덱스에 대해서 제대로 공부하신 분들이라면 위 상황에 대한 대답을 할 수 있을 것이다.
클러스터드 인덱스는 인덱스의 리프 레벨(Leaf Level)이 데이터 페이지(Data Page)이다. 해서 위의 소스코드에서 테이블을 만들 때는 ‘FGA’파일 그룹에 만들어 지지만 판매날짜 컬럼에 클러스터드 인덱스를 만들면서 인덱스의 리프 레벨 (Leaf Level) 즉 데이터 페이지 ( Data Page )가 ‘FGB’파일 그룹으로 재정의 되어졌다. 해서 판매 테이블이 최종적으로 위치하게 되는 파일 그룹은 ‘FGB’인 것이다. 그렇기 때문에 아무리 테이블의 파일 그룹과 인덱스의 파일 그룹을 구분한다 하더라도 클러스터드 인덱스가 만들어지면 클러스터드 인덱스가 정의된 파일 그룹에 테이블이 위치하게 되기 때문에 클러스터드 인덱스는 테이블을 저장하고자 하는 파일 그룹에 정의해야 하며 넌 클러스터드 인덱스를 테이블과 다른 파일 그룹에 저장해야 한다.
위의 파일 그룹에 대한 예는 다음 도표처럼 판매 테이블에 인덱스를 정의해야 한다.

인덱스       유형                      유니크              컬럼          종류                            파일그룹 

X판매         기본키                  Unique             판매번호   Non Clustered Index    FGB

XIE1판매     Inversion Entry    Non Unique      판매날짜   Clustered Index           FGA

그런 다음 다시한번 쿼리 분석기에서 ‘SP_HELP 판매’문을 실행하면 다음과 같이 테이블과 판매날짜 컬럼의 인덱스는 ‘FGA’ 파일 그룹에 그리고 판매 테이블의 기본키 인덱스는 ‘FGB’파일 그룹에 있는 것을 확인할 수 있다.

clip_image147[4]

프린트하기

1. 가로 방향 or 세로 방향으로 출력 선택 :  File > Print Setup 
2. File >  Print
   
출력 용지의 외곽선을 선택해서 출력물의 위치와 사이즈를 정의
    오른쪽 밑에 Fit Model버튼을 누르면 전체 디자인 했던 스키마가모두 보여질 수 있도록 자동으로 사이즈를 최적화
clip_image149[4]

에러처리: ERWin Unable to locate client connectivity software

-------------------------------------------------------------------------------------------

 

XP Home에서 원격 데스크톱 사용하기

$
0
0


Windows XP Home 에디션은 잘 알고 있는 것과 같이 Remote Desktop, 또는 Terminal Services 기능이 없으며 또한 지원되지도 않습니다. 원격 데스크톱 기능에 대하여 글 말미의 도움말에서 발췌한 내용을 참조합니다. 아래 트릭으로 Windows XP에서 Remote Desktop Protocol (RDP)를 인스톨하여 사용할 수 있습니다.

Windows XP Home에서 Remote Desktop Terminal Services(Server 구성 요소)를 실행하려면 우선 이 사이트의 아래 기사를 참조하여 Windows XP Home 에디션 자체가 자신을 XP Pro 에디션으로 인식토록 합니다.

XP Home 에디션을 Pro 에디션으로 업그레이드하는 방법 

Windows XP Home 에디션을 Windows XP Professional 에디션으로 전환하여 업그레이드하는 방법은 아래 순서를 따릅니다. [시작]-[실행]을 차례로 눌러 텍스트 입력창에 'regedit'를 타자한 후 엔터 키를 눌러 레지스트리 편집기를 기동합니다. 다음의 레지스트리 분기점까지 찾아갑니다.

HKEY_LOCAL_MACHINE/SYSTEM/ControlSet00X/Control/ProductOptions
ControlSet00X라는 표현에서 X(ControlSet004)의 숫자가 제일 큰 항목을 선택합니다.
ProductSuite레지스트리 키를 삭제합니다.
새로운 DWORD 값을 만들고 그 이름을 Brand로 합니다.
새로 만든 “Brand”의 값 데이터를 '0'으로 설정합니다.

시스템을 재부팅합니다.
재부팅 시에 BIOS 화면 바로 다음에 F8 키를 눌러 [Windows XP 시작 메뉴]가 나오도록 합니다.
[마지막으로 성공한 모드(Last Goog Configuration:LNG)]을 선택하여 엔터키를 누릅니다.
Windows XP는 여늬와 같이 부팅됩니다만, [바탕 화면]에 로깅한 후 [시스템 등록 정보]에서 확인하면 이제 사용자 시스템의 Windows XP Home 에디션은 Pro 에디션으로 보이게 됩니다.


위 트릭 적용 후, [내 컴퓨터]를 마우스 우클릭-[속성]을 선택-[시스템 등록 정보]에서 설치된 Home 에디션이 Pro 에디션으로 인식되고 있음을 확인합니다.

[장치 관리자]의 다른 수단인 명령줄 유틸리티인, DevCon을 아래에서 다이렉트로 다운로드합니다.
Devcon.exe

devcon.exe는 자동 풀림 압축이며, 이를 실행하여 적당 폴더를 선택하면, i386 그리고 ia64이라는 폴더를 만들어 압축 해제가 됩니다.
명령 프롬프트 창(CMD)을 열어 DevCon에 의하여 생성된 i386 폴더로 옮겨 rdpdr 드라이버를 재설치하기 위하여 아래 명령을 실행합니다.

devcon.exe -r install %windir%\inf\machine.inf root\rdpdr

위 명령 실행 후 컴퓨터를 재시작합니다.
이 단계에서는 아직도, 이 짜가 XP Pro로 전환된 Windows는 아직 Remote Desktop을 실행하기 위하여 필요한 Terminal Services에 연관된 레지스트리 설정이 없는 상태입니다.
Pro OS로 튜닝된 Windows XP Home에서 Terminal Services를 설치하여 사용할 수 있도록 하기 위하여 아래 배치 스크립트(역시 Windows 2000에서 TS를 지원 가능토록 함)를 다운로드하여 실행합니다.

Enable_tsxp.ba
이는 Terminal Services 값을 레지스트리에 병합함에 필요한 등록 파일(.reg)과 bootlog를 생성합니다.
레지스트리 패치 후 컴퓨터를 재부팅합니다.
재부팅 후는 Terminal Services가 실행되어 Incoming Remote Desktop Connection session을 수용하고 실행할 수 있는 준비가 된 상태로 됩니다.

Terminal Services가 실제로 작동하고 있는지를 검증하기 위해서는, Control Panel -> Administrator Tools -> Services에서 [Terminal Services] 앤트리를 하이라이트합니다. 만약에 [시작]되지 않았다면 수동으로 시작토록 합니다. [시스템 등록 정보]에는 [원격] 탭이 없으며, 원격 데스크톱의 기본 포트인 포트 3389가 방화벽에서 열려 있음을 확인합니다.

레지스트리 설정이 자동 로그온 기능의 활성으로 되어 있으면 매 로컬 콘솔에서 시스템 기동 시에 Administrator로 자동 로그인하여 암호 입력을 프롬프트하지 않거나 아니면, 사용자에게 로그온할 계정의 선택을 허용합니다.  이 기능을 사용치 않는 것으로 설정하려면 아래 레지스트리 분기점을 찾아 AutoAdminLogin의 값 데이터를 '1'에서 '0'으로 변경 설정합니다.

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon









XML 특수문자 입력(이스케이프 문자 사용) - Entity

형태소 분석 회사 목록 및 매뉴얼

$
0
0


형태소 분석 회사 목록 및 매뉴얼

고어 형태소 분석기와는 달리, 현대어 형태소 분석기는 매우 많은 회사들이 개발하였다.
처음엔 눈에 띄지 않았는데, 내가 개발하는 엔진이 약간 돌아가는 시점에서 많은 회사들의 제품들이 눈에 들어왔다.
대학 연구소쪽은 국내 AI의 황제들을 통해서 많이 찾아봤다.
내일 아침부터 아무 일도 못하는데, 오늘은 하루 종일 구글링만 했다....

1) 크리스탈인포 : 네이버에 있을 때 개발한 형태소 분석 시스템이라고 하는데, 지금도 쓰이는지는 알 수 없다.
    메인 개발자였던 분이 운영하는 블로그다. 1차 버전 개발기간 3개월, 상용화까지 1년이상 소요되었다고 한다. 한번 만나보고 싶을 정도로 대단한 실력의 소유자인 것 같다.
2) 모란소프트 : 다음 커뮤니케이션즈와 엠파스에 제공된 형태소 분석 시스템이라고 한다.
    CJK 형태소분석기의 매뉴얼이다. 내가 개발한 엔진의 매뉴얼과 API가 상당히 유사하다. 일단, Pure C로 만들어졌기 때문에 API가 내게 매우 친숙하고, 확률정보를 이용하는 방법도 유사하다. API 자체만으로도 분석해볼 대상인 듯하다.
3) 더자랩 : 드림아이커뮤니케이션즈에서 사용하는 검색엔진을 제작한 회사라고 한다. 1차 형태소분석 시스템을 2004년에 개발했다. 데모 페이지의 결과는 학술적으로 이용하기는 그다지 적합하지 않다. 분석 속도에 중점을 둔 듯하다.
4) MACH : 심광섭(성신여대 컴공) & 양재형 (강남대) 분들이 함께 개발한 Supersonic 형태소 분석기이다. 상용화탑재가 된 적이 있는지는 잘 모르겠다. 데모 시스템은 돌아가지 않고 있다. 
5) 고려대학교 자연어처리연구실 : 학술적으로 개발했거나, 21세기 세종계획의 코퍼스 구축에 쓰인 도구인 듯하다. 코퍼스 구축에서 여러가지 후보를 내는 것이 목적같다. 데모 사이트에서 결과를 볼 수 있다.
6) 국민대학교 자연어처리연구실 : 서열로 따지자면 가장 상위에 올라가야 하는 대표적인 형태소분석 사이트지만, 검색하다보니 아래에 위치하게 됐다. 강승식 교수님이 만든 KLT(구,HAM) 형태소분석기 사이트이다. 한글 스펠러는 나모 웹 에디터에 장착되어 있다.
7) 부산대학교 한국어정보처리연구실 : 권혁철 교수님의 지도하에 있는 국가지정연구실이다. 온톨로지를 포함한 많은 사이트들을 개발했는데, 작년까지로 진행과제들이 모두 종결된 듯하다. 현재 진행과제는 알 수 없고, 데모사이트가 없어서 안타깝다.
    나라인포테크도 이 연구실과 밀접하다.
8) 워드워즈 : 재작년에 설립된 언어처리 회사로 CMU 출신들을 중심으로 모여있다. 
    현재 대표로 계신 서승현 선생님의 (고요한 하늘님이 잘못되었다고 알려주셨습니다. 감사합니다.) 서승현 선생님과 친분이 있는 분의  블로그다.
9) 쓰리소프트 : 지능형 검색 솔루션 및 형태소 분석 시스템을 개발한 회사다. 연혁도 오래되었고, 정보검색 쪽에서는 가장 큰 회사가 아닐까 싶다. 형태소분석기의 소개 사이트이다.
10) 울산대학교 한국어처리연구실 : 옥철영 교수님의 지도하에 다양한 언어처리 솔루션을 개발한다. 데모 사이트는 제작중이라 보기 힘들다.
11) 충북대 자연어처리 연구실 : 서영훈 교수님의 지도하에 언어처리 솔루션 개발중이다.
12) 서강대 자연어처리 연구실 : 서정연 교수님의 지도하에 있고, 다이퀘스트라는 검색회사를 설립했다. 다이퀘스트는 현재 접속불가능하다.(AnonymousY 님이 알려주셨습니다. 감사합니다.)
13) 포항공대 자연어처리연구실 : 이근배 교수님의 지도하에 있다.
14) 경북대 언어정보처리연구실 : 이상조 교수님의 지도하에 있다.
15) 포항공대 지식언어공학연구실 : 이종혁 교수님의 지도하에 있다. 세종전자사전의 전산처리를 담당하고 있다.
      세종사전을 이용한 형태소분석기를 개발한 바 있다. 데모시스템은 공개하지 않았다.

검색을 해도 업계의 동향을 모르면 놓치는 게 많다.... 다이퀘스트 기업홍보란에서 퍼온 기사다.
http://itnews.inews24.com/php/news_view.php?g_serial=316355&g_menu=020200

Big-endian, Little-endian, and Byte Order Mark

$
0
0


  • Big Endian : 자릿수가 큰쪽 바이트가 먼저 저장. (ex) 3E1F 23A1 => 3E1F 23A1
    • 장점 : 사람이 이해하는 방식으로 표기하므로, 수치를 읽는데 자연스럽다.

  • Little Endian : 자릿수가 작은 쪽 바이트가 먼저 저장 (ex) 3E1F 23A1 => 1F3E A123
    • 장점 : 자릿수가 변하는 연산시 Big Endian 보다 빠르다. 자릿수 올림이 발생했을 경우( 예를 들면 F + 1 = 10 ), Big Endian의 경우는 자릿수가 밀려서 저장이 되어야 한다. 이는  performance issue 가 발생할 수 있으며 little Endian 을 채택한 경우 기존 자리는 그대로 있고 맨 뒤에 추가만 하면 되기 때문이다.

Byte Order Mark (BOM) : 현재 입력된 문자의 byte의 순서에 대한 정보가 담긴 Unicode Character. 파일의 맨 앞에 등장하며, 생략 가능하다.
 Encoding Hexadecimal
 UTF-8 EF BB BF 
 UTF-16 Big Endian FE FF
 UTF-16 Little Endian FF FE 
 UTF-32 Big Endian 00 00 FE FF 
 UTF-32 Little Endian FF FE 00 00 
 GB-1803084 31 95 33 

구글 크롬 단축키

$
0
0



창 또는 탭 바로가기

  • Ctrl+N
    • 새 창을 엽니다.
  • Ctrl+T
    • 새 탭을 엽니다.
  • Ctrl+Shift+N
    • 시크릿 모드로 새 창을 엽니다.
  • Ctrl+O를 누른 상태에서 파일 선택
    • 컴퓨터에서 선택한 파일을 Google 크롬에서 엽니다.
  • Ctrl을 누른 상태에서 링크 클릭
    • 새 탭에서 링크를 엽니다.
  • Shift를 누른 상태에서 링크 클릭
    • 새 창에서 링크를 엽니다.
  • Alt+F4
    • 현재 창을 닫습니다.
  • Ctrl+Shift+T
    • 닫았던 마지막 탭을 다시 엽니다. Google 크롬은 닫았던 탭을 10개까지 기억합니다.
  • 링크를 탭으로 드래그
    • 해당 탭에서 링크를 엽니다.
  • 링크를 탭 사이로 드래그
    • 탭 표시줄상의 특정 위치에서 새 탭으로 링크를 엽니다.
  • Ctrl+1~Ctrl+8
    • 지정된 숫자에 해당하는 위치의 탭으로 전환합니다. 각 숫자는 탭 표시줄상의 탭 위치를 나타냅니다.
  • Ctrl+9
    • 마지막 탭으로 전환합니다.
  • Ctrl+Tab 또는 Ctrl+PgDown
    • 다음 탭으로 전환합니다.
  • Ctrl+Shift+Tab 또는 Ctrl+PgUp
    • 이전 탭으로 전환합니다.
  • Ctrl+W 또는 Ctrl+F4
    • 현재 탭이나 팝업을 닫습니다.
  • Alt+Home
    • 홈페이지를 엽니다.

검색주소창 단축키

  • 검색어 입력
    • 기본 검색엔진을 사용하여 검색을 수행합니다.
  • 'www.'와 '.com' 사이의 웹주소 일부를 입력하고 Ctrl+Enter 누르기
    • 검색주소창에 입력된 검색어에 www. 및 .com을 추가하여 웹 주소를 완성하고 해당 웹페이지를 엽니다
  • 검색엔진 키워드나 URL을 입력하고 Tab을 누른 후 검색어 입력
    • 키워드나 URL에 연결된 검색엔진을 사용하여 검색을 수행합니다. 사용하려는 검색엔진을 Google 크롬에서 인식하면 Tab을 누르라는 메시지가 표시됩니다.
  • F6, Ctrl+L 또는 Alt+D
    • 웹 주소 영역에 있는 콘텐츠를 강조표시합니다.
  • 웹 주소를 입력한 후 Alt+Enter 누르기
    • 새 탭에서 입력된 주소의 웹페이지를 엽니다.

Google 크롬의 각 기능별 단축키

  • Ctrl+B
    • 북마크바 설정/해제
  • Ctrl+Shift+B
    • 북마크 관리자 열기
  • Ctrl+H
    • '방문한 페이지' 목록 보기
  • Ctrl+J
    • 다운로드 페이지 보기
  • Shift+Esc
    • 작업 관리자 보기
  • Shift+Alt+T
    • 툴바로 키보드의 포커스 옮기기. 키보드의 오른쪽 및 왼쪽 화살표 키를 사용하면 툴바의 각 버튼을 탐색할 수 있습니다.

웹페이지 단축키

  • Ctrl+P
    • 현재 페이지 인쇄
  • Ctrl+S
    • 현재 페이지 저장
  • F5
    • 현재 페이지 새로고침
  • Esc
    • 페이지 로딩 중지
  • Ctrl+F5 또는 Shift+F5
    • 저장된 콘텐츠를 무시하고 현재 페이지를 새로 고침
  • Alt를 누른 상태에서 링크 클릭
    • 링크 다운로드
  • Ctrl+F
    • '페이지에서 찾기' 상자 열기
  • Ctrl+G 또는 F3
    • 페이지에서 찾기 상자에 입력된 검색어와 일치하는 다음 단어 찾기
  • Ctrl+Shift+G 또는 Shift+F3
    • 페이지에서 찾기 상자에 입력된 검색어와 일치하는 이전 단어 찾기
  • Ctrl+U
    • 소스 보기
  • 링크를 북마크바로 드래그
    • 링크 북마크
  • Ctrl+D
    • 현재 웹페이지 북마크
  • Ctrl++
    • 텍스트 확대
  • Ctrl+-
    • 텍스트 축소
  • Ctrl+0
    • 기본 텍스트 크기로 되돌리기

텍스트 단축키

  • 콘텐츠를 선택한 다음 Ctrl+C 누르기
    • 콘텐츠를 클립보드로 복사합니다.
  • 텍스트 입력란으로 커서를 옮긴 다음 Ctrl+V 또는 Shift+Insert 누르기
    • 클립보드의 콘텐츠를 붙여넣습니다.
  • 텍스트 입력란으로 커서를 옮긴 다음 Ctrl+Shift+V 누르기
    • 클립보드의 현재 콘텐츠를 서식 없는 텍스트로 붙여넣습니다.
  • 텍스트 입력란의 콘텐츠를 선택한 다음 Ctrl+X 또는 Shift+Delete 누르기
    • 콘텐츠를 삭제하여 클립보드로 복사합니다.

Useful Links

JSON은 무엇인가?

$
0
0

JSON은 무엇인가?
  1. JSON은 무엇인가?
    • 경량의 데이타 교환 포맷이다.
      > XML과 비교한다.
    • 간단한 포맷
      > 사람들을 위해 읽고 쓰기가 쉽다.
      > 기계들을 위해 분석과 생성이 쉽다.
    • JSON은 텍스트 포맷이다.
      > 언어에 독립적으로 프로그래밍된다.
      > 프로그래머들에게 잘 알려진 C,C++,C#,Java,JavaScript,Perl,Pyton을 포함하는 C와 유사한 언어로 모여서 사용된다.
  2. XML을 넘어 왜 JSON인가?
    • on-the-wire(선을 통한) 데이타 포맷인 XML보다 가볍고 빠르다.
    • JSON 오브젝트는 XML 데이타가 타입이 없는데 비해 타입을 가진다.
      > JSON types : string, number, array, boolean
      > XML 데이타는 모두 String 이다.
    • JavaScript 코드를 위해 Native 코드포맷이다.
      > Data는 사용자의 JavaScript코드 안에서 JSON 객체에 접근이 쉽다.
      XML 데이타가 해석과 장황한 DOM API를 통해 변수에 접근하는 것을 필요로 하는데 비해 
      > 회수한 값들은 사용자의 자바스크립트 안의 객체속성에서 읽기가 쉽다.
  3. JSON은 어디에서 사용되는가?
    • 구성정보를 나타낸다.
    • 통신 프로토콜을 실행한다.

JSON Object

  1. JSON 구조
    • name/value 쌍으로 구성된다.
      > 여러가지의 언어들에서 object, record, struct, dictionary, hashtable, 키를 가지는 리스트, 배열집합 처럼 얻어진다.
    • 값들이 리스트는 순서가 있다.
      > 대부분의 언어들에서 array, vector, list, sequence 처럼 얻어진다.
    • JSON은 대부분의 지금의 언어를 통해 일반적인 데이타구조들이 지원된다.
  2. JSON Object 표기법
    • JSON Object는 name/value 쌍의 set은 순서가 없다.
    • JSON Object는 { 로 시작하고 } 로 끝난다.
    • 각각의 이름은 : 와 ,로 구분된 name/value 쌍의 형식을 따른다.
  3. JSON과 JavaScript
    • JSON은 JavaScript의 객체 문자 표기의 부분집합이다.
      > JSON은 JavaScript안에서 혼란스럽거나 야단스럽지 않게 사용될 수 있다.
  4. JSON Object 예제
     
    var myJSONObject = {"bindings": [
        {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"},
        {"ircEvent": "PRIVMSG", "method": "deleteURI", "regex": "^delete.*"},
        {"ircEvent": "PRIVMSG", "method": "randomURI", "regex": "^random.*"}
      ]
    };
    
    • 위의 예에서, JSON JavaScript 객체는 세개의 객체를 포함한 배열을 갖고있는, 각각은 "ircEvent","method","regex"멤버들을 포함한 하나의 멤버 "bindings"를 포함하여 생성된다.
    • 멤버들은 점(.) 이나 그아래 지시자들로 회수 할수 있다.
       
      myJSONObject.bindings[0].method // "newURI"
  5. JavaScript 코드안에서 Text를 Object로 변환하기
     
    var myObject = eval('(' + myJSONtext + ')');
    
    • eval() 함수를 사용하여, JSON text를 JSON 객체로 변환한다.
      > eval()은 JavaScript 컴파일러에서 실행한다.
      > JSON은 JavaScript의 서브셋으로 적합하다. 컴파일러는 text를 정확하게 변환하고, 객체 구조를 만든다.
  6. 보안 & JSON Parser
     
    // Include http://www.json.org/json.js
    var myObject = myJSONtext.parseJSON();
    
    • eval()은 컴파일 할 수 있고, 어떤 JavaScript 프로그램에서도 실행된다. 그래서 보안 이슈들(cross-site scripting)을 가질 수 있다.
      > 소스를 신뢰할 수 있을때, eval()을 사용해라.
    • 보안이 염려될 때 - 소스를 신뢰할 수 없을때 - JSON parser를 사용하는게 낫다.
      > JSON parser는 JSON text를 승인할 수 있다. 그래서 좀더 안전하다.
  7. Object를 Text로 변환하기
     
    var myJSONText = myObject.toJSONString();
    
    • 사용자는 JSON 객체를 JSON text로 변환할 수 있다.
    • JSON은 주기적 데이타 구조를 지원하지 않는다.

      > Do not give cyclical structures to the JSON stringifier
      > 주기적 구조들을 JSON stringfier로 줄수 없다

Java 안에서의 JSON

  1. 자바 개발자를 위한 JSON Tools
    • Parser
      > JSON text 파일들을 해석하고, 그들을 자바 모델로 변환한다.
    • Renderer
      > 자바를 text로 표현하게 한다.
    • Serializer
      > 알기쉬운 POJO clusters를 JSON 표현으로 나열한다.
    • Validator
      > JSON 스키마를 사용하여 JSON 파일의 내용을 유효한지 체크한다.
  2. JSONObject 자바 클래스
    • JSONObject의 name/value 쌍의 집합은 순서가 없다.
    • put 메소드는 객체로 name/value쌍을 add 한다.
    • text들은 JSON syntax rules을 정확히 따른 toString 메소드에 의해 만들어진다.
       
      myString = new JSONObject().put("JSON", "Hello, World!").toString();
      // myString is {"JSON": "Hello, World"}
      

클라이언트와 서버사이드 양쪽에서 JSON 데이타를 주고 받는 방법

  1. 서버사이드에서 JSON 데이타를 생성하고 보내는 방법
    • JSONObject 자바 객체를 생성한다.
    • put 메소드를 사용하여 name/value 쌍을 add한다.
    • toString 메소드를 사용하여 String 타입으로 변환한다.
      그리고 "text/xml"또는 "text/plain"처럼 content-type과 함께 클라이언트로 보낸다.
       
      myString = new JSONObject().put("JSON",toString();
      // myString is {"JSON": "Hello, World"}
      
  2. 클라이언트 사이드에서 JSON 데이타를 받는 방법
    • JSON 데이타는 String 처럼 반환된다.
    • JavaScript 코드안에서 JSON 객체를 만들수 있게 eval()을 호출한다.
      > var JSONdata = eval(req.response.Text);
    • 사용자는 한번 JSON 객체를 가질수 있고, 객체의 속성들에 접근하기 위해 . 을 사용할 수 있다.
       
      var name = JSONdata.name;
      var address = JSONdata.addresses[3];
      var streetname = JSONdata.addresses[3].street;
      
    • 클라이언트 사이드에서 JSON 데이타를 생성하고 보내는 방법
    • JSON 자바스크립트 객체를 생성한다.
    • XMLHttpRequest객체의 open 메소드 안에 "POST" HTTO 메소드를 사용한다.
    • XMLHttpRequest객체의 send 메소드안에서 JSON 자바스크립트 객체를 패스한다.
       
      var carAsJSON = JSON.stringify(car);
      var url = "JSONExample?timeStamp=" + new Date().getTime();
      createXMLHttpRequest();
      xmlHttp.open("POST", url, true);
      xmlHttp.onreadystatechange = handleStateChange;
      xmlHttp.setRequestHeader("Content-Type",
      "application/x-www-form-urlencoded");
      xmlHttp.send(carAsJSON);
      
  3. 서버사이드에서 JSON 데이타를 받는 방법
    • String 타입처럼 JSON데이타를 읽는다.
    • string으로부터 JSONObject 자바객체를 생성한다.
       
      String json = readJSONStringFromRequestBody(request);
      //Use the JSON-Java binding library to create a JSON object in Java
      JSONObject jsonObject = null;
      try {
      jsonObject = new JSONObject(json);
      }
      catch(ParseException pe) {
      }
      

리소스들

  1. JSON 리소스들
    • Introducing JSON
    http://www.json.org/
    • JSON in JavaScript
    http://www.json.org/js.html
    • JSON in Java
    http://www.json.org/java/index.html

참고문헌

Viewing all 30 articles
Browse latest View live