----- 실행 -----

Ctrl + F11 : 바로 전에 실행했던 클래스 실행

 

----- 소스 네비게이션 -----

Ctrl + 마우스커서(혹은 F3) : 클래스나 메소드 혹은 멤버를 상세하게 검색하고자 할때

Alt + LeftAlt + Right : 이후이전

Ctrl + O : 해당 소스의 메소드 리스트를 확인하려 할때

F4 : 클래스명을 선택하고 누르면 해당 클래스의 Hierarchy 를 볼 수 있다.


Alt + <-(->) : 이전(다음) 작업 화면

 

----- 문자열 찾기 -----

Ctrl + K : 찾고자 하는 문자열을 블럭으로 설정한 후 키를 누른다.

Ctrl + Shift + K : 역으로 찾고자 하는 문자열을 찾아감.

Ctrl + J : 입력하면서 찾을 수 있음.

Ctrl + Shift + J : 입력하면서 거꾸로 찾아갈 수 있음.

Ctrl + F : 기본적으로 찾기

 

----- 소스 편집 -----

Ctrl + Space : 입력 보조장치(Content Assistance) 강제 호출 => 입력하는 도중엔 언제라도 강제 호출 가능하다.

F2 : 컴파일 에러의 빨간줄에 커서를 갖져다가 이 키를 누르면 에러의 원인에 대한 힌트를 제공한다.

Ctrl + L : 원하는 소스 라인으로 이동

   로컬 히스토리 기능을 이용하면 이전에 편집했던 내용으로 변환이 가능하다.

Ctrl + Shift + Space : 메소드의 가로안에 커서를 놓고 이 키를 누르면 파라미터 타입 힌트를 볼 수 있다.

Ctrl + D : 한줄 삭제

Ctrl + W : 파일 닫기

Ctrl + I : 들여쓰기 자동 수정

Ctrl + Shift + / : 블록 주석(/* */)

Ctrl + Shift + \ : 블록 주석 제거

Ctrl + / : 여러줄이 한꺼번에 주석처리됨주석 해제하려면 반대로 하면 된다.

Alt + Up(Down) : 위(아래)줄과 바꾸기

Alt + Shift + 방향키 : 블록 선택하기

Ctrl + Shift + Space : 메소드의 파라메터 목록 보기

Ctrl + Shift + O : 자동으로 import 하기

Ctrl + Shift + F4 : 열린 파일 모두 닫기

Ctrl + M : 전체화면 토글

Ctrl + Alt + Up(Down) : 한줄(블럭복사

Ctrl + , or . : 다음 annotation(에러워닝북마크 가능)으로 점프

Ctrl + 1 : 퀵 픽스

F3 : 선언된 변수로 이동, 메소드 정의부로 이동

Ctrl + T : 하이어라키 �b업 창 띄우기(인터페이스 구현 클래스간 이동시 편리)

Ctrl + O : 메소드나 필드 이동하기

Ctrl + F6 : 창간 전환, UltraEdit  Editplus  Ctrl + Tab 과 같은 기능

 

----- 템플릿 사용 -----

sysout 입력한 후 Ctrl + Space 하면 System.out.println(); 으로 바뀐다.

try 입력한 후 Ctrl + Space 하면 try-catch 문이 완성된다.

for 입력한 후 Ctrl + Space 하면 여러가지 for 문을 완성할 수 있다.

템플릿을 수정하거나 추가하려면 환경설정/자바/편집기/템플릿 에서 할 수 있다.

 

----- 메소드 쉽게 생성하기 -----

클래스의 멤버를 일단 먼저 생성한다.

override 메소드를 구현하려면, 소스->메소드대체/구현 에서 해당 메소드를 체크한다.

기타 클래스의 멤버가 클래스의 오브젝트라면, 소스->위임메소드 생성에서 메소드를 선택한다.

 

----- organize import -----

자바파일을 여러개 선택한 후 소스->가져오기 체계화 해주면 모두 적용된다.

 

----- 소스 코드 형식 및 공통 주석 설정 -----

환경설정 -> 자바 -> 코드 스타일 -> 코드 포멧터 -> 가져오기 -> 프로파일.xml 을 불러다가 쓰면 된다.

또한 다수의 자바파일에 프로파일을 적용하려면 패키지 탐색기에서 패키지를 선택한 후 소스 -> 형식화를 선택하면 된다.

환경설정 -> 자바 -> 코드 스타일 -> 코드 템플리트 -> 가져오기 -> 템플리트.xml 을 불러다가 쓰면 된다.

 

----- 에디터 변환 -----

에디터가 여러 파일을 열어서 작업중일때 Ctrl + F6 키를 누르면 여러파일명이 나오고 F6키를 계속 누르면 아래로

Ctrl + Shift + F6 키를 누르면 위로 커서가 움직인다.

Ctrl + F7 : 뷰간 전환

Ctrl + F8 : 퍼스펙티브간 전환

F12 : 에디터로 포커스 위치

 

 

 

 

 

이클립스 자주쓰는 단축키 -

 

Ctrl + / : 주석 처리 - 한 라인/블록에 대해 주석 처리 (추가 및 제거)

Ctrl + L : 특정 라인으로 이동

Ctrl + F6 : Editor 창간의 이동

Ctrl + F7 : View 이동 메뉴

Ctrl + F8 : Prespectives 이동 메뉴

Ctrl + D : 한라인 삭제 - 커서가 위치한 라인 전체를 삭제 한다.

Ctrl + J : Incremental find 이클립스 하단 상태 표시줄에 Incremental find 라고 표시되어 한 글자자씩 누를 때 마다 코드내의 일치하는 문자열로 이동 , 다시 Ctrl + J 를 누르면 그 문자열과 일치 하는 부분을 위/아래 방향키로 탐색이 가능하다.

Ctrl + N : 새로운 파일 / 프로젝트 생성

Ctrl + 1 (빠른교정) - 문 맥에 맞게 소스 교정을 도와 준다변수를 선언하지 않고 썼을경우 빨간색 에러 표시되는데 이 단축키를 적용하면 변수에 맞는 선언이 추가 되도록 메뉴가 나타난다.

Ctrl + 0 : 클래스 구조를 트리로 보기

Ctrl + Space :  Cotent Assist - 소스 구문에서 사용 가능한 메소드멤버들의 리스트 메뉴를 보여준다.

Ctrl + PageUp , Ctrl + PageDown : Edit 창 좌우 이동 - Edit 창이 여러개 띄워져 있을경우 Edit 창간의 이동 한다.

Ctrl + Shift + Down : 클래스 내에서 다음 멤버로 이동

Ctrl + Shift + M : 해당 객체의 Import 문을 자동 생성 - import 추가 할 객체에 커서를 위치 시키고 단축키를 누르면 자동적으로 import 문이 생성

Ctrl + Shift + O : import 문을 자동 생성 - 전체 소스 구문에서 import 안된 클래스의 import 문을 생성해 준다.

Ctrl + Shift + G : 해당 메서드 / 필드를 쓰이는 곳을 표시 - View 영역에 Search 탭에 해당 메서드 / 필드를 사용하는 클래스를 표시 해준다.

Alt + Shift + R : Refactoring (이름변경) - Refactoing 으로 전체 소스에서 이름변경에 의한 참조 정보를 변경해 준다.

F3 선언 위치로 이동

F11 : 디버깅 시작

F8 : 디버깅 계속

F6 : 디버깅 한줄씩 실행(step over)

F5 : 디버깅 한줄씩 실행 함수 내부로 들어감 (step into)

F12 : Editor 창으로 이동 (Debugging 등 자동적으로 포커스가 이동 됐을경우 편리)

Alt + Up , Alt + Down : 줄 바꿈 - 해당 라인을 위 / 아래로 이동 시킨다.

Alt + Shift + S : Source Menu - 소스메뉴 (Import 추가 , Comment 추가 , 각종 Generator 메뉴가 나타난다.

Alt + Shift + Up : 블록설정 - 소스 코드를 블록 단위로 설정해 준다.

Alt + Shift + Down : 블록해제 - 소스 코드를 블록 단위로 해제한다.

Alt + Shift + J : 주석 생성 - 해당 메서드/클래스에 대한 주석을 템플릿을 생성해 준다.

sysout + (Ctrl + Space) : System.out.println() 문장 삽입 - 코드 템플릿을 이용해서 소스 구문을 추가

(Windows -> Preferences -> JAVA -> Editor -> Templates 에서 자주 쓰는 소스 구문을 추가시키면 <템플릿 이름> + (Ctrl + Space) 로 소스 문장을 완성 시킬 수 있다.)

Alt + Shift + Z : Surround With 메뉴 - try / catch 문이나 for , do , while 등을 해당 블록에 감싸주는 메뉴가 나타난다.

Ctrl + Shift + F : 코드 포맷팅 - 코드 내용을 문법 템플릿에 맞게 포맷팅(들여쓰기해준다.

Ctrl + Alt + Down한줄 복사후 아래에 복사 넣기 - Copy&Paste 대체하는 단축키커서가 위치한 라인을 복사해 밑줄에 생성해 준다.

Ctrl + Shift +X : 대문자로 변환

Ctrl + Shift + Y : 소문자로 변환

Ctrl + Shift + L : 모든 단축키의 내용을 표시해준다.

Ctrl + Shift + B : 현재 커서 라인에 Break point 설정

Ctrl + Shift + T : 클래스 찾기


Posted by JJOREG

 

SQL소개

 

STRUCTURED QUERY LANGUAGE의 머리글자를 딴 말이며 SQL그대로 읽는다. 아주 가끔 SEQUEL(씨퀄)이라고 잘못 읽는 사람이 있는데, 씨퀄은 옛날 이름이다. 에스 큐 엘로 읽으면 된다. SQL의 뜻은 구조화된 질의어이다. SQL에 구조화는 크게 중요하지 않은데도, SQL 이름에는 그대로 남아있다.

현재 SQL은 관계형 데이터베이스의 질의어로는 제1의 자리를 굳혀서 아마 관계형 데이터베이스를 쓸경우 90%이상 SQL을 쓰게 될것이다. 앞에서 관계대수에 대해서 배웠는데 실제 데이터베이스 시스템은 관계 대수 연산만으로는 자료를 처리하지 못한다. 관계 대수 연산은 자료를 고치는 명령(INSERT/DELETE/UPDATE)은 없이, 그냥 들어있는 자료를 가져오기만 하는 질의어(QUERY LANGUAGE)이고, 또한 스키마를 정의하는 명령은 존재하지 않는다.

SQL은 그런 모자라는 부분을 보안하여 실제 데이터베이스에서 사용이 가능하게 만들어진 언어이다.

SQL은 말 그대로 데이터베이스의 표준어 같은 느낌이지만 개발되는 프로그램에 따라서 SQL을 일부만 지원하거나 혹은 거대한 데이터베이스 관리 프로그램이라면 오히려 그 이상의 확장된 기능까지 지원하는 경우도 있다.

 

국제표준 SQL

SQL 1970년대에 처음 구현되기 시작하여 그 뒤 많은 변화가 있었다. 현재 SQL은 국제 표준화 기구(ISO: International Organization for Standardization)에서 표준을 만든다고 한다.

당연히 표준이 만들어 질 때마다 버전처럼 번호를 정하는데 국내 기준은 KS X 2017이라고 한다.

 

SQL에 들어가 있는 기본 기능들을 살펴보자면.

1 스키마를 정의하는 자료 정의어 (DDL: data definition language)

2 질의어 또는 자료 조작어 (DML: data manipulation language)

그런데 여기에서 질의어는 2가지 종류로 나뉘게 된다.

 

2-1. 상호 작용적(interactive) 자료 조작어 : 화변에서 명령을 넣고, 결과가 바로 화면으로 나오는 방식인데 이 방식은 거의 늘 지원된다. 보기를 들어, Oracle 경우에는 이를 SQL*Plus 라고 부른다. 학생들이 실습하기에 좋은 환경이다.

2-2. 내포된 (embedded) 자료 조작어 : 일반 고급 프로그래밍 언어(보기: C/C++, PL/I, Cobol, Pascal)로 싼 프로그램 안에 SQL 명령을 사이 사이 에 끼워 넣은 방식. 작은 데이터베이스 관리 시스댐에서는 이를 지원하지 않는다. 은행 업무, 철도/비행기 예약 업무등과 같이 늘 되풀이되는 실제의 업무 전산화에서는 이런 방식을 아주 많이 쓴다

 

3. 트레젝션 제어(transaction control)

4. 이외 뷰 정의, 무결성 제어, 권한 주기 등

 

자료의 형(domain, type)

 

Select, insert, delete, update등은 데이터 베이스의 자료를 다루는 DML명령들이다. 그런데 이러한 자료를 테이블에 담으려면 테이블의 속성에 대한 자료의 형 (domain = 범위)를 포함하여 스키마를 정의하는 DDL을 먼저 배워야 된다.

자료형이란 고급 프로그래밍 언어에서 사용하는 int char double같은 타입과 비슷하다. SQL을 사용하면서도 이를 모르면 안되는 것이다.

그럼 많이 사용하는 자료형에 대해서 알아보자.

 

Char(n) : fixed – length character string으로 저장하며, 이때 n은 기억 장소의 크기를 의미한다. 필요한 때에는 마지만에 빈칸을 (‘’, 0x20)을 덧붙인다. 보기를 보자면 char(3) ab를 저장하면 ‘ab’가 메모리에 저장되는게 아니라 ‘ab ‘가 저장되는 것이다. 실제 char 배열에서도 최종에 null을 넣어주는 것과 동일하다.

Varchar2(n) = variable – length character string 으로 저장하며, 이때 n은 최대 길이지만, 그보다 짧은 문자열이 들어오면 마지막에 빈칸을 덧붙이지 않고 짧은 문자열 그대로 저장한다. 오라클의 경우 Varchar Varchar2가 동일하게 작동하지만 Varchar2를 사용할 것을 권장한다.

Int, smallint : int는 보통 정수이고 smallint int보다 바이트수가 적은 정수형이다.

Numeric(p, d), number(p, d), decimal(p, d), dec(p, d) 십진 수를 정확하게 저장할 수 있는 자료형이다. P는 전체 자리수, d는 그 가운데 소수점 아래의 자리수를 의미한다. 보기를 들어 Numeric(3, 2)라고 한다면 1.23 식으로 정수 1개 소수점 2자리를 표시할 수 있다.

Real, double, float(p) : 실수형이다. Real은 보통의 실수이고 double real보다 바이트수가 많은 실수형이다. Float(n) n자리까지 실수를 저장한다.

 

실수 형 보충설명

컴퓨터 안에서 실수는 IEEE 754 표준에 따라서 보통 2진법으로 저장하는데 십진법으로 정확하게 나타낼 수 있는 값이 2진법으로는 나타낼 수 없는 경우가 있다. 10진법으로 0.1 2진법으로는 정확하게 나타낼 수 없다. 물론 오차가 아주 작아서 상관없는 경우가 있지만 만약 정확하게 나타내야 한다면 Numeric같은 형을 사용해야 한다.

 

DATE : 날짜를 나타내는 자료형

TIME : 시간을 나타내는 자료형

 

여기에 자료형또한 데이터베이스 시스템마다 새롭게 정의할 수 있으니 그때 그때 맞춰서 잘 사용해야 한다.

 

CREATE TABLE 명령을 사용하여 스키마 정의하기

 

스키마를 정의하는 명령은 create table 이고, 스키마를 지우는 명령은 drop table이다.

 

create table 테이블-이름 (

속성_이름1 자료-1, 속성 _이름2 자료-2, . … ,

primary key (속성 11 , 속성 12 , ... ),

unique key (속성 21 , 속성 22 , ... ),

foreÎgn key (속성 31 , 속성 32 , ... ) references 테이블_이름2

);

 

drop table 테이블-이름 ;

 

 

여기에서 주의할 점은 primary key(일차 키)절이 나오면 그 키 값이 꼭 같은 투플은 그 테이블 안에 두개 이상 있을 수 없다. 일차 키는 하나 또는 여러 개의 속성으로 이루어지는데, 만약 유저 항목에 아이디가 일차 키라면 그 테이블 안의 모든 투플들은 아이디가 달라야 한다.

또한 어떤 테이블에 unique key(유일한 키)절이 나오면 그 키 값이 꼭 같은 투플이 그 테이블 안에 두개 이상 있을 수 없다. 어떤 테이블에서 후보키가 2개 있을 때 일차키가 되지 못한 키를 unique key로 지정하면 된다.

속성에 대한 자료형을 지정한 뒤 그 뒤에 ‘not null’이라고 지정할 수 있는 not null이라면 그 속성에 대한 값으로 null을 허용하지 않는다는 말이다.

** 여기서 주의할 점은 어떤 테이블의 primary key에 속하는 모든 속성은 not null로 선언하지 않아도 null값은 허용하지 않는다. 그 밖의 경우에는 not null로 선언하지 않는다면 null값을 사용할 수 있으며 unique key foreign key의 일부로 지정된 속성의 값도(생각해보면 알겠지만 당연히 바람직하지 않다.)

 

create table 학생

 

(학번 char(7) not null ,

이름 char(20) not null ,

주번 char(14) not null ,

primary key (학번),

unique key (주번)

);

 

여기에서 (학번 char(7), 으로만 선언해도 primary key (학번), 라고 선언했으므로 학번은 자동으로 not null이다.

 

다음은 foreign Key(외래키) 가 들어간 내용을 살펴보자.

 

create table 수강

(확번 char(7) not null,

과목번호 char(7) not null ,

primary key (학번, 과목번호) ,

foreign key (학번) references 학생,

foreign key (과목번호) references 과목

);

 

foreign key 라고 선언된 것은 다른 스키마에서 키로 사용되고 있는 외래키라는 선언이며 references는 가져온 스키마의 명칭을 적는다.

 

테이블에 투플 넣기

 

create table 유저

(아이디 char(7) not null ,

패스워드 char(20) not null ,

);

 

ínsert ínto 유저 values (’전사전사’, ‘1258’);

 

insert 명령의 values 절에 속성 값을 넣게 되는데 테이블을 만들 때의 속성 순서대로 값을 넣을 때는 위와 같이 사용하지만 순서와 상관없이 하는 건 후에 배우겠다.

 

테이블 복사하기

이미 있는 테이블과 스키마도 똑같고 투플의 내용도 같은 테이블을 만드는 방법을 알아보자. 참고로 이 문법은 oracle에서 사용한 것이며 다른 DBMS에서는 지원하지 않을 수도 있다.

Create table copytable as select * from 유저; (기존 테이블을 복사해서 몇가지 기능을 실험해보고 싶을 때 유용할 것이다.)

여기에 추가로 조건을 줘서 사용하고 싶다면

Create table copytable as select 아이디 from 유저 where 패스워드 = ‘11111111’

식으로 사용할 수 있겠다.

 

Select – from – where 실행원리

 

엄밀한 뜻에서 자료를 가져오는 명령은 select이다. Select 명령에는 여러가지 절이 들어 갈수 있지만 가장 중요한 절은 from절과 where절이며 select 명령 형식은 다음과 같다.

Select 속성1, 속성2, …

From 테이블1, 테이블2, …

Where 조건1, AND/OR 조건2 …

 

SELECT 명령에서 From 절은 반드시 있어야 한다. Where 절은 보통 있지만 반드시 있어야 하는 것은 아니다.

 

명령의 단계별로 본다면 다음과 같이 해석할 수 있다.

 

유저

아이디

패스워드

캐릭터

법사법사

1234568

전사

법사법사

1234568

도적

전사전사

856412

마법사

전사전사

856412

전사

도둑도둑

987523

궁수

 

 

 

 

 

 

 

 

 

 

 

 

다음과 같은 테이블이 있다고 쳤을시.

Select 아이디

Form 유저

 

아이디

법사법사

법사법사

전사전사

전사전사

도둑도둑

 

 

 

 

 

 

 

 

 

 

다음과 같은 결과가 나오게 된다. 이것이

Select 아이디, 패스워드, 캐릭터

Form 유저라면

  

아이디

패스워드

캐릭터

법사법사

1234568

전사

법사법사

1234568

도적

전사전사

856412

마법사

전사전사

856412

전사

도둑도둑

987523

궁수

 

 





 

 

 

와 같을 것이다. 여기에

 

Select 아이디, 패스워드, 캐릭터

Form 유저

Where 아이디 = 법사법사

라면

 

아이디

패스워드

캐릭터

법사법사

1234568

전사

법사법사

1234568

도적

 

 

 

 

 

 

다음과 같을 것이다.

 

관계대수 연산으로 보자면

 

Π 아이디, 패스워드, 캐릭터아이디 = 법사법사 (유저) );

 

결론적으로 위의 select의 기본형은 다음과 같다.

Π 속성1 , 속성2 , ... (σ 조건 1 and/or, 조건 2, … (테이블1 X 테이블2 ...) )

 

가 된다.

여기에서 테이블1 x 테이블2 라는 내용을 보자면

유저 이외에 Temp라는 테이블도 넣는경우

 

Select 아이디, 패스워드, 캐릭터

Form 유저, Temp

Where 아이디 = 법사법사

 

Π 아이디, 패스워드, 캐릭터아이디 = 법사법사 (유저xTemp) );

라는 구문으로 해석할 수 있다는 뜻이 된다.

 

이제 단계별로 요약해보자.

 

1. From 절에는, select 명령에서 쓰고자 하는 테이블 이름이 나오는데, 테이블(엄밀하게 말하면 투플 변수 이름)이 둘 이상 있을 때 개념적으로모든 테이블(투플변수가 가리키는 테이블)의 카티전 곱을 한 결과 테이블을 다음 단계로 넘긴다. 만일 from 절에도 테이블 이름이 하나만 나오면 카티전 곱을 하지 않고 그냥 테이블을 넘긴다(할 수도 없다.).

 

2. where 절에는 조건이 나오는데, 관계대수(σ)의 선택연산을 한다. 조건이 여러 개 있으면, 원하는 바에 따라 and or을 붙이면 된다. Where 절은 반드시 있어야 하는 것은 아니지만 , 실제로는 거의 모든 select 명령에는 where절이 있다.

3. select명령 바로 뒤에 나오는 속성1, 속성2, … ”은 관계대수의 속성추출(Π) 연산을 하며 최종적으로 나온 테이블에서 필요한 속성만 빼내는 것이 명령의 최종 결과이다.

 

하지만 이에 대한 DBMS의 구현은 각기 다르며 실제 카티전 곱을 실행하는 경우 등은 없다. 이유는 실제 만들어진 DBMS마다 연산 최적화를 거칠 수 도 있으며 결과적으로 나오는 테이블이 중요할 것이지 내부연산의 결과는 크게 중요하지 않을 수 있다.

 

Select로 속성 추출

 

결국 select명령이란 데이터를 뽑아오는 것이다. 그리고 현재까지는 들어온 예로는 결과적으로 최종 테이블에는 겹치는 투플이 존재하지 않았다.

하지만 select명령의 결과에 겹치는 결과가 나오지 않거나 데이터테이블에 완벽히 겹치지 않는 투플만 존재하게 할 수 있을까?

그럴 수는 없다. 이유는 생각해보면 간단하다 결국 select insert update명령을 생각해보면 한번한번의 연산 추출한번할 때마다 한투플 한투플이 겹치는지 겹치지 않는지 연산해야 할 것이다. 이는 성능에 심각한 저하를 줄 수 있다.

그래서 나온 타협안이 다음과 같다.

1. Insert/update 명령의 결과로 표안에 겹치는 투플이 생기는 것은 허용한다.

2. select 명령의 경우

Select (또는 select all)의 경우 결과 테이블에 겹치는 투플을 허용한다.

Select distinct의 경우 결과 테이블에 겹치는 투플을 허용하지 않는다.

select 명령을 실행할 때

 

Select : 겹치는 투플 허용

Select all : 겹치는 투플 허용

Select distinct : 겹치는 투플 허용하지 않음

 

등으로 이는 선택한 속성의 수가 몇 개가 되든 문제 없다.

 

Where로 조건 나타내기

 

Where로 저건을 나타내는 것은 일반 조건문과 비슷하다.

Where 유저 = ㅋㅋㅋ

Where 공격력 > 2000

 

자연조인 나타내기

 

관계대수에서 자연조인을 where문으로 나타낼 수 있다. SQL에서 자연조인을 어떻게 나타내는지 보자.

유저 = (아이디, 패스워드)

캐릭터 = (아이디, 공격력, 방어력, 직업)

 

자연조인 단계를 생각하면서 확인해보자.

 

1. 학생과 수강 테이블의 카티전 곱 = FROM 유저, 캐릭터

2. 유저 아이디와 캐릭터 아이디가 같은 투플 선택 = where 유저.아이디 = 캐릭터.아이디

3. 두 테이블에서 공통 속성은 한번만 출력 = select 유저.아이디, 유저.패스워드, 캐릭터.공격력, 캐릭터.방어력, 캐릭터.직업

 

묶어서 보자.

 

Select 유저.아이디, 유저.패스워드, 캐릭터.공격력, 캐릭터.방어력, 캐릭터.직업

From 유저, 캐릭터

where 유저.아이디 = 캐릭터.아이디

 

select 다음에 속성을 다음과 같이 나타내도 꼭 같다.

 

select, 유저.* 캐릭터.공격력, 캐릭터.방어력, 캐릭터.직업

from 유저, 캐릭터

where 유저.아이디 = 캐릭터.아이디 ;

 

** 이때 캐릭터.공격력, 캐릭터.방어력, 캐릭터.직업 과 같은 구문은 다른 테이블과 겹치지 않으므로 캐릭터라는 항목을 빼도 되겠지만 어떤 데이터베이스 시스템이냐에 따라서 다를 수 있다.

 

속성의 이름을 정하거나 바꾸거나(renaming attributes [as])

 

속성에 이름이 없을 때 새 이름을 주거나 이미 이름이 있는데 다른 이름을 붙이려면 as를 쓰고 새 이름을 적어야 한다.

그럼 어떤 경우에 쓸까?

 

1. 다른 테이블 2개에 같은 이름의 속성이 하나씩 있을 때.

 

유저.아이디, 캐릭터.아이디 같은 경우가 다음과 같다. MMORPG같은 경우 캐릭터는 누가 소유하고 있는지 분명히 해야 하는데 같은 이름의 아이디라는 항목이 2개 있으면 분명 햇갈릴 수가 있다.

이런 경우 다음과 같이 as문을 이용할 수 있다.

 

Select 유저.아이디 as 유저_아이디, 캐릭터.아이디 as 보유유저아이디

From 유저, 캐릭터

where 유저.아이디 = 캐릭터.아이디

 

2. select 다음에 속성대신 수식이 올 때.

 

캐릭터 = (보유아이디, 공격력, 방어력)

 

Select 보유아이디, 공격력 * 10

From 캐릭터;

 

이럴 때 공격력 * 10이라고 하면 내용을 찍기는 하겠지만 이름이 없을 것이므로

 

Select 보유아이디, 공격력 * 10 as 밸런스조정공격력

From 캐릭터;

 

등으로 표현할 수가 있다.

이 내용들은 후에 배울 집계(aggregate)항목에서 같이 적용된다.

 

3. 이미 있는 속성이름과 다른 속성이름을 주려고 할 때.

 

Select 공격력

From 캐릭터;

 

현재 시간당 공격력의 의미로도 쓰이기 때문에 Dps이라는 이름을 주고 싶으면

 

Select 공격력 as Dps

From 캐릭터;

 

식으로 주면 된다.

 

테이블을 가리키는 투플변수

 

이제까지 테이블과 투플변수의 관계에 대해서 살펴보지 못했는데 이 기회에 알아보도록 하자.

 

Select 유저.아이디 as 유저_아이디, 캐릭터.아이디 as 보유유저아이디

From 유저, 캐릭터

where 유저.아이디 = 캐릭터.아이디

 

와 같은 경우를 봤을 때 유지.아이디가 당연하게 느껴질 수도 있다. 하지만 실제로 저런 식으로 사용하는 건 앞장에서 투플변수에 대해서 설명할 때 사용했던 문법이다. 우리는 투플 변수를 선언한적도 없는데 어떻게 저런 문법이 가능할까?

이에 대한 설명으로는 마치 C++의 디폴트 생성자처럼 어디선가 우리가 선언도 하지 않았는데 무시적으로 투플변수를 만들어 낸다. 그리고 묵시적으로 만들어내는 투플변수는 테이블 명과 동일하게 만들어진다. 라는 생각을 해볼 수 있다.

 

Select 유저.아이디 as 유저_아이디, 캐릭터.아이디 as 보유유저아이디

From 유저, 캐릭터

where 유저.아이디 = 캐릭터.아이디

우리가 실제로 본 이 위와 같은 명령중 From에서는 무시적으로 다음과 같이 처리하고 있다.

 

Select 유저.아이디 as 유저_아이디, 캐릭터.아이디 as 보유유저아이디

From 유저(테이블명) 유저(투플변수), 캐릭터(테이블명) 캐릭터(투플변수)

where 유저.아이디 = 캐릭터.아이디

 

즉 다음과 같이 바꾼다면 select에서도 변경해줘야 한다는 것.

 

Select Var유저.아이디, Var캐릭터.아이디 as 보유유저아이디

From 유저 Var유저, 캐릭터 Var캐릭터

where 유저.아이디 = 캐릭터.아이디

 

또한 as 명령은 사실 있어도 되고 없어도 된다. 위의 명령은 아래의 명령과 동일하게 작동한다.

 

Select Var유저.아이디, Var캐릭터.아이디 as 보유유저아이디

From 유저 as Var유저, 캐릭터 as Var캐릭터

where 유저.아이디 = 캐릭터.아이디

 

어떤 DBMS시스템은 as명령을 지원 안하기도 한다. 오라클이 대표적이다.

 

같은 테이블에 대하여 둘이상의 투플변수를 정의하는 경우.

  

캐릭터

아이디

공격력

방어력

법사법사

10

10

마수마수

20

20

전사전사

30

30

궁수궁수

40

40

도둑도둑

50

50

 

 

 

 

 

 

 

 

 

 

  

여태껏 from명령에서는 일반적으로 2개의 테이블을 사용했다. 그런데 하나의 테이블에서 어떤 유저와 어떤 유저를 비교하려면 어떻게 해야 할까? 답은 의외로 간단하다. 하나의 테이블에 2개의 투플변수를 선언하여 하면 된다.

 

Select T2캐릭터.아이디, T2캐릭터.공격력

From 캐릭터 T1캐릭터, 캐릭터 T2캐릭터

 

여기에 자신 내부에서 특정 투플들을 뽑아내기 위한 좀더 복잡한 조건들을 사용해보자.

 

Select T1캐릭터.아이디, T1캐릭터.공격력

From 캐릭터 T1캐릭터, 캐릭터 T2캐릭터, 캐릭터 T3캐릭터

Where T2캐릭터.아이디 = 마수마수 and T3캐릭터.아이디 = 궁수궁수 and T1캐릭터.공격력 < T2캐릭터.공격력 and T1캐릭터.공격력 > T3캐릭터.공격력

 

이런식으로 사용한다면

 

전사전사

30

30

 

 

투풀만이 뽑혀져 나올 것이다.

 

이를 좀더 생각해보면 테이블이 몇 개이든 상관없이 연산이 가능할 것이다.


문자열(character string) 연산

 

문자열의 패턴을 다루는 특별한 연산이 존재한다. like연산으로 like연산은 where 절 안에서 속성이 어떤 패턴에 맞는지를 확인할 수 있다. 먼저 보기를 하나 살펴보자.

 

Select 아이디

From 유저

Where 이름 like ‘% 전사%’

 

여기에서 %기호는 글자가 0, 1, 2개 등에 해당한다. % 전사%는 글자앞에 글자가 전혀 없어도 좋고, 어떤 한글자가 있어도 좋다는 이야기이다.

다음 문자열들은 % 전사%와 비교했을 때 참이다.

 

전사” “조 전사” “박 전사

전사1” “ 전사2” “ 전사 0”

 

Like 다음 _(underscore)글자가 올 수도 있는데, 이 글자는 어떤 글자이든 딱 한 글자에만 해당한다.

Where 이름 like ‘__전사%’ 이런 조건이라면

 

   = “  전사” “미친전사” “호호전사

거짓 = “   전사” “완미친전사” “호호호호전사

 

두글자면 앞에 허용하는데 3글자가 앞에 오거나 4글자가 오면 당연히 안된다. 말 그대로 글자수를 딱 지키게 하기 위한 조건이다.

일반적으로 고급 프로그래밍 언어에서 “ ”는 한바이트에 해당하지만 NLS_LANG 환경 변수를 KOREAN_KOREA.K016KSC5601로 설정하면 밑줄은 한 글자마디 하나에 해당한다. ‘a’와 한글 는 같게 본다.

마찬가지로 ‘ ’공백과 도 같은 글자 수로 치게 된다.

 

투플 간추리기 (order by)

 

앞에서 보았듯 select 명령의 결과테이블에서 나오는 투플은 데이터베이스 관리 시스템에서 정한 순서대로 나온다. 즉 자신이 원하는 순서 혹은 자신이 원하는 정렬대로 테이블이 출력되도록 하는 명령이라고 보면 된다.

 

Select 아이디

From 유저

Order by 아이디

 

와 같이 사용하면 아이디가 가나다 순으로 정렬되어 나오게 된다. 기본적으로 아무런 명령도 내리지 않은 order by 아이디는 올림차순으로 정렬되게 된다.

당연히 그 반대로 있다.

 

Select 아이디

From 유저

Order by 아이디 asc <- 올림차순 정렬

Order by 아이디 desc <- 내림차순 정렬

 

만약 두가지 속성을 정렬해서 보려고 한다면 어떻게 하면 될까?

 

Select 아이디, 패스워드

From 유저

Order by 아이디, 패스워드;

 

식으로 정렬하면 된다. 혹은 맨 마지막 구문을 다음과 같이 적어도 같은 결과를 낸다.

 

Order by 아이디 asc, 패스워드 asc;

 

만약 아이디는 올림으로 하지만 그 안에서 패스워드는 내림차순으로 하고 싶다면 다음과 같이 명령할 수 있다.

 

Order by 아이디 asc, 패스워드 desc;

 

이때 정렬 원칙은 첫번째 속성을 기준으로 간추리고 그 다음 속성으로 정렬 그 다음 속성으로 정렬하는 방식이다.

 

Posted by JJOREG

관계형 데이터베이스의 구조

 

  관계형 데이터 베이스는 테이블의 집합이며 관계형 데이터 베이스에서는 관계라는 말 자체를 테이블과 동일하게 본다.

  그에 관한 용어를 정리해보겠다.

 

 이 표하나를 통채로 관계(=테이블)이라고 한다.

 하나의 열은 속성이라고 한다.

 속성2

속성

속성

속성

 이 한줄은 속성속성의 데이터가 모여서 이루어진다. 이를 투플이라고 한다.

 

 

 

 

 

 

 

 

 

 

 

 데이터 베이스 공부를 하며 권하는 용어

 수학용어

 일반용어

 테이블 OR 관계

 관계 

 테이블

 투플

 투플(TUPLE)

 가로 행(ROW)

 속성

 속성 

 세로 (COLUMN)

 

 

속성의 도메인(=범위), 투플 변수

 

투플 변수라는 용어가 있는데 이는 어느 시점의 어떤 테이블이 있다고 할 때 그 테이블의 하나의 투플을 가리키는 변수이다.

가리킨다라는 말에서도 알 수 이듯이 C의 포인터와 비슷한 개념이다.

 

아이디

패스워드

캐릭터

법사법사

654321

마법사

전사전사

123456

전사

도둑도둑

123456

도둑

같은 테이블이 있다고 할 때. Temp투플변수 라는 이름의 투플변수를 선언했다면.

 

Temp투플변수 = 어느 시점의 어떤 테이블의 아이디(일차키)가 법사법사인 투플;

 

Char Temp아이디[10] = Temp투플투플.아이디;

 

라고 한다면 Temp아이디에 담겨있는 아이디는 법사법사일 것이고 Temp아이디.패스워드는 654321. Temp아이디.캐릭터는 마법사일 것이다.

이때 관계형 데이터 베이스는 속성이 단순하고 값 또한 하나이다. 이런 경우의 테이블의 스키마를 1NF라고 하는데 제1정규형이라고 부른다. 즉 관계형 데이터베이스는 모두 1NF이다.

 

테이블 스키마와 테이블 인스턴스

 

데이터베이스는 테이블의 집합인데. 테이블을 만들려면 스키마를 먼저 만들고 그 안에 데이터를 입력하여 투플을 넣어야 한다. 즉 스키마는 테이블을 만들기 위한 틀이다.

스키마를 구성하기 위해서는 다음과 같은 내용이 필요하다.

 

1.     그 데이터베이스 안에서 고유한 테이블의 이름.

2.     그 테이블에 들어있는 속성의 이름 목록

3.     각 속성에 대한 도메인(=범위)

 

그러므로 스키마를 생성하는 create table명령은 위의 내용을 모두 포함한다.

 

Create table 유저(테이블의 이름) {아이디(속성) char(10) (도메인), 패스워드(속성) char(10) (도메인), 캐릭터(속성) char(10) (도메인) }

 

식으로 유저라는 테이블의 이름 각 3가지 속성의 속성정의 그리고 각 속성의 도메인을 정한다.

틀이 있으면 안에 내용을 넣고 찍어내면 붕어빵처럼 테이블들이 찍혀 나오는데 이렇게 찍혀 나온 테이블들을 인스턴스라고 한다.

 

데이터 베이스 스키마 데이터 베이스 인스턴스

 

데이터베이스는 하나의 스키마 하나의 인스턴스로 이루어져있지 않다. 데이터베이스는 수많은 스키마와 그 스키마에서 찍혀져 나오는 인스턴스들로 이루어진다. 바로 하나의 데이터베이스를 이루는 모든 스키마를 데이터베이스 스키마라고 하며 찍혀 나온 모든 인스턴스들을 데이터베이스 인스턴스라고 한다.

 

언제나 강조하지만 스키마는 함부로 바뀌지 않는다. 스키마를 하나더 만들고 말지 이미 만들어진 테이블의 스키마를 변경한다는 것은 기존의 인스턴스들을 모두 폐기할 수도 있는 일이다.

 

(Keys)

개체-관리 모델에서 사용했던 수퍼키, 후보키, 일차키, 외래키 개념은 관계형 데이터베이스에서도 다 사용이 가능하다.

후보키(일차키를 포함하여)는 테이블의 인스턴스에 대한 제약 조건이다. 다시 말하여, 허용되는 인스턴스와 허용되지 않는 인스턴스를 규정한다. 같은 값이 있어서는 안되는 수퍼키의 제한을 보자면 만약 테이블에 존재하는 값이.

 

관계 대수(relational algebra)

 

관계형 데이터 베이스도 질의어가 존재하며 이런 질의어의 이론적 바탕이 되는 것이 관계 대수와 관계 해석인데 여기서는 관계 대수에 대해서 알아보겠다.

 

보통의 덧셈, 뺄셈, 곱셈, 나눗셈 연산은, 주어진 수 두 개에 각 연산을 하며, 그 결과는 수 하나가 나온다. 마찬가지로 관계 대수 연산도 연산이기 때문에 데이터 베이스의 연산이므로 연산에는 테이블이 들어간다.  

 

변수 : 테이블 하나 또는 2

결과 : 테이블 하나

 

관계 대수의 기본 연산은 다섯개이다. 이 연산만 있으면 관계 대수에서 할 수 있는 모든 일을 나타낼 수 있다. 기본 연산말고 다른 연산이 더 있긴 하지만, 그런 연산은 기본 연산 다섯 개로 다 나타낼 수 있다.

예를 들자면 테이블A * 4라는 연산이 있다고 하면 테이블A + 테이블A + 테이블A + 테이블A라고 할 수 있을 것이다.

 

그럼 기본연산 5가지에 대해서 알아보자.

 

선택(SELECT) 연산

속성 추출(PROJECT) 연산

합집합(UNION) 연산

차집합(SET DIFFERENCE) 연산

카티전 곱(CARTESIAN PRODUCT) 연산

 

기본 연산 말고 다른 연산으로는 다음과 같은 것이 있는데, 이런 연산은 모두 위의 연산 다섯만으로 나타낼 수 있다.

교집합(SET INTERSECTION), 자연조인 (NATURAL JOIN), 나누기(DIVISION)

 

그럼 이제 하나한씩 알아보도록 하자.

 

선택(SELECT) 연산 -> 입력테이블 1개 결과 테이블 1

선택 연산은 테이블 한 개를 읽어서, 조건(PREDICATE, CONDITION)을 만족하는 투플만으로 이루어진 테이블을 결과로 내보내는 것이다.

선택연산은 σ시그마라는 기호로 나타낸다. 선택 연산은 σ p(R)과 같이 나타낸다. p는 조건이고 R은 테이블이며 결과 또한 테이블 이다. 입력 테이블과 결과 테이블의 스키마는 같지만, 결과 테이블에 있는 투플의 수는 입력 테이블에 있는 투플의 수보다 작을 수도 있다.

예제 테이블을 보자.

                                                   

아이디

패스워드

캐릭터

법사법사

654321

마법사

전사전사

123456

전사

도둑도둑

123456

도둑

 

위의 학생 테이블에서 아이디가 전사전사인 투플만 선택하려면 다음과 같이 한다.

 

σ 아이디 = “전사전사” (유저)

 

그럼 결과로 테이블이 나올 텐데 다음과 같이 나오게 된다.

 

아이디

패스워드

캐릭터

전사전사

123456

전사

 

셀렉트 연산이 어느 정도 이해가 갈 것으로 보인다. SLECT연산으로는 투플을 통째로 가져오게 된다.

 

** 참고로 관계대수의 SELECT 연산과 SQLSELECT 연산은 다르다. SQL SELECT 연산은 관계대수의 PROJCET와 같다.

 

속성추출 연산 (π, PROJECT): 입력테이블 1, 결과 테이블 1

 

속성 추출 연산은 테이블 한 개를 읽어서, 원하는 속상만으로 이루어진 테이블을 결과로 낸다.

PROJECT연산은 비추다라는 뜻인데, 테이블의 위에 어떤 속성은 감추고, 어떤 속성은 그대로 보이게 하여, 원하는 속성만 보이도록 하는 연산을 가리킨다.

속성 추출 연산은 π ATT1, ATT2 … (R)식으로 나타낸다. 여기서 ATT1, ATT2는 원하는 속성 R은 입력 테이블이며, 결과도 또한 테이블이다. 입력 테이블에 있는 모든 속성을 π뒤에 적는 예외적인 경우(당연히 모든 속성이므로 실제 연산은 일어나지 않는다)를 빼고는, 입력 테이블의 스키마와 결과테이블의 스키마는 다르다. 거의 모든 경우, 입력 테이블에 있는 속성의 수보다 결과 테이블에 있는 속성의 수가 적다.

 

아이디

패스워드

캐릭터

법사법사

654321

마법사

전사전사

123456

전사

도둑도둑

123456

도둑

 

π 아이디(유저)

결과는 예상이 될것이다.

 

아이디

법사법사

전사전사

도둑도둑

 

다른 연산도 한번 해보자.

π 아이디, 패스워드(유저)

 

아이디

패스워드

법사법사

654321

전사전사

123456

도둑도둑

123456

 

만약 테이블이 아래와 같을 땐 어떨까?

 

테이블 명 : 예제 테이블 1-1

아이디

패스워드

법사법사

654321

법사법사

125648

전사전사

564879

도둑도둑

123456

 

Π 아이디 (예제 테이블 1-1)

 

아이디

법사법사

전사전사

도둑도둑

 

결과를 보면 알겠지만 속성추출 연산을 하면 원래 입력 테이블보다 결과 테이블에서 투플의 수가 줄어든다고 잘못 생각할 수도 있는데 실제 연산에 따라서 다르다. 즉 하나의 속성에 입력된 투플에 같은 값이 없다면 당연히 결과 테이블의 투플은 달라지지 않는다.

이것을 보고 이번에는 혼합 연산을 해보자.

 

Π 패스워드 (σ 아이디 = “전사전사” (예제 테이블 1-1))

수학연산과 같다 먼저 가로안의 연산을 먼저 하므로 아이디가 전사전사인 투플이 뽑혔을 것이다.

이 상황에서 패스워드만 뽑아내는 연산을 하면 564879의 패스워드가 나올 것이다. 테이블로 나올 것이므로 다음과 같을 것이다.

 

패스워드

564879

 

합집합 연산합집합 연산(, UNION) : 입력테이블 2, 결과 테이블 1

 

위에서 선택 연산과 속성 추출 연산에서는 입력 테이블이 하나였는데, 합집합 연산의 입력 테이블 수는 두 개다. 말그대로 두개의 테이블을 합하는 연산을 행한다. 일단 먼저 간단한 합집합 연산을 해보자.

 

ID테이블1

아이디

법사법사

전사전사

도둑도둑

ID테이블2

아이디

힐러힐러

탱커탱커

도둑도둑

 

 ID테이블1 ID테이블2을 하게 되면

 

ID테이블 결과

아이디

법사법사

전사전사

도둑도둑

힐러힐러

탱커탱커

 

 

 

 

 

 

 

 

 

 

 

 

 결과테이블을 보면 알겠지만. 겹치는 투플은 테이블에서 제외된다.

 그럼 다음과 같은 테이블은 가능할까?

 

ID테이블1

아이디

패스워드

법사법사

1234568

전사전사

856412

도둑도둑

987523

ID테이블2

아이디

캐릭터

법사법사

전사

전사전사

마법사

도둑도둑

궁수

 

 위의 테이블 사이의 합집합 연산은 불가능하다. 합집합을 하기 위해서는 두개가 호환성(COMPATIBLE)이 있어야 하는데, 테이블 R1 R2가 호환성이 있으려면 다음의 2가지 조건을 만족시켜야 한다.

 

0.     테이블 TABLE1 TABLE2가 있다고 한다.

1.     TABLE1 TABLE2의 속성의 수가 같아야 한다.(속성수를 N이라고 하자.)

2.     TABLE1.A1 TABLE2.A1의 도메인(= 범위, 자료형)이 같고 TABLE1.A2 TABLE2.A2의 도메인이 같고 TABLE1.A(N) TABLE2.A(N)의 도메인 범위가 같아야 한다.

 

  즉 위의 예는 당연히 합집합 연산이 되지 않는다. 하지만 속성의 수가 아무리 많아도 속성의 도메인이 같다면 합집합 연산이 된다.

 

ID테이블1

아이디

캐릭터

전사전사

전사

탱커탱커

마법사

도둑도둑

궁수

ID테이블2

아이디

캐릭터

전사전사

전사

법사법사

격투가

마수마수

마수사

 

 다음과 같은 테이블을 합집합 연산을 하게 되면

 

ID테이블 결과

아이디

캐릭터

전사전사

전사

탱커탱커

마법사

도둑도둑

궁수

법사법사

격투가

마수마수

마수사

 

 

 

 

 

 

 

 

 

 

 

 와 같은 테이블이 나오게 될 것이다.

 

 차집합연산(-, SET DIFFERENCE):입력 테이블 2개 결과 테이블 1

 

 차집합은, 첫째 테이블에 있는 투플 가운데, 둘째 테이블에도 있는 투플을 뺀 나머지 투플만 결과 테이블에 나오다.

 이때 둘째테이블에만 있는 투플은 차집합 연산에 영향을 주지 않는다.

 

ID테이블1

아이디

캐릭터

전사전사

전사

탱커탱커

마법사

궁수궁수

궁수

ID테이블2

아이디

캐릭터

전사전사

전사

탱커탱커

마법사

용사용사

용사

 

 차집합 연산도 합집합과 마찬가지로 두개의 테이블의 호환성이 있어야만 가능하다.

 다행이 위의 두 테이블은 호환성이 있으니 차집합 연산을 해보도록 하자.

 

 ID테이블1 - ID테이블2 =

ID테이블결과

아이디

캐릭터

궁수궁수

궁수

 

 

 

 

 

1.     첫번째 테이블에 있는 투플 가운데 둘째 테이블에도 있는 투플을 뺀다.(전사전사, 탱커탱커)

2.     둘째 테이블에만 있는 투플은 차집합 연산에 영향을 주지 않는다.(용사용사)

3.     나머지 투플만 결과 테이블에 나온다.(궁수궁수)

4.     차집합 연산은 보면 알겠지만 교환 법칙이 성립하지 않는다. T1 – T2 = TR T2 – T1 = TR 되지 않는다.

 

 카티전 곱(X, CARTESIAN PRODUCT) : 입력 테이블 2, 결과 테이블 1

 카티전 곱은 이것만 따로 쓰는 일은 아주 드물고, 자연 조인을 위한 중간 과정으로 많이 쓰인다.

 카티전 곱은 어떤 설명보다 그대로 보는 것이 이해가 빠를 것이다.

 

ID테이블1

아이디

패스워드

법사법사

1234568

전사전사

856412

도둑도둑

987523

ID테이블2

아이디

캐릭터

법사법사

전사

법사법사

도적

전사전사

마법사

전사전사

전사

도둑도둑

궁수

 

 이전에 보여줬던 합집합 연산이 되지 않는 테이블 조합이다. 하지만 카티전 곱으로는 연산이 가능하다.

 

 카티전 곱을 하고 난 후 결과 테이블은 다음과 같은 특징을 가진다.

0.     테이블 TABLE1 TABLE2가 있다고 한다. 결과테이블은 TABLERESULT

1.     TABLERESULT의 속성의 수는 TABLE1, TABLE2의 속성의 합과 같다. 2+2가 된다.

2.     하지만 같은 속성은 존재할 수 없으므로 같은 속성은 이름을 변경해서 새로운 테이블 속성이 된다.

3.     결과 테이블의 투플 수는 양쪽 투플 수의 곱이다.

 

ID테이블RESULT

아이디(유저)

패스워드

아이디(보유캐릭터)

캐릭터

법사법사

1234568

법사법사

전사

법사법사

1234568

법사법사

도적

법사법사

1234568

전사전사

마법사

법사법사

1234568

전사전사

전사

법사법사

1234568

도둑도둑

궁수

전사전사

856412

법사법사

전사

전사전사

856412

법사법사

도적

전사전사

856412

전사전사

마법사

전사전사

856412

전사전사

전사

전사전사

856412

도둑도둑

궁수

도둑도둑

987523

법사법사

전사

도둑도둑

987523

법사법사

도적

도둑도둑

987523

전사전사

마법사

도둑도둑

987523

전사전사

전사

도둑도둑

987523

도둑도둑

궁수

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

자 쉽게 이해가 된다면 좋겠다. 결과를 보면 카타전 곱에 대해서 다시한번 정리해보자.

 

0.     테이블 TABLE1 TABLE2가 있다고 한다. 결과테이블은 TABLERESULT

1.     TABLERESULT의 속성의 수 = TABLE1, TABLE2의 속성의 합;

2.     TABLERESULT의 속성의 결과물 = TABLE1, TABLE2의 속성의 곱;

3.     R1에 있는 각 투플고 R2의 각 투플 사이에 조합 가능한 모든 경우에 두 투플을 붙여(CONCATENATE)만든 투플이 결과 테이블에 나온다.

4.     카타전 곱은 T1 – T2 = TR T2 – T1 = TR 된다. 즉 교환법칙이 성립한다.

 

관계 대수 그밖에 연산(ADDITIONAL OPERATIONS)

 

위에서 본 다섯 개의 연산으로 관계 대수가 할 수 있는 어떤 질의도 할 수 있다. 즉 지금부터 설명하려는 관계 대수 그밖에 연산이라는 항목에 나오는 연산들은 기본연산을 조합하여 만들어진 연산들이다.

 

교집합 연산(, SET INTERSECTION) 입력 테이블 2, 결과 테이블 1

교집합은 입력 테이블 두개 모두 들어있는 투플만 결과에 테이블을 내보낸다.

 

아이디

전사전사

탱커탱커

도둑도둑

아이디

전사전사

법사법사

마수마수

 

ID테이블1 ID테이블2 =

 

ID테이블결과

아이디

캐릭터

전사전사

전사

 

 

 

 

 

합집합 차집합과 마찬가지로 교집합도 입력 테이블 두개는 호환성이 있어야 한다.

또한 교집합 연산은 교환법칙이 성립한다.

 

0.     T1 – T2 = TR T2 – T1 = TR 되지 않는다.

1.     카타전 곱은 T1 – T2 = TR T2 – T1 = TR 된다. 즉 교환법칙이 성립하지 않는다.

 

그리고 앞서 말했듯이 추가연산은 기본연산을 기반으로 표현할수 있는데. 교집합은 다음과 같이 풀이할 수 있다.

(R1 R2) = (R1 - (R1 - R2)) = (R2 - (R2 - R1))

 

그럼 교집합을 사용하는 경우를 예로 들어보자.

 

유저&캐릭터TABLE

아이디

캐릭터

전사전사

전사

전사전사

마법사

도둑도둑

전사

도둑도둑

격투가

마수마수

마수사

 

 

 

 

 

 

 

 

 

 

 

다음의 테이블에서 전사와 마법사를 플레이하는 유저의 ID를 구해보자.

먼저 해야 할 일은 전사와 마법사를 플레이하는 유저ID를 모두 구해야 한다.

 

π아이디(σ 캐릭터= “전사” (유저&캐릭터TABLE))

 

아이디

전사전사

도둑도둑

 

 

 

 

 

 

그 다음은 마법사이다.

 

π아이디(σ 캐릭터= “마법사” (유저&캐릭터TABLE))

 

아이디

전사전사

 

 

 

 

자 이다음 두개의 테이블을 교집합 하면 결과는 예상하듯이 전사전사캐릭터만 나올 것이다. 이를 수식으로 다시 풀이해보면?

 

π아이디(σ 캐릭터= “전사” (유저&캐릭터TABLE)) π아이디(σ 캐릭터= “마법사” (유저&캐릭터TABLE))

쉽게 이해가 되었다면 좋겠다.

 

자연 조인(|X|, NATURAL JOIN) : 입력 테이블 2, 결과 테이블 1.

 

이 연산은 관계형 데이터 베이스에서 굉장히 자주 쓰이는 연산이다. 뒤에서 배울 스키마 정규화, 스키마 나누기 등과 밀접한 관련이 있다.

 

일단 연산 과정부터 설명해 보겠다.

 

0. 2개의 테이블을 정의한다.

1. 카티전 곱을 한다.

2. 테이블 R1 R2에 공통적으로 나오는 속성의 값이 같도록 하여 선택 연산을 수행한다.

3. 단계 2를 거치면서 각 투플에서 R1 R2에 공통적으로 나오는 속성은 그 값이 꼭 같기 때문에, 공통 속성은 한번만 나오도록 속성 추출 연산을 수행한다.

 

이걸 이제 실제로 해보자.

 

2개의 테이블이 존재한다.

ID테이블1

아이디

패스워드

법사법사

1234568

전사전사

856412

도둑도둑

987523

ID테이블2

아이디

캐릭터

법사법사

전사

법사법사

도적

전사전사

마법사

전사전사

전사

도둑도둑

궁수

 

카티전 곱을 한다. ID 테이블 1 X ID 테이블 2;

ID테이블RESULT

아이디(유저)

패스워드

아이디(보유캐릭터)

캐릭터

법사법사

1234568

법사법사

전사

법사법사

1234568

법사법사

도적

법사법사

1234568

전사전사

마법사

법사법사

1234568

전사전사

전사

법사법사

1234568

도둑도둑

궁수

전사전사

856412

법사법사

전사

전사전사

856412

법사법사

도적

전사전사

856412

전사전사

마법사

전사전사

856412

전사전사

전사

전사전사

856412

도둑도둑

궁수

도둑도둑

987523

법사법사

전사

도둑도둑

987523

법사법사

도적

도둑도둑

987523

전사전사

마법사

도둑도둑

987523

전사전사

전사

도둑도둑

987523

도둑도둑

궁수

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

σ 아이디(유저) = 아이디(보유캐릭터) (ID테이블RESULT)

ID테이블RESULT

아이디(유저)

패스워드

아이디(보유캐릭터)

캐릭터

법사법사

1234568

법사법사

전사

법사법사

1234568

법사법사

도적

전사전사

856412

전사전사

마법사

전사전사

856412

전사전사

전사

도둑도둑

987523

도둑도둑

궁수

 

 

 

 

 

 

 

 

 

 

 

 

π 아이디(유저), 패스워드, 캐릭터 (ID테이블RESULT)

 

ID테이블RESULT

아이디(유저)

패스워드

캐릭터

법사법사

1234568

전사

법사법사

1234568

도적

전사전사

856412

마법사

전사전사

856412

전사

도둑도둑

987523

궁수

 

 

 

 

 

 

 

 

 

 

 

 

 쓸모 있는 데이터만 뽑혀 나온듯 하다.

 자연조인을 할 때 최종 연산에서 제거하는 공통속성은, 일반적으로 한 테이블에서는 일차키이고, 타른 테이블에서는 외래키인 경우가 대부분이다. 그런 경우가 90% 이상이라고 봐도 될 정도라고 한다.

 이런 경우 결과 테이블에 나오는 투플의 수는, 공통 속성이 외래키인 투플 수와 거의 같다. 위에서 본 ID테이블 1, ID테이블 2가 있다을 때 ID테이블 2는 학번을 외래키로 가진 테이블이다. 그리고 결과로 나온 테이블의 투플 수도 확인한 바와 같이 5개이다.

 또한 자연조인을 할 때 결과 테이블이 나오지 않는 투플이 있는데, 이를 외톨이 투플(DANGLING TUPLE)이라고 한다.

 외톨이 투플은 참조 무결성과 관련이 있으니 기억해 두자.

 

 (VIEW, VIRTUAL RELATION, VIRTUAL TABLE)

 

 일반적으로 데이터베이스 안에는 그 기관에서 쓰는 거의 모든 자료가 들어가 있기 때문에, 그 자료를 모두 보게된다면 보안에 심각한 문제가 생긴다.

 보통 따라서 각 사용자가 업무에 맞는 필요한 정보만 볼 수 있게 해야 한다.

 이벤트 당첨자를 결정하기 위해서 마케팅 담당자가 유저테이블을 보는데 패스워드를 볼 필요가 없을 것이다.

 뷰의 필요성에 대해서는 짧지만 가장 좋은 예를 든 것 같고 이런 뷰를 정의하는 방안에는 2가지가 있는데 다음과 같다.

1)     뷰의 정의만 저장한다.

뷰의 정의만 정해놓고 데이터베이스에서 요청이 왔을 때 정의에 맞춰서 투플을 채워주는 것이다.

2)     뷰의; 투플을 계산하여 저장해둔다.

뷰를 정의할 때, 뷰의 투플을 미리 계산하여 저장해 두는 방식이다. 이런 뷰를 계산된 뷰 구체화된 뷰(MATERIALIZED VIEW)라고 한다.

 

 이런 뷰를 보기 위해서는 당연히 투플의 원 주인인 데이터베이스에서 정보를 받아와야 하는데 뷰에 대한 요청이 왔을 때, 다음의 두가지 과정을 거쳐서 뷰에 투플을 채운다.

1.     데이터베이스에 변경된 사항이 있다면, 뷰를 계산하여 저장한 뒤에 그 뷰를 쓴다

2.     지난번에 변경이 없다면 이미 계산하여 저장해두었던 뷰를 그대로 쓰면 된다.

 

당연히 뷰는 이름 그대로 보여주기 위한 용도이기 때문에 일반적으로 뷰를 보면서 수정하게 하는 일은 없다.

 

Posted by JJOREG

개체집합(ENTITY SET)


객체(ENTITY)또는 객체(OBJECT)

  개체란, 실제 세상에 있는 객체(OBJECT)이다. 개체와 객체는 뜻이 거의 같아서 서로 바꾸어 쓸 수 있다고 보면 된다.

  객체는 다른 객체와 구별되는데, 객체의 보기로는 각 사람, 각 자동차, 각 과목등이 있다. 각 사람은 다른 사람과 구별되며, 각 자동차도 서로 구별된다. 마찬가지로 각 과목도 서로 구별된다. 그런데, 사람이나 자동차는 실제로 만질수 있지만, 과목등은 그럴수 없다 그런데 개체-관계 모델에서는 구별하지 않는다


  개체집합(ENTITY SET)

  개체집합이란 같은 형의 개체의 집합이다. 보기를 들어 학생 개체집합, 은행의 고객 개체 집합, 교수의 개체의 집합 등이다. 그런데 개체집합은 반드시 서로 겹치지 안하야 하는 것이 아니라 겹칠수도 있다.

  즉 은행과 회사에 모두 김말동이라는 데이터베이스를 사용한다면 김말동은 은행과 회사 양쪽 개체집합에 모두 속한다.


 속성(attribute 또는 property)

  개체는 속성(attribute 또는 property)의 집합으로 나타낸다. 보기를 들어, 유저개체는, 비밀번호, 아이디, 캐릭터등의 속성으로 나타낸다.


  도메인(= 범위, domain)

  속성과 관련하여 도메인(=범위)라는 용어를 자주 쓰는데, 도메인이란, 어떤 속성의 값으로 될 수 있는 모든 값의 집합을 가리킨다. 보기를 들어, 유저의 이름이 맨 앞에 앞의 한자리를 성으로를 포함하여 일곱자리라고 하면, 이때 학번의 도메인(=범위)는 일곱자리이다.

  이런 이름의 속성은 문자열이고, 과목 이름은 일곱자리 문자열 이다.

  특히 SQL에서는 프로그램할 때는 자료의 형과 도메인을 거의 같이 다루기 때문에 이런 혼란이 생기게 된다.

  어떤 속성의 자료형과 도메인을 엄격하게 구별하지 않더라도, 실제로는 크게 혼란이 없는데, 엄밀하게 말하면, 도메인은 속성에 허용되는 값의 집합이지만, 경우에 따라서는 속성에 대한 자료형(보기 int, char(20))을 도메인이라고 보아도 될 것이다. 자료형으로 속성의 도메인을 나타냈더라도, 필요하다면 언제든지 실제로 허용되는 값인지 아닌지 엄격하게 확인하여, 잘못된 값이면(다시 말하여 도메인 밖의 값이라면)받아들이지 않으면 될 것이다.

  (도메인의 조건에 이름의 길이 말고도 다른 제한이 가능한지는 한번 물어보자.)

  

  속성의 형

  이제 속성의 형에(attribute type)에 대하여 살펴보자, 속성의 형은 두가지 다른 기준으로 독립적으로 나눌 수 있는데, 구체적으로 보면

  단순(simple) 속성과 복합(composite)속성

  값이 하나인(single-valued)속성과 값이 여럿인(multi-valued)속성

  이 두가지는 독립적이기 때문에 조합하면 다음과 같이 네가지 속성의 형이 나오게 된다.


  단순하면서 값이 하나

  단순하면서 값이 여럿

  복합이면서 값이 하나

  복합이면서 값이 여럿


  단순속성

  

  우리가 보통 쓰는 속성은 단순속성이다.

  create table 유저 {순서인덱스 char(7), 이름 char(20), 캐릭터 char(15)}

  

  복합 속성

  날짜를 여덟글자로 나타내는데, 연, 월, 일로 나눈다고 하면 다음과 같이 글자는 8글자로 나누고 연도는 4자리, 월 2자리 등으로 표현하면 이는 복합속성이다.

  하지만 이는 만약 가상적으로(SQL에서는 못하지만) 설정한 것이다.


  create table 날짜 { 날짜 (char(4), 월 char(2), 일 char(2)) }

  복합 속성은, 관계형 데이터베이스에서는 사용할 수 없다.


  값이 하나인(single - valued) 여럿인(multi-valued) 속성

  이제 값이 하나인 속성과 값이 여럿인 속성에 대하여 살펴보자, 보기를 들어, 학생이 세 과목을 수강한다는 사실을 다음과 같이 나타내면, 과목번호 속성은 값이 하나인 속성이다.


create table 수강1 (학번 char(7) , 과목번호 char(5)) ;

수강1 학번 과목번호 

99021 01 , CS333 

99021 01 , CS444 

9902101 , CS555


  그러나 학생이 세과목을 수강한다는 사실을 "가상적으로"(SQL에서는 역시 다음과 같이 못한다) 표시한다면 이는 값이 여럿인 속성이다.


create table 수강2 (학번 char(7) , 과목번호-목록 5et of char(5)) ;

수강2 학번 char(7) , 과목번호-목록 

9902101 , {CS333, CS444, CS555}


널(null) 값


  영어로는 null이라고 하는데, 이 말은 라틴 말 nullus에서 온 말이다. nullus는 n(아님) ullus(어떤 것도)가 더해진 것이다. 원래 뜻은 "값이 없다" 비었다, 0이다 등의 뜻이다.


 sql에서는 여러가지 의미로 쓰이므  null값은 다루기 골치 아프다. 

 

 1. 해당되지 않음

 2. 빠진 값

 3. 잘 모름


 null값은 될수록 쓰지 않는 것이 좋다고 본다. 특힝 예상되는 이상한 값은 null값 대신, 설계할 때 미리 정해둔 값을 쓰는 것이 좋다.


 관계 집합(relationship set)


  관계란 개체 두개 또는 여러 개 사이의 연관을 말한다. 관계 집합이란 같은 형의 관계를 모은 것을 말한다.


  예를 들어 학생과 과목이라는 객체가 있을때 어느 학생이 어느 과목을 듣는지(=연관)을 생각해 볼수 있는데.

  이것을 수강 관계라고 할수 있다.


  위에서 객체의 속성을 배웠는데, 관계에도 속성이 있을 수 있다. 

  보기를 들어 학생과 과목 객체 사이의 수강 관계에서 학생이 받은 성적 등급 속성을 생각 할 수 있다. 만일 성적 등급이 어떤 과목 객체의 속성이라면, 

  그 과목을 듣는 모든 학생이 꼭 같은 성적을 받는 웃지 못할 일이 생긴다.

  그러므로 성적은 학생과 과목 객체 사이의 수강 관계의 속성으로 나타내는 것이 옳다.


  거의 모든 관계가 두 객체 사이의 관계인 이진(binary)관계 이지만, 가끔 세개 이상의 객체 관계도 있을수 있다.


  객체 집합으로 나타낼까, 관계 집합으로 나타낼까.

  위에서 객체 집합과 관계 집합을 살펴보았는데 설계를 하다보면 실제로 어떤 것을 객체로 나타낼지, 아니면 관계로 나타낼지 뚜렷하지 않을 때가 있는데 그건 너무나 당연하므로 걱정하지 않아도 된다. 그런 경우, 반드시 객체로 해야 한다든지, 아니면 반드시 관계로 해야한다든지 하는 규칙은 전혀 없다.


  사상(=매핑)제약 조건(mapping constraints)

   두 객체 사이에 이진 관계가 있을때, 저 쪽 객체에 연결될 수 있는 이쪽 객체의 수를 사상 크기(mapping cardinalities)라고 한다. 이 관계는 1:1 1:n m:1 m:n 네가지가 있다. 전화번호와 그 전화번호 소유자 사이의 관계를 보기로 매핑크기를 살펴보자.


  1. 전화번호 : 소유자_주번 = n:1

  전화번호는 소유자가 한명 뿐이다.

  그러나 한 사람이 여러대의 전화를 가질 수 있다.


  2. 전화번호 : 소유자_주번 = 1:n

  각 사람은 전화번호를 하나만 가질수 있다.

  그러나 여러 사람이 한대의 전화를 같이 가질 수 있다.


  3. 전화번호 : 소유자_주번 = 1:1

  각 전화번호는 소유자가 한명이고

  각 사람은 전화번호를 하나만 가질 수 있다.

  달리 말하면 각 사람은 전화번호 하나만, 각자 독점적으로 가지게 된다


  4. 전화번호 : 소유자_주번 = m:n

  한사람은 여러개의 전화번호를 가질 수 있고,

  한 전화번호는 여러 사람이 같이 쓸 수 있다.


  이런 네가지 가능성 가운데 우리 현실에 가장 가까운 것을 찾는다면 일반적으로 4번일 것이다.


  이는 대학으로 치면 학생이 학과를 이중 전공하고 학과는 여러학생이 모여잇다고 친다면 있을 때도 4번과 같이 나눌 수 있다.


  키(key)

  객체 집합이 있을 때 그 안에 있는 각 객체를 어떻게 구별할 수 있을까 하는 문제가 있다. 물론 관계 집합에서도 마찬가지로 관계 집합 안에 관계가 여러개 있을때 그안에 있는 각 관계를 어떻게 구별할까 인데 개체-관계 모델에서는 결국 그 객체의 속성 값으로 구별할 수 밖에 없다.

  이제 개체 집합에서 특정 개체를 가리킬 수 있는 여러가지 키에 대하여 배워보자. 


  수퍼키(SK: superkey)

  개체집합에서는 어떤 개체를 유일하게 가리킬 수 있는 하나 이상(= 하나 또는 여러)속성의 집합을 "수퍼키"라고 한다. 후보기에 필요한 속성말고 더 많은(super)속성이 있을 수 있어서 superkey라고 하는데, 이때 super는 우리말로 넘치는 뜻이 있다.


  ex)

  학번은 각 학생을 유일하게 가리킬수 있으므로, 학번은 수퍼키이다. 위에서 보았듯이 키는 속성의 집합이므로, 학번자체가 키가 아니라 {학번}이 키이다.

  {학번, 이름}은 각 학생을 유일하게 가리킬 수 있으므로 {학번, 이름}은 수퍼키이다.

  {주번}은 수퍼키일까? 주번은 사람을 유일하게 가리킬수 잇으므로 수퍼키이다.

  {이름}은 수퍼키일까? 이름이 같은 사람은 있을수 잇으므로 이름은 수퍼키가 아니다.


  후보키(CK, candidate key)

  주어진 수퍼키의 속성에서, 어떤 속성을 뺀 뒤에도 수퍼키가 될수 있다면, 주어진 수퍼키는 후보키가 아니다. 달리 말하면, 주어진 수퍼키의 속성에서 속성 하나라도 뺀다면 수퍼키가 될 수 없을 때, 주어진 수퍼키를 후보 키라고 부른다.

  다른 각도에서 보면, 후보키는 최소의 수퍼키이다. 말로하자니 후보키가 좀 어렵지만 보기를 보면 쉽게 알수 있다.

 {학번, 이름}도 수퍼키이고, {학번} 도 수퍼키이다. 이중에서 이름을 빼도 {학번은 }수퍼키므로 후보키가 아니다.


  거기에 비해서 {학번}에서 속성을 하나라도 빼면 {}이 되어 버리므로(빈 집합 : empty set)가 되어버리므로 더 이상 수퍼키가 아니다. 따라서 {학번}은 후보 키이다.


  {주민번호}는 후보키 일까? 만일 주민 등록 번호가 겹치지 않는다고 가정하면, 위에서 보았듯이 주번은 수퍼키이고, 속성 하나로 이루어진 수퍼키는 후보키 이므로 {주번}은 후보키이다.


  일차 키(PK: primary key)

  주어진 객체 집합 또는 관계 집합에 만일 후보키가 하나뿐이면, 그것이 저절로 일차키가 된다. 그런데, 만일 주어진 집합에 후보키가 둘이상 잇으면, 데이터베이스를 설계할 때 그 가운데 하나를 일차키로 고르고 나머지는 그냥 후보키가 된다.

  그러면 일차 키인{학번}과 일차 키가 되지 못한 후보 키{주번}은 어떻게 다를까? 나중에 참조 무결성을 볼때 알겠지만, 보기를 들어, 학생 객체집합과 과목 객체 집합 사이의 수강관계 집합에서, 학생 객체를 가리킬 때 일차키인 {학번}을 쓰며, 일차키가 아닌 후보키 {주번}을 쓰지 않게 된다. 이것이 일차키가 아닌 후보키 사이의 아주 중요한 차이이다.


학생 객체 집합={ (9902101 , 흥길동, 790101-1234567 , ... ), 

(9902102, 박두리, 791212-3456789, .. .), .. .} 

과목 객체 집합={ (CS100, 컴퓨터 개론 .. . ), 

(CS200, 프로그래밍, .. . ), 

(CS300, 데이터베이스 , ... ) } 

수강 관계 집합1={ (9902101 , CS100, ... ), 

(9902101 , CS200, .. .) , 

(9902102, CS200, ... ), 

(9902102, CS300, .. . )}


  위의 수강 관계 집합1에서 보듯이, 학생 객체를 가리킬 때 일차 키인 {학번} 9902101, 9902102 등으로 나타낸다. 다시말해서 수강관계 집합2에서와 같이 {주번}으로 가리키지 않는다는 것이다. 일차 키와 일차 키가 아닌 후보 키는 이 보기를 통하여 확실히 이해하였으리라 본다.


  수강 관계 집합2={ (790101-1234567 , CS100 , ... ), 

(790101 -1234567, CS200, ... ), 

(791212-3456789, CS200 , ... ), 

(791212-3456789, CS300, ... )}

  

    그런데, 위에서 수퍼키, 후보 키, 일차 키 등을 배웠는데, 어떤 속성이 그냥 키이다. 아니다라고 말할 수는 없고, 주어진 집합안에서 키이다 아니다라고 말할 수 있다. 구체적인 보기를 들자면, 학생 집합에서 학번은 후보 키이지만, 그렇다고 {학번}이 늘 후보키라고 할 수는 없다는 것이다.


  보기를 들어 수강 관계 집합을 생각해 보자. 학번이 9902101 인 학생이 세 과목 을 수강하면, 수강 관계 집합에는 그 학번이 있는 객체가 세 개 있다. 실제로 수강 관계 집합의 후보 키는 {학번 , 과목번호}이다. 따라서 {학번}이 학생 객체 집합에 서는 후보 키이지만, 수강 관계 집합에서는 후보 키가 아니다. 


  따라서 {학번}이 일반적으로 키이다 또는 아니다라고 말할 수 없고, 어떤 객체 집합이 주어졌을 때 그 집합에서 {학번}이 키이다 또는 아니다라고 말할 수 있는 

것이다. 이 점은 아주 중요하므로 잘 알아두기 바란다. 즉 객체집합안에 들어가서야 키로서 의미를 지니게 된다.


  sort key

  수퍼키, 후보 키, 일차 키 등에서 말하는 키는 주어진 객체 집합 에서 그 키 값만 일면, 어떤 특정 객체를 가리킬 수 있다‘ 하지만, 간추리기를 할 때 쓰는 키 (sort key 또는 sort field) 라는 용어는, 위에서 배운 수퍼(=넘치는)/후보/일차 키에 나오는 키와 개념이 다르다 간추리기 키는 그냥 그 값으로 간추린다는 뜻이며, 그 따일 안에 간추리기 키 값이 같은 줄이 여러 개 있을 수도 있다. 보기를 들어, 수강 관계가 있는 파일을, 학번을 간추리 기 키로 하여 간추렬 수 있는데, 이 경우 학번이 같은 줄이 여러 개 나올 수 있다.

  즉 현재 테이블 안에서 sort key를 지정하고 이 키를 이용해서 테이블을 간추린다. 할때 그 키를 기준으로 정렬되는데 이럴때 사용하는 것이 sort key다.


  외래 키(foreign key)

  앞서 나온 키들은 주어진 테이블에서 특정 투플을 가리킬 수 있는 키이다. 여기서 투플이란 다음 설명을 보자.


  

 Attribute 

  
     
     
     
 Tuple    
     


   릴레이션 (relation) 

같은 성격의 데이터들의 집합을 의미. 흔히 테이블이라고 말하는 용어와 같은 의미로 이론적인 용어. 

릴레이션은 튜플과 에트리뷰트로 데이터를 정렬하여 관리한다. 


   튜플 (tuple)

릴레이션의 각 행을 의미. 흔히 일반적인 용어로 레코드(record)와 로우(row)와 같은 의미로 사용된다. 


   에트리뷰트(attribute)

릴레이션에서 이름을 가진 하나의 열을 말한다. 흔히 일반적인 용어로 칼럼(column)과 같은 의미로 사용된다. 


   디그리(degree)

에트리뷰트의 수를 말한다. 


   카디널러티(cardinality)

튜플들의 수를 말한다. 

- 한 릴레이션에 정의된 튜플들은 모두 다르다. 

- 한 릴레이션에 정의된 튜플들은 순서에 무관하다. 

- 튜플들은 시간에 따라 변한다. 

- 릴레이션 스키마를 구성하는 에트리뷰트의 값은 동일해도 된다. 

- 에트리뷰트는 더 이상 쪼갤 수 없는 원자값으로 구성된다. 

- 릴레이션을 구성하는 튜플을 유일하게 식별하기 위한 속성들의 부분집합을 키(Key)로 설정한다. 

  

  외래키란 다른 테이블에서 일차키인 속성의 집합이 주어진 테이블이 있을때, 이 속성의 집합을 주어진 테이블에서 외래키라고 한다. 말로는 어려운듯 하지만 보기를 보면 쉽게 알수 있다.  일단 키를 구성하는 SQL 명령어를 보자


create table 수강 (학번 char(7) 과목번호 char (7), 

primary key (학번, 과목번호)) ; 


그리고 위에서 보았던 학생 테이블의 스키마는 다음과 같이 정의할 수 있었다. 


create table 학생 (학번 char(7) , 이 름 char (2이 , 

primary key (학번));


  위의 수강 테이블에서 {학번}은 일차 키가 아니지만 (일차 키는 {학번, 과목번호}), {학번}은 학생 테이블에서 일차 키이다. 따라서, 수강 테이블에서 {학번}은 외래 키이며, 이 사실까지 더하여 수강의 스키마를 SQL로 나타내면 다음과 같다.


create table 수강 (학번 char (7), 과목번호 char (7) , 

primary key (학번, 과목번호) , 

foreign key (학번) references 학생) ;


  수강 테이블의 일차 키는 {학번, 과목번호}인데 이 사실은 primary key 키 설정에 나타나있다. 수강 테이블의 {학번}은 외래키이고, {학번}은 학생 테이블에서 일차 키인데, 이 사실은 "foreign key (학번) references 학생"에 나타나있다. references 다음에는 학번이 일차 키인 테이블의 이름 학생이 온다.


  일반적으로 키라고 말할 때는, 어떤 테이블의 스키마에서 어떤 속성의 집합이 무슨 키라고 해야한다. 외래 키의 경우에도 이 말은 적용된다. 그냥 막연히 학번이 외래키라고 하는 건 틀리며 수강스키마에서 학번이 외래키라고 말해야 정확하다. 학생 스키마에서 학번은 일차키이므로 각 키가 소속된 테이블을 명확하게 명시해 주지 않고 말하면 틀린것이다.


  개체 관계도 (entity - relationship diagram)


  객체 관계 모델에서는 데이터베이스의 논리적인 구조를 그림으로 나타낼수 있는데. 이를 개체 관계도라고 한다. 프로그램의 순서도와도 마찬가지인데. 개체-관계도는 데이터베이스를 설계할 때의 순서도라고 생각하면 된다.


  이런 식으로 표현되는 것이 개체관계도를 의미한다.


  관계의 표현(relationship)의 표현

  관계란 여러 개체 사이에 존재하는 연관성을 말하는데, 보기를 들어 학생과 과목 사이에 수강이라는 관계가 있다면, 학생과 과목 객체를 수강이라는 관계로 연결하여 그려볼 수 있다.



  여기에 관계 속성인 수강 관계에 학점이라는 속성이 생긴다면 다음과 같이 표현할 수 있다. 학점은 학생이나 과목 어디에도 포함되지 않고 수강에 포함되는 속성이이다.


 이거 왠지 UML이랑 비슷해 지는 느낌인데. 사상크기또한 개체와 개체를 연결하는 선에 화살표를 사용하여 나타낸다. 사상크기는 아까 봤던대로, 1:1, 1:N, N:1, M:N이 있는데 이 내가지를 화살표로 다음과 같이 표현이 가능하다.



  이 관계도를 보고 테이블을 만드는 과정은 당연히 그 반대로 실행하면 된다. 또한 일차키에는 밑줄을 치는 방식으로 표현할 수가 있다.


  이렇게 구조도를 짜고 DB구조를 설계할때 주의해야할 점은

  관계를 테이블로 만드는 것은 개체를 테이블로 만드는 것보다 조금더 복잡한데. 위 그림에서 수강테이블을 말하는 것인데. 관계를 맺고 있는 개체의 사상 크기에 따라 만드는 방법이 다르다. 각 사상크기에 따른 테이블 생성 방법은 다음과 같다.


  1:1 관계 : 관계에 참여하는 한쪽 개체의 속성에 다른 쪽의 개체의 일차키를 포함시킨다. 관계 자체에 속성이 있는 경우, 한쪽 개체의 속성에 관계 자체의 속성도 포합시킨다.

  1:N N:1의 관계 : N쪽 개체에 대응하는 테이블의 속성에 1쪽 개체의 일차키를 포함시킨다.(외래 키가 됨). 관계 자체에 속성이 있을 경우, N 쪽 개체에 대응하는 테으블의 속성으로 관계 자체의 속성을 포함시킨다.

  M:N의 관계 : 관계 이름으로 된 새로운 테이블을 만들되, 관계에 관련되는 개체 두개의 각각의 일차키와 관계 자체의 속성을 테이블의 포함시킨다. 이때 관계에 대응하는 테이블의 일차 키는 개체 두개의 일차 키를 더한 것이다.









  





Posted by JJOREG



  자료 정의어(DDL: data definition language)

  자료 정의어는 스키마를 정의하는 언어이다. 스키마 정보는 자료 사전(data dictionary, 또는 자료 목록(= data directory)이라고도 함)에 들어 있다. 스키마 정보란, 자료(보기: 아이디, 패스워드 등)에 대한 자료(보기: 아이디의 자료형은 char이고 몇자리의 char인지)인데, 이를 메타데이터(metadata)라고 보통 부른다.

  

  SQL에서 자료 정의어의 보기를 들면 다음과 같다.


  create table 유저 {순서 인덱스 char(7), 아이디 char(10), 패스워드 char(15), 보유 캐릭터 개수 int };  


   자료 조작어(DML: data manipulation language)

   자료 조작어는, 데이터베이스 안에 있는 자료를 가져오거나(retrieve), 없에거나(delete) 바꾸거나(update), 데이터 베이스에 새 자료를 넣는(insert)일을 한다.

   SQL에서 자료 조작어의 보기를 들면 다음과 같다.


select * 

from 유저

where 아이디 = ’홍길동’; 


insert into 유저

values ('9902101' ’ 흥길동’); 


delete 

from 유저 

where 아이디 = 홍길동’? 


update 유저 

set 아이디 = '장길산’ 

where 아이디 = 홍길동’ ;


  자료 조작어의 성질 : 비절차적, 집합 결과


  자료 조작어의 성질을 말할때 책에 따라서 풀이가 좀 달라서 혼란스러운데 다음과 같이 두가지 독립적인 기준에 나눌수 있으며, 그 결과 2*2의 네가지 로 나눌 수 있다.


  첫째 절차적인지 (procedural) 비절차적인지 (non - procedural)

  우리가 많이 쓰는 c 등의 고급프로그래밍 언어는 거의 모두 절차적이다.

  int a = 0; 이런 문장은 정수형 a를 선언하여 메모리 상에 올리고 거기에 0을 대입하는 절차적인 과정을 거친다.

  절차적인 자료 조작어로는, 뒤에서 배우게 될 관계 대수 (relational algebra), 그리고 계층적 모델과 네트웍 모델에서 쓰는 자료 조작어가 있다.

  비절차적 언어로는 관계 해석(relational calculus)가 있으며, 또한 관계 해석을 많이 채택한 SQL에서도 비절차적 면을 볼수 있다.(SQL은 관계 해석과 관계 대수 두가지에 바탕을 두고 있다.) 


  비절차적 언어의 특징을 살펴보면, 보기를 들어 유저, 아이디, 캐릭터라는 속성으로 이루어진 유저라는 테이블이 있을때 유저 테이블의 스키마와 인스턴스가 아래와 같다면


   유저   순서인덱스    아이디    캐릭터

0000000001   ID1          전사

0000000002   ID2          전사

0000000003   ID1          마법사

0000000004   ID2          마법사


   이테이블에서 캐릭터가 마법사인 유저의 아이디를 찾아내라고 한다면 절차적 언어에서는  FOR문등으로 반복을 돌면서 찾게 될 것이다.

  그에 비해서 비절차적 언어인 SQL을 쓴다면 어떤 철자적인 내용에 대해서는 말하지 않고 다음과 같이 쓸것이다.


  select 순서인덱스

  form 유저

  where 캐릭터 = "마법사"


  둘째, 자료 조작어의 명령 결과로 한번에 레코드가 한개(recored-at-a-time)씩 나오는지 아니면 여러개의 자료(자료의 집합)가 한꺼번에 나오는지 (set-at-a-time)에 따라서 두가지로 나뉜다.  조합해 보면 다음과 같다.


  비절차적 한개씩 (이녀석은 별로 없다고 한다)

  비절차적 자료집합 (관계 해석 SQL)

  절차적 한개씩 (계층적 모델, 네트웍모델)

  절차적 자료집합 (관계 대수)


  질의어(query language)와 자료 조작어(DML)


  질의어(쿼리)라는 낱말은 원래 뜻은 물어보다이며 데이터 베이스와 관련하여서는 이미 있는 자료나 정보를 가져오는 것이다. SQL에서 보면 select만 해당되고 insert, delete, update는 해당되지 않는다.

  이에 비해, 자료 조작어(DML)는 이미 있는 자료를 가져오는 것뿐만 아니라, 있는 자료를 지우거나 고치는 것과, 새 자료를 넣는 것까지 할수 있으므로 질의어 보다 더 넓은 개념이다. SQL에서 보면 select, insert,delete, update를 모두 포함하는 개념이다.

  그렇지만, 오늘날 실제로 질의어라는 용어를 원래의 뜻대로 있는 자료를 가져오는 것에 국한하여 쓰는 일은 아주 드물다. 거의 모든 사람들은 쿼리문을 자료 조작어와 맞바꾸어 쓸수 있는, 뜻이 같은 용어로 본다. 낱말의 원래 뜻을 생각하면 잘못된 용법이지만, 오늘날 거의 모든 사람들이 이렇게 하므로 그냥 관습을 따를 수 밖에 없다고 본다.


  데이터 베이스 관리자와 사용자

  데이터 베이스 관리자(DBA: Database Administrator)

  데이터 베이스 관리자는 데이터베이스 관리 시스템을 관리할 뿐만 아니라, 데이터베이스, 그리고 그 기관에서 개별된 응용 프로그램을 관리한다. 작은 기관의 경우에는 한사람이 관리자 일을 할 수도 있을 것이고, 큰 기관에서는 관리자의 일을 여러 사람이 맡게 된다.

  관리자는 그 밖에도 자료 접근 권한을 정하고 바꾸는 일, 무결성 제약 조건을 정하는 일을 한다.


  데이터 베이스 사용자


  데이터 베이스 사용자의 종류는 너무 많고, 또한 나누는 기준에 따라 다르지면 몇가지 종류를 보자면


  응용프로그래머 : 주어진 데이터베이스 관리시스템을 써서 그 기관에 필요한 응용프로그램을 만든다. 게임을 만드는 프로그래머도 이에 속한다. 이 경우 보통의 SQL(이른 바 상호 작용적 SQL: interactive SQL)을 바로 쓰기보다는 주로 내포된(embedded) SQL을 많이 사용한다.

  일반사용자 : 만들어진 응용프로그램을 쓰는 사람인데, 실제로 이런사람이 엄청 많다. 뭐 그냥 실생활에 쓰이는 대부분을 보면 된다. 우리 자신들 이니까.


  4GL 운영체제


  4GL(fourth generation language)

  4GL 데이터베이스를 다루기 위하여 쓰는 언어 가운데 4GL이라는 것이 있다. 

  제 1세대 언어는 1GL(first-generation language)라고 하며 기계어(machine langage)가 여기에 속한다.

  제 2세대 언어는 어셈블리 언어

  우리가 쓰는 c같은 고급언어를 3세대 언어라고 한다.

  4GL이란 3GL보다 한단계 더 높다고 보다는데, 일반적으로 데이터베이스 환경에서 양식을 만들거나 화면에 자료를 보여주는 프로그램을 쉽게 짤 수 있게 해주는 것이 4GL의 주요 기능이다. 그런데 SQL은 표준화가 잘되어있어서, SQL 프로그램이 다른 데이터베이스 관리 시스템에 옮겨가더라도 별 어려움 없이 잘 돌아간다. 하지만 4GL은 표준화가 전혀 되어 있지 않아서, 다른 데이터 베이스 관리 시스템에 옮겨가서 쓸 수가 없다는 단점이 있다.

  

  데이터 베이스 관리 자체(DBMS)  와 운영 체제(OS)

  운영 체제의 관점에서 보면 데이터베이스 관리 시스템은 어디까지나 하나의 응용프로그램이므로, 데이터베이스 관리 시스템은 운영체제 위에서 돌아간다. 위에서 돌아간다고 해서 데이터베이스 관리시스템이 운영체제를 관리한다는 것은 아니다. 운영체제가 데이터베이스 관리 시스템을 통체한다.

  일반적으로 파일을 처리하는 응용프로그램의 경우, 응용 프로그램에서 운영체제의 파일관리자를 통하여 파일을 처리하게 된다. 그런데 데이터베이스 응용프로그램은 파일의 내용을 바꾸려면, 먼저 데이터베이스 관리시스템에 이를 요청하고, 데이터베이스 시스템은 다시 운영체제의 파일 관리자를 통하여 파일을 처리하게 된다.

  

Posted by JJOREG

데이터 베이스에서 뷰란?

  뷰(=view)는 가상 테이블(=virtual relation)이라고도 한다.


자료의 추상화(data abstraction) 세 단계


  데이터베이스 관리 시스템과 사용자 사이의 상호 작용을 쉽게 풀이하기 위하여 데이터베이스의 자료를 추상화하며, 보통 다음과 같이 세 가지 수준으로 나눈다.

  하지만 이는 개념모델(reference model)이다. 즉 꼭 따라야 하는 것은 아니며 데이터 베이스의 모든 시스템이 이 모델에 의하여 구성된 것은 아니다.

  이는 마치 데이터통신에서(ISO OSI의 일곱 단계 통신모형에 맞는 통신 프로그램이 거의 없는 것이나 마찬가지이다.)


  1) 물리적 수준(physical level)

  자료가 실제로 저장되는 수준이며, 가장 아래 수준이다.


  2) 논리적 수준(logical level)

  이것은 데이터베이스 관리자(DBA : database administrator)이 처리하는 수준이다.


  3) 뷰(=가상 테이블) 수준(view level)

  일반 사용자가 쓰는 수준으로 볼 수 있다. 이런 것이다. 데이터란 결국 바이트단위로 처리를 하게 되는데. 이는 기계어로 보면 왠만해서는 알아볼 수 없다.

  하지만 문서처리 프로그램중 엑셀프로그램 처럼 도표로 사용자가 볼 수 있고 권한에 따라서 필요한 부분만 수정할 수 있다면? 이런 부분이 바로 view 수준이라고 한다.


  그런데 실제 상용 데이터베이스 관리 시스템에서 어떤 명령이 어느 수준에 해당하는지 명확하게 나누는 것은 쉽지 않다. 뷰 수준은 그런데로 쉽게 알 수 있지만 물리적 수준과 논리적 수준은 때때로 경계가 모호하다. 하지만 앞서 말했듯 위의 세가지 모델은 어디까지나 참조 모델일 뿐이므로, 구체적인 어떤 사용 데이터베이스 관리 시스템의 명령을 세단계로 나누는 문제에 너무 매달리지 말자.


자료의 독립성(data independence)


  일반적으로 자료의 독립성이란 어느 단계의 스키마를 바구었을 때, 그 위 단계의 스키마에 영향을 주지 않고 결국 응용 프로그램에 영향을 주지 않는 것을 가리킨다.

  c++로 친다면 클래스 간의 의존성 제거 객체지향적으로보면 리스코프 치환법칙과 의미가 통한다.

  자료의 독립성은 다음과 같이 두가지로 나타나게 된다.


  1) 물리적(physical) 자료 독립성

  맨 아래 단계인 물리적 스키마를 바꿔도, 그 위 단계인 논리적 단계 스키마에 영향을 주지 않는 것을 가리킨다. 당연히 논리적 스키마에 영향을 주지 않으므로 그 위 단계인 뷰 단계의 스키마에는 물론 영향을 주지 않는다.

  

  여기서 잠깐! 스키마란?

  데이터베이스 스키마(database schema)는 데이터베이스에서 자료의 구조, 자료의 표현 방법, 자료 간의 관계를 정의한 것을 말하는 전산학 용어이다. 데이터베이스 관리 시스템(DBMS)이 주어진 설정에 따라 데이터베이스 스키마를 만들어 내며, 데이터베이스 사용자가 자료를 저장, 조회, 삭제, 변경할 때 DBMS는 그것이 생성한 데이터베이스 스키마를 참조하여 명령을 수행한다.


  2) 논리적(logical) 자료 독립성.

  가운데 단계인 논리적 단계의 스키마를 바꿔도 그 윗 단계인 뷰 단계의 스키마에 영향을 주지 않는 것을 가리킨다. 뷰 단계 스키마에 영향을 주지 않기 때문에, 그 결과 응용 프로그램에도 영향을 주지 않는다.


  이때 이 두가지 독립성 단계에 대해서 제대로 설명하지 않는 부분이 많은데 그 이유는 상용 데이터 베이스 관리 시스템에서 물리적 단계와 논리적 단계를 나누기가 쉽지 않기 때문이다.

  하지만 SQL명령어 적으로 예를 들어 보겠다.


  create table 유저 {순서인덱스 cahr(7), 아이디 cahr(20)};


  위의 create table 명령은 순서인덱스와 아이디이라는 속성으로 이루어진 학생이라는 테이블을 만든다. 그 뒤 아래에 select 명령을 쓰면, 아이디가 '홍길동'이라는 유저의 이름을 보여준다.


  select *

    form 유저

    where 아이디 = '홍길동';


  자료의 독립성에 관한 구체적인 첫번째 보기는 색인(= 찾아보기, index)이다. 색인이 있으면 검색속도가 빨라지게 되는데.

  보기를 들어 유저수가 10000명인데 유저자료가 아이디 순서대로 간추려져 있다면 이름에 대한 색인이 없다고 한다면 create index 명령을 써서 이름에 대한 색인을 만들어 둔뒤 '홍길동'을 찾으면,색인이 없을 때보다 검색 속도가 훨씬 빨라진다.


  create index 이름_색인

  on 학생(이름);

  select *

  form 유저

  where 아이디 = '홍길동';

  

  그런데, 여기서 중요한 것은 색인이 새로 만들어 지더라도, 위의 select 명령을 전혀 바꾸지 않고 꼭 같은 결과를 얻을수 있지만, 색인이 있든 없든, select 명령은 바뀌지 않고 그대로 이고, 다만 실행 속도가 달라질 뿐이다.


  자료 독립성에 관한 구체적인 둘째 보기는 뷰에 관한 것이다. 보기를 들어, 아래와 같이 순서 인덱스, 아이디, 패스워드로 이루어진 유저이라는 테이블이 있고, 학생이라는 테이블에서 create view 명령을 써서, 학번과 이름만으로 이루어진 학생_view라는 뷰를 정의했다고 하자


  create table 유저 {순서 인덱스 char(7), 아이디 char(10), 패스워드 char(15)};

  create view 유저_view as

   select 순서 인덱스, 아이디

     from 유저;


  이렇게 하면 응용 프로그램에서는 유저_view라는 뷰를 다음과 같이 쓸 수 있다.

  

  select *

    from dbwj_view

    where 순서인덱스 = '9902101';


  그런데 학생에 휴대전화라는 속성이 하나 더 들어가서 유저의 스키마가 다음과 같이 바뀌었다고 하자.

  

  유저 {순서 인덱스 char(7), 아이디 char(10), 패스워드 char(15), 휴대전화 char(15)};

  

  유저의 스키마가 이렇게 바뀌더라도 결국 유저_view를 정의하는 create view 명령을 바꿀 필요가 없으며, 또한 유저_view를 쓰는 응용프로그램에서 select 문장을 전혀 바꾸지 않아도 결과는 제대로 나온다. 유저의 스키마가 바뀌었지만, 유저_view의 정의를 바꿀 필요가 없으며, 유저_view 뷰를 쓰는 응용프로그램에서 SQL문장을 전혀 바꿀 필요가 없다.

  이를 고급프로그래밍 언어 C++에서 처리한다고 생각해보자.


found=0 ; 

for 0=1; (= num_records ; i++) { 

read from 유저_view 순서인덱스 , 아이디) ; 

if (아이디 = 홍길동’) { 

printf (학번, 01 름) ; found++ ; 

} // endif 

} // end for 

if (tound == 0) 

  printf 홍길동 학생이 없습니다 ) ;


식으로 짜며 당연히 다형성이나 그때그때 필요한 코드를 또다시 짜야만 할것이다.

물론 이런 것을 감안하고 프로그래밍 할 수는 있지만 그것은 이미 존재하는 데이터 베이스 시스템과 같은 역할을 하는 파일입출력 프로그램을 고급언어로 다시 짠다는 것인데 엄청난 노력과 시간이 들어가게 될 것이다.


스키마(schema)와 인스턴스(instance)?


  데이터 베이스와 관련하여 스키마와 인스턴스는 구별되어야 하는데 관계형 데이터 베이스의 경우에는 관계(= 테이블, relation)와 데이터베이스 각각에서 스키마와 인스턴스 개념이 적용된다. 다시 말하여 테이블의 스키마와 테이블의 인스턴스가 존재하며 또한 데이터 베이스의 스키마와 데이터베이스의 인스턴스라는 개념이 존재한다는 것이다.


  관계형 데이터베이스 환경에서 관계의 스키마와 관계의 인스턴스를 비교해보자. 아홉 자리를 차지하는 순번 인덱스이라는 속성(attribute), 스무 자리를 차지하는 아이디이라는 속성, 그리고 열 다섯 자리를 차지하는 패스워드라는 속성으로 이루어진 학생이라는 관계를 만드는 SQL 문장 create table가 아래에 나와있다.


  create table 유저 {순서 인덱스 char(7), 아이디 char(10), 패스워드 char(15)};  


  이 문장은 학생이라는 테이블에 어떤 속성(순서 인덱스, 이름, 집전화)가 있으며, 각 속성의 자료형(data type)가 무엇인지만 나타낸다. 다시 말하면 테이블의 틀(=뼈대)을 나타낼 뿐, 그 테이블 안에 어떤 자료가 실제로 들어있고 어떤 식으로 데이터베이스의 로직이 이루어지는지는 알수가 없다.

  이처럼 테이블에 있어서 속성 이름과 자료형 등에 관하여 규정하는 것을 관계(=관계)의 스키마라고 한다. 위의 create table라는 SQL 명령은 학생이라는 테이블(=관계)의 스키마를 만드는 명령이다.

  위에 설명한 단어의 원론적인 설명과 다르게 데이터베이스에서 스키마(SCHEMA)는, 틀, 뼈대 등의 뜻이 있으며 보통 한글로 옮기지 않고 스키마라는 용어를 그대로 사용한다.

  데이터 베이스는 일반적으로 도표형식으로 내용을 볼 수 있는데.


  유저   순서인덱스    아이디    패스워드

0000000001   ID1        23451123

00000000012   ID2       123456

  

  이런식으로 어떤 특정 시점에 테이블 안에 있는 구체적인 값의 집합을 관계(=테이블)의 인스턴스라고 한다.


  그런데 일반적으로 테이블의 스키마는 처음 만들 때 잘 생각해서 만들기 때문에, 일단 스키마를 한번 만들면 잘 바꾸지 않는다. 거기에 비해서 테이블의 인스턴스는 상대적으로 스키마보다는 많이 바귀게 된다.


일단 스키마가 바뀌는 경우를 보도록 하자. 


• 현재 있는 학번, 이름, 집전화 속성 가운데 어떤 속성을 빼기 . 

보기 . 패스워드를 뺀다


  create table 유저 {순서 인덱스 char(7), 아이디 char(10)};  


·현재 없는 속성을 더 넣기 . 

보기 : 보유 캐릭터 개수를 더 넣는다


  create table 유저 {순서 인덱스 char(7), 아이디 char(10), 패스워드 char(15), 보유 캐릭터 개수 int };  


휴대전화 char(15)); 


• 속성의 자료형을 바꾼다, 

보기: 패스우드의 자료형을 char(15) 에서 char(20) 로 바꾸었다. 


  create table 유저 {순서 인덱스 char(7), 아이디 char(10), 패스워드 char(20), 보유 캐릭터 개수 int };  


  당연히 데이터 베이스의 테이블이 많아질수록 수많은 유저들의 정보가 통채로 입력되므로 그에 맞는 정보를 입력해줘야 한다. 유저수가 많으면 많을 수록 보통 번거로운 것이 아닐 것이다. 거기에 비해서 테이블의 인스턴스는 상대적으로 많이 바뀌지 않는다. 인스턴스가 바뀌는 경우에 대해서 예를 들어본다면


  유저가 한명 추가되어 맨 마지막줄에 새로운 유저가 들어오는 경우.

  혹은 한명의 유저의 패스워드가 변경된 경우.

  이외 등등등.


  과 같은 경우 인스턴스가 바뀌었다고 하는데. 일반적으로 테스블의 한 행이 바뀌거나, 추가되거나, 삭제되면 인스턴스가 바뀐다고 하며 예상해봐서 알겠지만 당연히 인스턴스는 자주 바뀐다.


  자료 모델?


  데이터베이스에서 자료를 나타내는 방식은 여러가지가 있으며, 책에 따라 나누는 기준이나 방법도 다르다. 

  어떻게 나누냐는 덮어 두고 실제 쓰여졌던 데이터 베이스의 모델들에 대해서 알아보겠다.


  개체 - 관계모델(E-R : entity - relationship model)

  개체 - 관계 모델은 데이터베이스 설계(data base design) 때 많이 쓰인다. 그렇지만 개체 - 관계 모델에 따른 데이터 베이스 관리 시스템 프로그램이 개발되어 있지 않기 때문에, 실제 자료를 처리하기 위하여 우리가 개체 - 관계 모델을 쓰지는 않는다.

   개체 관계 모델은 실제 세계에 대한 인식을 바탕으로 한다 객체지향프로그래밍과 닮은 방향성을 가지고 있어 보인다. 이 모델은 첫째, 개체(entity), 둘째 개체와 개체 사이의 관계(relationship), 이 두가지를 기본으로 하고 있어서 개체 - 관계 모델이라고 부른다.

  개체란, 학생, 과목, 은행 계정, 회사 등과같이 실제 세상에 있는 객체를 가리키며, 각 객체는 다른 객체와 구별된다. 개체는 하나 또는 여러개의 속성으로 나타내게 된다. 유저를 패스워드 순서 인덱스 아이디라고 나눈 것과 같다.

  이에 쓰이는 용어는 개체 집합, 관계 집합, 개체 사이의 사상(=매핑) 크기(mapping cardinality) 제약, 개체 - 관계 모델 그림 (diagram) 등이 있다.

  

  객체지향 모델(OO model, object - oriented model)

  객체지향 모델은 개체-관계 모델을 수용하고 거기에 실행할 수 있는 프로그램까지 모두 포함한다.


  관계형 모델 (relational model)


  관계형 모델은 오늘날 가장 널리 쓰이고 있는 관계형 데이터베이스의 바탕이 되는 모델이다.

  자료(data)를 나타낼 때, 그리고 자료사이의 관계(relationship)를 나타낼 때 모두 관계(relation, 또는 테이블 : table, 표)를 쓰기 때문에, 관계형 모델이라고 부른다. 관계형 데이터베이스는 1970 년대에 연구가 시작되어 오늘날 가장 널리 쓰고 있다.


  네트웍 모델(network model)

  관계형 모델이 나오기 전에, 네트웍 모델에 바탕을 둔 사용 프로그램을 1960년대 후반부터 썼지만, 요즘은 이 모델을 사용하여 제작되는 데이터 베이스는 거의 없다.


  계층적 모델(hierarchical model)

  관계형 모델이 나오기 전에 계층적 모델에 바탕을 둔 사용 프로그램을 1960년대 후반부터 썼지만, 요즘 새로만들 때 역시나 이 모델을 쓰는 곳은 거의 없다.












Posted by JJOREG

데이터 베이스(DATABASE)란?

  자료를 많이! 모은것!

  하지만 자료라고 해서 아무런 연관없는 자료를 그냥 모으면 그건 유용하지 않다.

  데이터 베이스에 있는 자료는 서로 연관성이 있는 자료들이어야 한다. 

  게임이라면 플레이어 데이터 플레이어 아이템 유저 패스워드 같은 식으로 데이터를 연관시켜 모아놓은 것을 의미한다.


데이터 베이스 관리시스템(DBMS : DATABASE MANAGEMENT SYSTEM)

  데이터 베이스와 더불어 많이 쓰이는 용어로 데이터 베이스 관리 시스템이라는 용어가 있다. 데이터베이스와 데이터 베이스 관리 시스템은 다른 개념을 가리킨다.

  DB는 말그대로 데이터의 집합 DBMS는 그것을 편하게 관리하기 위한 시스템이다.


  심플하게 설명하면다음과 같다.

  DB는 창고다. 

  DBMS는 그곳에서 일하는 사람들

  창고는 그 자체로 그냥 물건을 보관하고 물건을 정리하고 빼고 추가하고 하는 일을 하는 것은 창고에서 일하는 사람들이 하는 일이다.


응용(또는 사용자) 프로그램(DBMS : DATABASE MANAGEMENT SYSTEM)

  그런데 각 기관에서 데이터베이스를 관리하려면 데이터베이스 관리 시스템에 있는 프로그램을 활용하여, 그 프로그램등에 맞춰서 또다른 관리 프로그램을 만들어야 한다.

  게임을 생각해보면 유저 패스워드가 있고 그 데이터를 넣고 뺄 수 있는 DBMS가 있다고 해서 유저패스워드를 통한 로그인 시스템까지 지원해주는 것은 아니다.

  그것은 또 우리가 만들어야 한다. 이를 사용자 프로그램이라고 한다.


데이터 베이스 시스템이 파일관리보다 좋은 점.

  컴퓨터가 처음 나왔을 때는 운영체제 개념이 나오면서 파일 체제 개념도 따라서 나오게 되었다. 그런데 파일체제 많으로는 복잡한 일을 하는데 어려움이 있었다.

  그런 상황에서 거대한 데이터를 파일처리 시스템만으로 관리하지 못하므로 그를 지원하는 기능을 갖춘 DBMS가 1960대 부터 등장하기 시작했다.

  오늘날 많이 쓰고 있는 관계형(relational) 데이터베이스는 1970년대부터 나오기 시작하였다.

  그럼 파일 처리와 데이터베이스 시스템의 차이에 대해서 본격적으로 알아보자.


  1) 자료의 중복(data redundancy)와 자료의 불일치(data inconsistency)

  파일 처리 접근 방식을 쓰면, 꼭 같은 정보가 여러군데 되불이 될 수 있다. 보기를 들어 게임에서 아이템데이터가 변경되었다고 치자. 그런데 유저 아이템데이터는 유저의 세이브파일에도 들어 있고 게임의 로직 아이템파일에도 들어있으며, 각 NPC데이터 파일에도 들어있다. 그럼 결국 세가지 파일을 다 바꿔야 할것이다. 만약 하나라도 이 데이터가 바뀌게 된다면 세개의 파일을 모두 바꿔줘야 한다. 혹은 그러다 어떤 파일을 바꾸지 못하는 경우가 생기는데 이런경우 자료 불일치라고 한다.

  또한 파일로 관리할시 이렇게 세개의 파일이 모두 아이템 데이터를 가지는 경우가 생기는데 이는 같은 자료를 중복적으로 가지게 되는 경우이다.


  2) 자료처리의 불편함.

  파일 처리 접근 방식은 보통 고급언어에서 응용프로그램을 짜야하는데 이는 고급언어에 대한 훈련이 필요하다. 그런데 데이터베이스는 거진 공통적인 명령을 사용하고 고급 프로그래밍 언어보다 데이터를 처리하는데 필수적인 기능만을 모아놓았다. 프로그래밍언어로 파일안의 데이터를 처리하기 위한 명령어는 복잡하거나 상황이나 언어 플랫폼에 따라서 달라지는 반면 데이터베이스는 훨씬 편하게 사용이 가능하다.


  3) 자료의 고립(data isolation) 문제

  게임 아이템을 모아놓은 아이템데이터 NPC의 능력을 모아놓은 파일 월드세팅 파일 등이 따로 존재하는데 이를 모아서 세이브파일을 만든다고 치면 같은 자료가 3개의 파일에 따로 생기는 것이다. 그 결과 자료 불일치가 생기는 경우가 생긴다.

  
  4) 자료의 무결성(data integrity)

  자료의 무결성이란 자료에 잘못이 없어야 한다는 것을 말하는데, 자료의 불일치를 포함하여 여러가지 경우에 자료의 무결성이 깨질 수 있다.

  책에 따라서 자료의 불일치와 자료의 무결성에 풀이가 다를수 있는데 일반적으로 자료의 불일치는 자료의 무결성을 깨게 된다. 하지만 자료의 불일치가 아니더라도 자료의 무결성을 깨는 경우가 많다. 

  예를 들어 자료의 불일치와 다르게 게임의 퀘스트데이터파일은 한군데에만 저장되어 있더라도 그것을 처리하는 응용프로그램의 로직이 내부응용프로그램에서 다섯군대가 있다고 친다면 그 로직들마다 자료의 무결성을 보장하는 코드를 짜야 한다 또한 퀘스트파일이 변경된다면 그것을 처리하던 다섯개의 로직에서 그에 대한 예외처리를 모조리 해줘야 한다.

  예를 들면 이런것이다. 퀘스트 파일안에 퀘스트가 해결되었다면 0 퀘스트가 진행중이라면 1 퀘스트를 완료했다면 2라고 정했다. 그런데 갑자기 분기 퀘스트가 생기면서 1000의 자리는 퀘스트 실행중 뒤의 3자리를 분기가 생기는 퀘스트의 번호를 표기하기로 했다 1001 이런식으로 말이다. 이제부터 퀘스트 내부내용 데이터는 무조건 4자리의 정수여야 한다.

  그렇다면 결국 다섯개의 로직을 모두 그에 맞춰서 변경해야 한다 하지만 데이터 베이스에서는 무를 위한 제약을 한곳에서만 처리해주면 된다.


  5) 원자성(atomicity)

  플레이어가 NPC와 거래를 하면 게임은 다음과 같은 처리를 거친다.

  0. 플레이어의 아이템을 건네줄 수 있는지 확인

  1. 플레이어의 아이템 데이터를 삭제.

  2. 플레이어의 아이템 데이터 저장.

  3. NPC의 아이템 데이터 를 수정.

  4. NPC의 아이템 데이터 저장.

  그런데 게임 도중 3번 까지만 처리하고 갑자기 정전이 되어 게임이 종료가 됬다고 치자.

  다시 와보니 플레이어의 아이템만 사라지고 NPC는 아무런 변화가 없다. 퀘스트 아이템 이었는데!

  하지만 데이터 베이스에서는 트레젝션(=거래, transaction)이라는 개념을 도입하여 다음과 같은 과정이 생기지 않도록 한다.


  6) 동시접근 문제(concurrent acces anomalies)

  어떤 파일을 동시에 2개의 게임 쓰레드에서 수정하려고 한다면 파일 처리 방식에서는 자료의 값이 잘못 될수가 있다.

  하지만 데이터 베이스에서는 동시 접근 제어(concurrency control) 기능이 있어서, 동시접근 하면 순서를 지켜서 처리하도록 보장한다.


  7) 보안문제(security problems)

  파일처리 접근 방식에서는 자료에 대한 보안에 어려움이 있다 수많은 에디터를 통해서 파일을 에디팅하는 모습을 볼 수 있을 것이다. 하지만 서버와 DB를 통한 관리는 자료를 모두 한군데에 저장하고 사용자의 권한등을 자세히 정함으로서 자료의 보안을 쉽게 유지할 수 있다.

Posted by JJOREG

  프로그래밍 설계적인 부분이지만 어찌보면 기획적인 부분과도 연계된다.

  예를 들자면 이런 것이다.


  게임을 개발하는데 아이템 인벤토리 기능을 만들게 되었다.

  그럼 다음과 같은 스토리를 생각해야 합니다.


  사용자 스토리


  1. 사용자가 인벤토리를 열었을때 정수 X 정수 만큼의 아이템아이콘이 뜬다.

  2. 사용자가 인벤토리에서 아이콘을 클릭해서 빈공간으로 옮겨놓으면 순서에 상관없이 옮겨진다.

  3. 사용자가 아이템아이콘을 클릭하여 다른 아이콘으로 옮겨넣으면 인벤토리 안에서 아이템의 순서가 변경된다.

  4. 사용자가 정렬 기능을 누르면 아이템의 이름순으로 아이템이 정렬 된다.

  5. 사용자가 인벤 바깥으로 아이템아이콘을 놓으면 아이템 버리기 창이 나온다.

  6. 이외 등등....


  말그대로 사용자의 입장에서 인벤토리를 어떻게 사용할가에 대한 스토리를 작성하면 되는 것이죠.


  이런 사용자 스토리를 정할때 권장되는 개념적인 조건들이 몇가지 있습니다.

  1. 독립적인 Independent

  2. 절충 가능한 Negotiable

  3. 가치 있는 Valuable

  4. 예상 가능한 Estimable

  5. 간단한 Small

  6. 테스트 가능한 Testable

  첫글자만 따보면


  INVEST -> 투자가 됩니다.


  유즈 케이스는 액터가 달성하고자 하는 목적을 설명하는 내용을 담는 것을 말합니다. 

  액터는 시스템 외부에 존재하는 엔티티로 사람이나 장치 또는 다른 소프트웨어와 같이 상호작용을 시작하는 단위를 의미합니다.


  1. 사용자가 인벤토리 버튼을 누른다.

  2. 사용자의 아이템데이터를 기반으로 인벤토리 UI에 아이템이 배열된 상태로 디스플레이 된다.

  3. 사용자가 아이콘을 조작할 수 있다.

  4. 아이콘의 조작에 따라서 몇가지 아이템데이터의 이동 삭제 분류 등이 일어난다.

  5. 인벤토리 시스템은 자신을 통해서 펼쳐지는 동작을 서버에 보고하여 플레이어 아이템의 변경을 통보한다.


  이렇게 간단하게 표현할수도 있고 UML 유즈 케이스 다이어 그램 처럼 시각적인 표현을 사용할수도 있습니다.

  유즈케이스 템플릿등으로 표현할수도 있습니다. 유즈캐케이스 템플릿은 이렇습니다.


  이름 : 인벤토리 시스템

  버전 : 1.0

  설명 : 인벤토리를 통해서 사용자가 자신의 아이템을 조작할수 있다.

  목표 : 아이템을 버리거나 아이템 교체 아이템 정렬 등의 기능을 수행한다.

  결과 소유자

  1. 유저들은 자신이 현재 소유하거나 획득한 아이템을 볼 수 있다.

  2. 쓸모없는 아이템을 버리거나 우선순위에 따라 재배열 할수 있다.

  기본 과정

  1. 인벤토리를 통해서 아이템아이콘들을 인벤토리에 담아서 보여준다.

  2. 아이템 아이콘을 클릭 & 드래그하여 인벤토리 내부에서 조작할수있다.

  확장

  a. 아이템 아이콘을 서로 교체하면 순서가 변경된다.

    a-1. 빈공간은 빈공간 아이템아이콘으로 판단하고 서로 교체된다.

    a-2. 아이템 아이콘끼리의 교환이 있을 수 있다.

  b. 아이템 아이콘을 인벤 토리 바깥에 드랍하면 아이템을 버리게 된다

    b-1. 아이템을 실제로 버리겠냐는 메세지를 출력한다.

    b-2. 아이템의 종류에 따라서 버릴수 없는 아이템이 존재하면 아이템을 버릴수 없다는 메세지를 출력한다.

  트리거 

    인벤토리 열기 키를 누른다.

  후속조건

    없음.

   

'게임개발공부 > 프로그래밍의 의견들' 카테고리의 다른 글

프로그래밍 설계상의 부채  (0) 2014.07.29
밸런싱 관련 의견.  (0) 2014.01.11
소프트웨어 개발 프로세스 모델.  (0) 2014.01.09
의견 1  (0) 2013.11.27
Posted by JJOREG

처음 코드를 작성하는 것은 빚을 지는 것과 같다. 그리고 코드를 개선하는 것은 빚을 갚는 활동이다. 

약간의 빚을 지고 있는 동안에는 빚을 갚기 위한 개발이 가속화된다.

진정한 위험은 채무가 상황되지 않을 때 발생한다. 올바르지 않는 코드에 시간을 쏟는 일은 빚에 이자를 더하는 것이다.

완성도 낮은 코드로 인해 전체 엔지니어링 조직은 빚더미에 쌓인다.


문제는 거의 언제나 항상 제품 출시일 때문에 발생한다. 

다시 돌아가서 문제를 해결할 시간이 없다는 말이 있듯이 출시를 위해서 당분간 필요한 코드를 이리저리 조금씩 붙여 나가다가 어늗덧 감당할수 없게 된다.


프로그램이 빚더미에 앉았을 때 다음과 같은 징후가 발견된다.


취약성 

시스템의 내부로직과 의존할 뿐 누가 봐도 관련 없어 보이는 부분의 상세 구현 내용이 노출되거나 예상치 못한 부작용이 발생할 때 취약점이 느러나며 그 결과 코드를 변경할 때는 연관성이 없어 보이는 코드에서 사이드 이펙트가 발생한다.


경직성

유연하지 못한 소프트웨어는 변화에 큰 걸림돌이다. 실제로 잘못된 설계로 인해 작은 코드 변경에도 많은 노력이 필요하며, 보통은 비싼 비용이나 많은 시간, 위험 부담이 높은 리팩토링 등이 발생하기 때문에 새로운 변경을 위한 노력은 한없이 늦춰진다.


부동성

유능한 엔지니어는 소프트웨어를 안정적이고 유지보수도 쉽게 만들기 위해서 코드를 재사용 할수 있는 부분들을 먼저 찾는다. 하지만 이러한 노력도 특정 상황에만 해당되서 그 외에 재사용 할 수 없는 코드를 만나면 그 노력은 무용지물이 되고 만다. 주변 코드와 딱 달라 붙어서 아주 밀접한 관계를 맺는 코드를 구현한다거나 아니면 특정 도메인에 한정된 로직을 하드코딩하는 경우가 여기에 속한다.


비 이동성

팀원 중 딱 한명의 엔지니어만이 시스템의 특정 부분을 감당 할 수 있는 경우를 일컬어 비 이동성이라고 한다. 어떤 업무를 담당하는 사람은 그 기능을 처음 개발한 개발자이거나 불행히도 그 코드를 좀더 개선하고자 시도했던 사람 일수도 있다. 수많은 대규모 프로젝트에서는 모든 엔지니어가 프로젝트 전체를 구체적으로 이해한다는 것은 불가능 하지만 그렇다고 다른 개발자가 쉽게 코드를 이해하지 못하거나 효과적으로 요구사항을 반영하지 못하도록 영역을 나누는 것도 프로젝트에 결코 도움이 되지 않는다.

'게임개발공부 > 프로그래밍의 의견들' 카테고리의 다른 글

사용자 스토리 & 유즈 케이스  (0) 2014.07.30
밸런싱 관련 의견.  (0) 2014.01.11
소프트웨어 개발 프로세스 모델.  (0) 2014.01.09
의견 1  (0) 2013.11.27
Posted by JJOREG
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <d3d9.h>
#include <d3dx9.h>
#include <algorithm>
#include <iostream>
 
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
 
using namespace std;
 
float myVec3Length(D3DXVECTOR3* pSrcVec)
{
    float TempLength = 0.0f;
    //pSrcVec->
 
    TempLength = sqrt(pSrcVec->x * pSrcVec->x + pSrcVec->y * pSrcVec->y + pSrcVec->z * pSrcVec->z);
 
    return TempLength;
}
 
int _tmain(int argc, _TCHAR* argv[])
{
    D3DXVECTOR3 LenVector = D3DXVECTOR3(1, 2, 3);
 
    cout << LenVector.x << LenVector.y << LenVector.z << endl;
    cout << D3DXVec3Length(&LenVector) << endl;
    cout << myVec3Length(&LenVector) << endl;
 
    return 0;
}

 

벡터계산중 길이와 정규화 함수를 만들어 보았다.

 

 

Posted by JJOREG