DB 튜닝 - INDEX 제대로 사용하기

개발 노트 2009. 5. 18. 13:15 posted by 무병장수권력자


DB에서 INDEX 제대로 사용하기

작성자 : 김문규
최초 작성일 : 2009.5.18

데브피아에서 기가 막히게 좋은 전문가 글을 찾았습니다. 간단하게 정리해 봅니다.

인덱스를 사용하기를 기대하지만 그렇지 않은 기본적이고 대표적인 예입니다.

1. 인덱스 컬럼을 변형하여 비교할 때
BAD
WHERE TO_CHAR(HIREDATE,'YYYYMMDD') = '19980518';
GOOD
WHERE HIREDATE = TO_DATE('19980518')

BAD
WHERE SALARY + 1000 > 100000;
GOOD
WHERE SALARY > 100000 - 1000;

비교하는 인덱스 컬럼의 형이나 값을 변경하면 발생합니다.
이 경우에는 비교값을 변경해 주어야 인덱스를 사용하게 됩니다.

2. 비교 대상의 형이 달라서 내부적으로 형변환을 하는 경우
BAD
WHERE EMP_ID = 200383;
GOOD
WHERE EMP_ID = ‘200383’;

EMP_ID가varchar라고 할 경우에 비교값이 숫자인 경우에 DB에서 자동으로 이를 숫자로 변경하고 비교하게 됩니다. 이 경우에 인덱스 컬럼에 변형이 일어났기 때문에 인덱스를 사용하지 못하게 됩니다.

3. NULL을 비교하는 경우
BAD
WHERE JOB IS NULL;

일반적으로 Oracle을 기준으로 NULL은 인덱스 대상이 아니라고 합니다. 따라서, 이를 해결하기 위해서는 NULL을 쓰지 말고 다른 정해진 값을 이용해서 비교해야 합니다. (흠..이건 좀...)

4. 부정형 조건인 경우
BAD
WHERE JOB NOT IN ( 'INSTRUCTOR','STAFF');

부정형 역시 인덱스를 사용하지 못하는 대표적인 조건 쿼리 입니다. 아닌 놈을 찾으려면 전체를 뒤지는 수 밖에요. 이를 피하기 위한 근본적인 DB 모델링이 중요합니다.


이하 원문을 그대로 가져다 붙입니다. 추가 설명이 필요하면 읽어 보세요.
http://www.devpia.com/DevStudy/Lecture/OffLineDetail.aspx?nSemiID=1429&lectype=evt

필자가 처음에 SQL을 배울 때 SQL이 상당히 이상했다. 원하는 것만 요구할 뿐 어떻게 가져오라는 정보가 SQL에는 없었기 때문이다. FILE레벨의 I/O까지 코딩에 익숙한 필자에게 절차가 없다는 것이 오희려 더 이상했던 것이다.
물론 상세한 과정이 필요하지 않으므로 편리하고 좋았다 그러나 어떻게 가져오는지는 알지못하고 단지 사용할 뿐이었다.
그러나 SQL이 PLAN이라는 실행 계획을 만들고 그에 따라 가져오게 된다는 사실은 안것은 한참 뒤에 일이었다.
저자소개: 유원석
(現) (주)위즈베이스 컨설팅본부 수석컨설턴트
프로젝트 :
ㆍ하나투어 DB아키텍터
ㆍSK Telecom NGM Project 시스템 성능관리자
ㆍKT EDW Projec Main Architect 수행
ㆍLG 전자 Eagle Project 시스템 성능 개선 등
강 의 :
ㆍ한국썬마이크로시스템즈 대용량데이터베이스
ㆍ한국썬마이크로시스템즈 Orange를 이용한 DB튜닝
결국은 내가 하지않은 일을 Optimizer라는 프로그램이 대신 해주고 있는 것이 아닌가? 그래서 정말 고마운 놈이라고 생각했었다. 그러나 밑는 도끼에 발등을 찍힌다는 말이 있지 않은가?
Plan에 index를 달아주어도 Index를 사용하지 않고 full table scan만 하고 있으니 당체 속도가 나지를 않았다.
이래저래 해서 나중에 알게되었지만 결국 컬럼의 변형을 가하면 index를 사용하지 못한다는 것이다. 우리가 직접 사용하지는 않지만 결국 우리가 SQL을 사용한다는 것은 Optimizer라는 놈에게 SQL의 수행을 부탁하는 것이다. 따라서 우리가 Optimizer에 대해서 잘 안다면 SQL을 좀더 효율적으로 수행하도록 할 수 있지 않은가!
그러면 인덱스를 달았을 때 Optimizer가 index를 사용하지 못하는 경우를 통해서 우리가 애써(?)생성한 인덱시가 무용지물이 되지 않도록 해보자.
아래예제에 사용할 TABLE LAYOUT이다.
EMPLOYEES
---------
Rows=15,132
Empty Blocks=7
Chain Count=0
Avg Space Freelist Blocks=0
Sample Size=15,132
Partitioned=NO

Blocks=121
Avg Space=885
Avg Row Length=51
Freelist Blocks=0
Last Analyze=2009/05/04
Column Name
---------------
EMP_ID
MGR_ID
LAST_NAME
FIRST_NAME
HIREDATE
JOB
SALARY

Nullable
-----------------


NOT NULL
Column Type
-----------------
VARCHAR2(40)
VARCHAR2(40)
VARCHAR2(24)
VARCHAR2(14)
DATE
VARCHAR2(24)
NUMBER(7,2)
Distinct
-----------------
15,132
679
9,443
3,579
3,903
53
3,267
Buckets
------------------
75
75
75
75
75
53
75
INDEX
--------------------------------------------------------------------------------------
IDX_GENDER : GENDER
      Type=NORMAL, Uniq=No, Distinct=2, Rows=15,132, Last Analyze=2009/05/04
IDX_HIREDAT : HIREDATE
      Type=NORMAL, Uniq=No, Distinct=3,903, Rows=15,132, Last Analyze=2009/05/04
IDX_JOB : JOB
      Type=NORMAL, Uniq=No, Distinct=53, Rows=15,129, Last Analyze=2009/05/04
IDX_SALARY : SALARY
      Type=NORMAL, Uniq=No, Distinct=3,267, Rows=15,132, Last Analyze=2009/05/04
IDX_TYPE2 : TYPE
      Type=NORMAL, Uniq=No, Distinct=6, Rows=15,132, Last Analyze=2009/05/04
PK_EMP_ID : EMP_ID
      Type=NORMAL, Uniq=No, Distinct=15,132, Rows=15,132, Last Analyze=2009/05/04
필자가 여러군데 튜닝을 하면서 가장 많이 본것중에 하나는 INDEX를 달았으나 쓰지 못하게 되는 경우이다. 대표적인 경우가 아래와 같이 날짜타입(HIREDATE)에 TO_CHAR를 씌운 경우이다.
SELECT FIRST_NAME, LAST_NAME
FROM EMPLOYEES
WHERE TO_CHAR(HIREDATE,'YYYYMMDD') = '19980518';
물론 INDEX는 아래와 같이 생성되어있다.
CREATE INDEX IDX_HIREDATE ON EMPLOYEES(HIREDATE);
우리가 원하는 것은 INDEX를 타고 테이블을 가져오기를 바란것이었다.

그러나 실제 PLAN은 아래와 같이 나온다.
Execution Plan
--------------------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=28 Card=151 Bytes=3K)
1 0 TABLE ACCESS (FULL) OF 'EMPLOYEES' (TABLE) (Cost=28 Card=151 Bytes=3K)
TABLE ACCESS (FULL) 이란 뜻은 INDEX를 타지 않고 테이블을 처음부터 끝까지 읽어서 찾는다는 뜻이다. 한마디로 10건이며 10건읽고 100만건이면 100만건을 다 읽어야 결과가 나온다는 말이다.

OPEN시에는 빠르던 시스템이 시간이 지날수록 느려지는 결정적인 역할을 하는 것이 바로 위와 같은 경우이다. 그럼 어떻게 해야 제대로 인덱스를 사용할 수 있을가?
일단 간단히 SQL의 수정으로 해결할수 있다. HIREDATE는 날짜 타입이다.
따라서 인덱스를 HIREDATE로 했을 때 인덱스를 타기위해서는 INDEX를 생성한것에 변형을 주어서는 안된다.
SELECT FIRST_NAME, LAST_NAME
FROM EMPLOYEES
WHERE HIREDATE = TO_DATE('19980518')
따라서 간단하게 위와 같이 고치면 INDEX를 사용하게된다.
Execution Plan
--------------------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=3 Card=4 Bytes=92)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'EMPLOYEES' (TABLE) (Cost=3 Card=4 Bytes=92)
2 1 INDEX (RANGE SCAN) OF 'IDX_HIREDATE' (INDEX) (Cost=1 Card=4)
물론 결과도 빠르게 나온다 그러나 중요한 점이 있다 결과가 같을까?
운이 좋으면 결과가 같을 것이고 대부분의 경우는 결과가 틀리다.
왜 그럴까?
날짜 타입은 날짜와 시분초의 정보도 가지고 있다. 따라서 TO_DATE(‘19980518’)라는 말은 정확히 1998년5월18일 0시0분0초라는 뜻이다. 그래서 우리가 원하는 1998년5월18일자와는 차이가 있다.
따라서 1998년5월18일 0시0분1초 ~ 23시59분59초까지의 데이터는 나오지 않게되는것이다.
이것은 튜닝할 때 유의할 점이다. 결과를 같게 유지해야하는것이다. 이 상황을 알고있다면 방법은 간단하다.
아래아 같이 고치면 빠른시간에 원하는 결과를 얻을 수 있을 것이다.
SELECT FIRST_NAME, LAST_NAME
FROM EMPLOYEES
WHERE HIREDATE BETWEEN TO_DATE('19980518'||'00:00:00','YYYYMMDD HH24:MI:SS')
AND TO_DATE('19980518'||'23:59:59','YYYYMMDD HH24:MI:SS')
비슷하지만 함수의한 변형이 아닌 간단한 연산에의한 변형의 경우도 마찬가지이다.
$1000의 인센티브를 더주면 $10000이 넘는 사람을 찾는 SQL을 만들어보자.
아마 아래와 같을 것이다.
SELECT FIRST_NAME, LAST_NAME
FROM EMPLOYEES
WHERE SALARY + 1000 > 100000;
물론 INDEX는 아래와 같이 만들었다.
CREATE INDEX IDX_SALARY ON EMPLOYEES(SALARY);
그러나 PLAN을 보자
Execution Plan
--------------------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=29 Card=757 Bytes=13K)
1 0 TABLE ACCESS (FULL) OF 'EMPLOYEES' (TABLE) (Cost=29 Card=757 Bytes=13K)
인데스를 타지 못한다. 왜일까. 간단한 연산이지만 SALARY컬럼에 가공을 했기 때문에 OPTIMIZER는 인덱스를 타는 것을 포기해버린다.
따라서 우리가 기초적인 수학 실력을 발휘해서 이항을 해준다면 아래와 같은 조건이 될것이다.
SELECT FIRST_NAME, LAST_NAME
FROM EMPLOYEES
WHERE SALARY > 100000 - 1000;
이경우에 PLAN을 보자.
Execution Plan
--------------------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=3 Card=1 Bytes=17)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'EMPLOYEES' (TABLE) (Cost=3 Card=1 Bytes=17)
2 1 INDEX (RANGE SCAN) OF 'IDX_SALARY' (INDEX) (Cost=2 Card=1)
재미 있게도 이번에 제대로 된 인덱스를 탄다. Optimizer가 바보 같다는 생각이 들지 않는가?
물론 바보같다. 그러나 OPTIMIZER나름대로 깊은 고민이 있다. 아주 잛은 시간내에 OPTIMIZER는 많은 경우의 수를 타진해야한다. 따라서 이항연산과 같은 것 까지 검토하면 너무 많은 시간을 소모하게 된다 따라서 그런부분은 포기한것이다.

또다른 경우중에 하나가 DB의 내부적인 변형이다. 이는 개발자가 의도하지 않게 문제를 야기하는 경우이다.
여기 PK 조건으로 검색하는 SQL이 있다.
SELECT LAST_NAME,FIRST_NAME
FROM EMPLOYEES
WHERE EMP_ID = 200383;
그러나 PLAN은 아래와 같이 나왔다.
Execution Plan
--------------------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=29 Card=1 Bytes=19)
1 0 TABLE ACCESS (FULL) OF 'EMPLOYEES' (TABLE) (Cost=29 Card=1 Bytes=19)
분명히 아래와 같은 INDEX를 생성하였다.
CREATE INDEX PK_EMP_ID ON EMPLOYEES(EMP_ID);
왜 인덱스를 안타는 것일까?
그 이유은 OPTIMIZER의 내부 변형 규칙에 있다.
일반적으로 비교를 하려면 두개의 데이터 형이 같아야 한다.
그런데 EMP_ID는 VARCHAR2(40)이다 그리고 비교하려는 것은 200383이라는 숫자이다.
따라서 숫자와 문자는 비교할수 없기 때문에 내부적으로 변형이 이루어진다.
문자보다 숫자가 우선순위가 높아서 문자와 숫자를 비교하게되면 문자쪽이 숫자로 변형되어 비교하게 되는 것이다.
따라서 위의 SQL은 OPTIMIZER는 아래와 같은 SQL로 수행하게된다.
EMP_ID를 TO_NUMBER(EMP_ID) = 2000393과 같이 처리하게 된다.
SELECT LAST_NAME,FIRST_NAME
FROM EMPLOYEES
WHERE TO_NUMBER(EMP_ID) = 200383;
이는 처음 예제에서 날짜 컬럼에 TO_CHAR를 씌원것과 같은 효과이다. 따라서 이문제를 해결하기위해서는 반대쪽, 즉 2000293을 문자로 변환해주면 문자대 문자의 비교이므로 내부적 변형이 발생하지 않게된다.
SELECT LAST_NAME,FIRST_NAME
FROM EMPLOYEES
WHERE EMP_ID = ‘200383’;
 
Execution Plan
--------------------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=2 Card=1 Bytes=19)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'EMPLOYEES' (TABLE) (Cost=2 Card=1 Bytes=19)
2 1 INDEX (RANGE SCAN) OF 'PK_EMP_ID' (INDEX) (Cost=1 Card=1)
아래 SQL을 보자 JOB에 NULL인 조건을 검색하는 것이다.
SELECT LAST_NAME,FIRST_NAME
FROM EMPLOYEES
WHERE JOB IS NULL
아래 SQL을 보자 JOB이 NULL인 조건을 검색하는 것이다.
물론 아래와 같은 JOB INDEX를 생성하였다.
CREATE INDEX IDX_JOB ON EMPLOYEES (JOB);
아래 PLAN을 보자 왜 IDX_JOB INDEX를 타지 못하는가?
Execution Plan
--------------------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=29 Card=3 Bytes=63)
1 0 TABLE ACCESS (FULL) OF 'EMPLOYEES' (TABLE) (Cost=29 Card=3 Bytes=63)
이경우에는 Oracle의 경우 일반적으로 index를 생성할 때 null값은 index항목에 넣지 않는다. 따라서 null은 index에 없기 때문에 null조건을 준다면 그것은 index를 탈수 없다.
따라서 위와 같은 경우 반드시 index를 타려거든 job컬럼을 NOT NULL로 설정하고 NUL대신 특정값 (예를 들면 : ‘NOT ASSIGN’ ) 으로 설정하고 QUERY를 아래와 같이 수정한다면 인덱스를 탈수 있을 것이다.
SELECT LAST_NAME,FIRST_NAME
FROM EMPLOYEES
WHERE JOB = ‘NOT ASSIGN’;
아래 SQL를 하나 더 보자
SELECT LAST_NAME,FIRST_NAME
FROM EMPLOYEES
WHERE JOB NOT IN ( 'INSTRUCTOR','STAFF');
이번의 NULL을 비교한것도 아닌데 INDEX를 사용하지 못한다. 이것은 일반적인 INDEX가 =이나 <, > , BETWEEN조건에 만 인덱스를 탈수 있고 부정형으로 비교했을때는 인덱스를 탈수 없기때문이다.
생각해보자 어떤 것을 순서대로 정리해 놓았는데 그것이 아닌 것을 찾으려고 한다면 전체를 다 읽어봐야지만 아니것을 알수 있지 않은가?
따라서 가급적 프로그램 구성에서 부정형 조건이 들어가게 한다는 것은 성능을 저하시킬 가능성이 매우 높기 때문에 이런 조건이 되지 않도록 설계단설계부터 고려해야한다.

이상은 간단하게 INDEX를 주었을 때 일반적으로 INDEX를 타지 못하는 경우를 든것이다. 사실 위예 예처럼 실제 프로젝트에서 많은 부분이 INDEX를 생성하고도 OPTIMIZER의 특성을 몰라서 INDEX를 쓰지 못한채 APPLICATION이 돌고 있다. 이는 곧바로 자원의 과도 사용으로 나타나고 느린 응답시간으로 나타나게 된다. 항상 시스템을 OPEN하고 마음을 조리지 않으려면 내가 생성된 INDEX를 잘 탈수 있게 내가 SQL을 잘 작성했는지 검토해 보기 바란다.
아래 4개의 항목은 반드시 기억해 두기 바란다.
인덱스를 사용하지 못하는 경우는 아래와 같다.
  • 인덱스 컬럼에 변형이 일어난 경우
    • WHERE TO_CHAR(HIREDATE,'YYYYMMDD') = '19980518';
    • WHERE SALARY + 1000 > 100000;
  • 내부적인 변형이 일어난 경우
    • WHERE EMP_ID = 200383;
  • NULL을 비교하였을 경우
    • WHERE JOB IS NULL;
  • 부정형으로 조건을 기술한 경우
    • WHERE JOB NOT IN ( 'INSTRUCTOR','STAFF');

물론 이 경우 이외에 Optimizer의 판단에 따라서 인덱스를 사용하지 못하는 경우도 있다. 그러나 대부분의 경우에는 위에 항목을 만족한다면 원하는 index를 타는 효율적인 sql작성에 좋은 기준이 될것이다. 마지막으로 sql을 작성한후 반드시 plan을 확인해 보기 바란다.
실제 plan이 어떻게 되는냐를 확인해보지 않으면 무심코 과거의 실수를 답습할 수 있기때문이다.

'개발 노트' 카테고리의 다른 글

HSQLDB 사용  (0) 2009.05.26
[C/C++] 변수 선언의 기본  (0) 2009.05.22
파이(pi) 값 계산하기  (2) 2009.05.13
C++ course work  (0) 2009.05.11
Javascript 상속  (0) 2009.05.08


파이(pi) 값 계산하기

개발 노트 2009. 5. 13. 00:02 posted by 무병장수권력자


파이(pi) 값 계산하기

작성자 : 김문규

최초 작성일 : 2009.5.14

SuperPi 라는 프로그램을 많이 보았을 것입니다. PC의 계산 능력을 측정하는 수단으로 종종 사용되고 있습니다. 이 프로그램은 pi값을 계산하는 알고리즘을 수행하는 시간을 측정하는 방식을 사용합니다.
pi는 아시다시피 순환하지 않는 무한 소수이며 이를 계산하는 방법은 무한급수를 이용하는 방법을 비롯하여 몇가지가 있습니다. (수학에 약한지라...자세히는 저도 모릅니다.)
계산할 자리수에 따라서 계산되는 복잡도와 시간이 달라지게 됩니다.

본 포스트에서는 정확하게는 SuperPi는 아니고 이와 유사한 프로그램의 소스를 공유하고자 합니다.
유용하게 사용하시길 바랍니다.


'개발 노트' 카테고리의 다른 글

[C/C++] 변수 선언의 기본  (0) 2009.05.22
DB 튜닝 - INDEX 제대로 사용하기  (1) 2009.05.18
C++ course work  (0) 2009.05.11
Javascript 상속  (0) 2009.05.08
윈도우 탐색기 기본 실행 폴더 위치 변경하기  (0) 2009.04.11


C++ course work

개발 노트 2009. 5. 11. 12:28 posted by 무병장수권력자


정확히 기억나지 않지만 어느 교육기관에서 사용하고 있는 C++ 마스터 코스의 과정 안내입니다.
키워드가 잘 정리되어 있기 때문에 혼자서 정리할 때 참고하면 좋을 듯 합니다.

○ 1주 
C++ 기본코드, C++ 함수의 특징(오버로딩, inline, 디폴트 인자. 함수 template) 
Namespace, reference 
동적 메모리 할당(new/delete), 객체 지향 프로그램의 개념 
생성자, 소멸자, 접근지정자, friend, 갭슐화, 초기화 리스트 
복사생성자(얕은 복사, 깊은 복사, 복사금지, 참조개수) 
Static 멤버, const 멤버함수,멤버 함수 포인터, 멤버를 가르키는 포인터  

○ 2주 
Empty class, nested class, class declaration, Callback 의 개념 
연산자 재정의 개념, +연산자 재정의 Rule, 증가/감소, ostream과 추출연산자, endl 
대입연산자, 변환연산자, 변환 생성자, string class, Reference Counting 
new/delete 재정의, Smart pointer, Iterator의 개념 
상속의 개념, protected, 접근 변경자, 상속에서의 생성자/소멸자 
Function Override , upcasting, binding, 가상함수, 가상소멸자  

○ 3주 
가상함수의 원리, Prototype Pattern, 순수 가상함수와 추상클래스, 인터페이스 개념 
Template Method, Stategy Pattern, Decorator, Composite, Factory, Adapter 
Exception 개념, Exception Safety, Exception Neutral, Stream class 
Advance Template, Traits, Policy, Template Design, Meta Programming  

○ 4주 
STL 원리, Iterator 분류, iterator_traits 
Container Class. Sequence Container, Associative Container, Container Adapter 
Algorithm, TR1과 BOOST 소개 
Boost 활용


 

'개발 노트' 카테고리의 다른 글

DB 튜닝 - INDEX 제대로 사용하기  (1) 2009.05.18
파이(pi) 값 계산하기  (2) 2009.05.13
Javascript 상속  (0) 2009.05.08
윈도우 탐색기 기본 실행 폴더 위치 변경하기  (0) 2009.04.11
XHTML 왜 써야 하나요?  (0) 2009.03.31


Javascript 상속

개발 노트 2009. 5. 8. 16:52 posted by 무병장수권력자



작성자 : 김문규
최초 작성일 : 2009.5.8

Animal 객체를 Dog 객체가 상속하고 이를 사용하는 모습에 대한 예제입니다.

<script type='text/javascript'>       

Animal = function() {
    this.name = "nobody"
    this.speak = function () {
        return "Who am I?"
    }
}
Dog = function() {
  this.speak = function() {
    return "Woof!"
  }
}
Dog.prototype = new Animal();

myAnimal = new Dog();
alert('The animal named ' + myAnimal.name + ' says ' + myAnimal.speak());

</script>





SixthSense - 색다른 미래 인터페이스

MIT Media Lab 2009. 4. 22. 09:21 posted by 무병장수권력자


작성자 : 김문규
최초 작성일 : 2009. 4.22

MIT 미디어 랩에서 색다른 인터페이스를 발표했다고 합니다.

자세한 정보는 아래의 웹페이지를 참조하시면 됩니다.
http://www.pranavmistry.com/projects/sixthsense/

SixthSense는 wearable gestural interface 입니다. 뭐 흔하다면 흔한 증강현실(Augmented Reality) 기술입니다.

근데 이놈 이전 것들과는 좀 다릅니다. 참신한 응용 애플리케이션들을 같이 선보이고 있네요.

카메라, 프로젝터+거울, 손가락을 이용해서 정보와 사람을 인터페이스 합니다. (손가락이 포인팅 디바이스의 역할을 하며, 아직 미완인지 모르지만 색깔로 구분된 마커를 손가락에 부착한 모습입니다.) 물론 이 인터페이스를 통해서 사람의 액션(행동)에 필요한 정보를 빠르고 정확하게 실시간으로 보여줍니다.

그리고, 중요한 가격은 현재 데모 장비는 350$로 구성했다는 군요.
아직 하드웨어 적이나, 조작 측면해서 다소 어색한 면은 있지만 언젠가는 스타트랙, 마이너리티리포트의 세상은 오고야 말 것 같습니다.

너무 맘에 드는 어플리케이션이 많이 있어요.
- 손가락만 모아서 사각형으로 만들면 바로 사진이 찍어 지고 저장되는 것
- 손가락 만으로 전화를 걸 수 있도록 하는 것
- 책을 골랐을 때, 독자 서평을 바로 보여주는 것
- 슈퍼마켓에서 선택한 상품의 정보를 바로 보여주는 것
- 신문의 사진 영역에 동영상을 바로 보여주는 것
- 대화중인 사람의 성향을 나타내는 단어(tag cloud)를 바로 보여주는 것
- 시계가 없어도 손목에 프로젝터 시계를 바로 보여주는 것

이 기술의 핵심은 바로 입니다. 지금도 핸드폰을 열어서 검색한다면 가능하겠지요~ 하지만, 귀찮습니다.

백문이불여일견, 동영상으로 확인하세요.

프리젠테이션


데모 1


스크린샷 1 - 신문의 사진 영역에 최근 동영상을 보여주는 기능



데이터베이스 정규화

데이터베이스 2009. 4. 17. 10:33 posted by 무병장수권력자


데이터베이스 정규화
(Database Normalization)


작성자 : 김문규
최초 작성일 : 2009. 4.16

1. 들어가며
데이터베이스 정규화는 설계된 데이터베이스의 유지와 보수를 위해서 꼭 지켜져야 할 기본 규칙들이 잘 구현되었는 지를 확인하는 과정입니다. 훌륭하지 않은 모델러에 의해 만들어진 모델도 정규화의 과정을 거치면 피해야할 데이터베이스 상의 오류 가능성들이 대부분 사라지게 됩니다.
여기서 중요한 사실은 정규화는 데이터 모델을 검증하는 것이지 모델링의 기술은 아니라는 점입니다. 하지만, 실제로는 정규화에 대해서 잘 이해하고 있다면 이를 고려하여 훌륭한 모델을 도출할 수 있다고 생각됩니다.
정규화의 목적은 데이터베이스 상의 오류인 Anomaly(아노말리)를 제거하는 것입니다. 이를 유발하는 주요 원인은 다음과 같습니다.
. 단일 값이 아닌 속성 (집전화와 휴대전화를 comma(,) 구분자등을 이용해서 넣은 전화번호 속성)
. 다중 의미를 가지는 속성 (학생이면서 교수를 가리키는 학생/교수 속성)
. 파생 속성 ((단가X판매개수)의 의미를 가지는 총판매액 속성)
. 인스턴스의 반복된 출현 (같은 값을 여기 저기에 중복해서 저장하는 경우)

이런 현상들을 제거하기 위해 여러 단계의 정규화 이론이 존재합니다. 뭐 다 알고 다 하면 좋겠지만 통상 3차 정규화까지, 또는 BCNF까지 수행한다고 합니다. 본 포스트의 범위는 3차 정규형까지로 한정하고자 합니다. 나머지는 다음 기회에 다루도록 하겠습니다.

2. 1차 정규형 (1st Normal Form, 1NF)
: 모든 속성을 최소의 의미 단위로 분할함

1차 정규형을 만족시키기 위해서는 Multi-Value Attribute(다중 값 속성)과 Multi-Part Attribute(다중 부분 속성)을 분할해야 합니다. Multi-Value Attribute란, 한 컬럼에 여러개의 값을 복수로 저장한 것 입니다. 아래 예시에 email 컬럼이 이에 해당합니다. Multi-Part Attribute란, 한 컬럼이 여러개의 의미 단위로 이루어진 것 입니다. 아래 예시에서 phoneno 컬럼이 이에 해당합니다. 전화번호는 국번과 그외 번호로 이루어지게 됩니다.

custID name emails phoneno
1 이름1 cus1@email.com;cus1@naver.com;cus1@korea.com 02-123-4567

위 구조의 대표적인 문제는 email을 하나더 추가하려면, email 값을 select한 후 해당 스트링의 뒤에 값을 concatenate한 뒤, 다시 insert를 해야 합니다. 또한 cus1@naver.com 이라는 이메일을 가지는 사용자를 검색하려면 like 검색을 해야 할 뿐 아니라 mcus1@naver.com 이라는 사용자가 있다면 정확하게 검색되지도 않게 됩니다. 전화번호의 경우 국번 정책이 바뀌어서 02에서 01로 바뀌었다고 하며, 현재 테이블 구조에서는 역시 select후 string 변경 후, insert가 일반적인 방법이게 됩니다.

이를 수정하면 다음과 같습니다. (이후에도 계속 말하겠지만, 절대적인 실전 답이 아니라, 해당 정규화를 잘 설명하기 위한 예시임에 주의하세요.)
custID name
1 이름1

custID emails
1 cus1@email.com
1 cus1@naver.com
1 cus1@korea.com

custID phoneno1 phoneno2
1 2 1234567

이렇게 스키마를 변경하면 위에서 언급한 문제들은 더이상 존재하지 않습니다.

3. 2차 정규형 (2nd Normal Form, 2NF)
: 키가 아닌 속성(non key)이 완전하게 함수적 종속

키는 여러개의 속성으로 이루어지는 복합키(합성키)의 형태가 있을 수 있습니다. 이 경우에 모델러의 실수로 두종류의 복합키가 한 테이블에 존재하는 경우에는 일부 속성은 복합키1에 종속되고 나머지는 복합키 2에 종속될 수 있습니다. 이 경우에 해당 속성은 키에 부분적으로 종속되게 됩니다. 2차 정규형은 이를 제거하고자 합니다.

학번 학과명 학과코드 과목번호 학점
1111111 전자공학 1A A111 3.0
2222222 컴퓨터공학 1B B111 4.0
3333333 경제학 2A C111 4.5

이 테이블은 어떤 학생이 어디에 속해있고, 해당 학기 수강과목의 학점이 얼마인지가 저장되어 있는 테이블입니다. 느낌상 학번이 UID인 테이블처럼 보입니다. 과연 그런가요?

실제로는 아래와 같은 테이블일 것입니다.
학번 학과명 학과코드 과목번호 학점
1111111 전자공학 1A A111 3.0
2222222 컴퓨터공학 1B B111 4.0
3333333 경제학 2A C111 4.5
3333333 경제학 2A D111 4.0

이 경우에 테이블의 속성들의 관계를 살펴보면 다음과 같습니다.
학번 -> 학과명, 학과코드
학번,과목번호 -> 학점
즉, 학점이 학번이라는 키에 부분적으로만 종속되어 있습니다.

'학번이 333333인 학생의 학점을 3.5로 낮추어라.' 쿼리가 동작해서는 안됩니다. 과목이 두개이기 때문에 어떤 과목의 학점을 바꾸어야 하는 지 확실하지 않기 때문입니다. 이런 경우를 부분적으로 종속되어 있다고 합니다.

다음과 같이 테이블을 설계하면 부분 종속을 피할 수 있게 됩니다.
학번 학과명 학과코드
1111111 전자공학 1A
2222222 컴퓨터공학 1B
3333333 경제학 2A
3333333 경제학 2A

학번 과목번호 학점
1111111 A111 3.0
2222222 B111 4.0
3333333 C111 4.5
3333333 D111 4.0

위의 두번째 테이블은 복합키가 UID를 구성하는 경우로서 필요에 따라 인조키(artificial key)를 사용하는 것도 좋겠습니다.

4. 3차 정규형 (3rd Normal Form, 3NF)
: 모든 속성은 UID에 직접 종속되어야 함 (이행 종속 제거)

이행 종속(Transitive Dependency)이란 A가 B에 종속되고 B는 다시 C에 종속되는 경우입니다. 관계가 있긴 있는데, 간접적인 관계인 경우를 가리킵니다.

다음의 예를 보면, price는 고객ID에 직접 종속된 값이 아닙니다. 가격은 서비스에 직접적으로 종속되어 있는 속성이고 고객이 특정 서비스를 받기 때문에 특정 price를 지불하는 것입니다. 즉 체인처럼 종속적인 연결되고 있는 것이지요.
따라서, 만일 4번 고객이 요금 인상으로 price를 15000으로 입력 했다면 일반 서비스 가격에 대한 규칙이 깨지게 됩니다.

고객ID service price
1 일반 10000
2 프리미엄 20000
3 프레스티지 30000
4 일반 10000

따라서, 가격에 대한 규칙을 따로 명시한 테이블이 필요하게 됩니다. 다음처럼 relation을 분리하면 위에서 설명한 anomaly가 해결되게 됩니다.

고객ID service
1 일반
2 프리미엄
3 프레스티지
4 일반

service price
일반 10000
프리미엄 20000
프레스티지 30000


5. 마치며
초반에 말씀드린데로 엔터프라이즈 급 서버 시스템 과제를 몇번 수행한 분들의 경우에는 그다지 새롭지 않습니다. 해오던 것이니까요. 그런데, 직접 데이터 모델링을 수행해야 한다면, 마구잡이로 하고 싶지는 않으실 겁니다. 또한, 제대로 만든 건지 확인도 해보고 싶으실 것이고요.
이때, 정규형을 머리속에 넣어두고 작업하시길 바랍니다. 분명 도움이 되실 겁니다.

6. 참고 사이트
http://yuhani.springnote.com/pages/916900



데이터 모델링에서 사용하는 기본 개념 2

데이터베이스 2009. 4. 16. 10:22 posted by 무병장수권력자


데이터 모델링에서 사용하는 기본 개념 2
Relationship(관계)

작성자 : 김문규
최초 작성일 : 2009. 4.16

이번에 다룰 개념은 Relationship 입니다. 우리말로는 관계입니다. 엔터티간의 연관성을 설명하는 것입니다. 단순히 생각하면, 속하는 관계, 속하지 않는 관계, 필수로 연관되는 관계, 있어도 그만 없어도 그만인 관계...들이 있지요. 이런 관계들이 어떻게 정의되는 지 확인해 보세요.

1. Relationship 이란?
엔터티들을 연결하여 의미를 가지는 모델로 만들어 주는 것을 의미합니다. 엔터티가 명사였다면, 관계는 동사에 해당하지요. "사원은 부서에 속한다." 라는 모델에서 사원, 부서는 엔터티, 속한다는 관계가 되겠습니다.
연결되었다는 것은 관련된 제약이 있다는 말입니다. 즉, A테이블에 있는 a1이라는 속성이 B테이블에 있는 b1이라는 속성과 관련이 있는 값이라는 것이지요. 이전 포스트에서 이런 고리를 FK(Foreign Key)라고 설명 드렸습니다.

2. Identifying Relationship
FK가 UID와 관계된 경우입니다. 아래의 그림처럼 방번호와 건물번호가 함께 방의 UID를 구성하고 있습니다. 건물1 에도 101호가 있고 건물2에도 101호가 있는 경우에는 두 개의 속성이 함께 UID를 이루게 되겠지요. 이런 경우에 건물과 방의 관계는 Identifying Relationship 입니다.


3. Non-Identifying Relationship
FK가 UID와 관계되지 않는 경우입니다. 아래의 그림처럼 방번호만으로 방이라는 엔터티를 완전하게 대표할 수 있지만, 건물과의 관계를 설명하기 위해서 UID가 아닌 속성으로 존재하는 경우이지요. 예를 들면, 건물1에는 101호부터 110호까지 있고, 건물2에는 201호부터 210호까지가 있는 경우입니다.



4. Mandatory / Optional Relationship
말그대로 꼭 있어야 하는 가, 아닌가 입니다. 좀더 쉽게 말하면 FK의 Null을 허용할 것인가 아닌가 입니다.
이 개념은 앞선 identifying 관계와 같이 설명되어야 합니다.

1) Identifying Madatory
identifying이면서 사원은 무조건 부서에 속해야 하는 경우

2) Non-Identifying Madatory
non-identifying이면서 사원은 무조건 부서에 속해야 하는 경우

3) Non-Identifying Optional
non-identifying이면서 사원은 부서가 없을 수 있는 경우, 대기발령, 신입사원...등등...^^





'데이터베이스' 카테고리의 다른 글

데이터베이스 정규화  (0) 2009.04.17
데이터 모델링에서 사용하는 기본 개념 1  (0) 2009.04.14
객체지향 DBMS 란?  (0) 2009.04.14


데이터 모델링에서 사용하는 기본 개념 1

데이터베이스 2009. 4. 14. 17:02 posted by 무병장수권력자


데이터 모델링에서 사용하는 기본 개념 1
Entity(엔터티, 개체), Attribute(어트리뷰트, 속성), Key(키)


작성자 : 김문규
최초 작성일 : 2009. 4.14

데이터 베이스 모델링은 어느 정도의 경험만 있다면 누구나나 할 수 있습니다. 논리 정연하게 열심히 고민하면 이론적인 모든 것들이 자연히 그 결과로 나타내기 때문입니다. 하지만, 이론적인 기반없이 고민하는 경우 시간의 낭비가 심하고 후임자에게 그 논리를 설명해 주기 매우 어렵게 됩니다.
따라서, 공부하셔야죠~. 실전에 들어가기 전에 알아야 할 것들이 있으며 이를 간단하게 확인해 보죠.



1. Entity
데이터모델링의 기본으로 식별 되어야 하는 대상을 의미합니다. 테이블에 해당할 가능성이 매우 높습니다.
인사 시스템을 예로 들면, 사원, 부서... 이런 것들이겠지요.

여기서 주의할 점은 아래와 같습니다. (논리적 모델링을 기준으로...)
. 중복되는 데이터를 없앨 것
  - 중복되는 값이 여기저기 있으면 데이터 정합성이 깨질 가능성은 그만큼 높아집니다.
. 상속의 개념이 필요하다면 적극적으로 활용할 것
  - 중복되는 데이터를 줄이기 위한 방법일 수도 있습니다.
  - 또한 논리적으로도 데이터 구조가 명확해 지기도 합니다.
이 두가지만 주의한다면 추후에 DB의 유지, 보수가 매우 편해지게 됩니다.

또하나, 이름을 지을 때도 주의해야 합니다.
. 단수로 이름을 짓습니다.
. 한번에 알아 먹을 만하게 지어 주세요.
. 그렇다 하더라도 되도록 단순하게..
. 공백 없이 대문자로 통일하세요.
. 두가지 의미를 동시에 사용하지 마세요. (예. 수험생/재수생)
. 인스턴스 이름을 사용하지 마세요. (예. CAR != BMW)
. 축약어는 정해진 룰에 따라서.. (같은 DB내에서 중구난방의 축약어는 정말 으... 보기 싫죠?)

2. Attribute
엔터티를 설명하는 속성들 입니다. 테이블의 컬럼들이 될 가능성이 매우 높은 것들입니다.
관리 할만한 중요성이 있는
최소 의미 단위의 것들을
중복이 일어나지 않도록 선택하시면 됩니다.
이 값은 잠재적으로 Key가 될 수 있는 값들입니다.

3. Key
Key(키)란, 해당 엔터티를 잘 설명해줄 수 있는 중요한 속성입니다.
키의 조건은 아래 정도 입니다.
. 인스턴스를 유일하게 식별할 수 있어야 합니다.
. 널(Null)이 되어서는 안됩니다.
. 자주 변경되지 않는 값이면 좋겠습니다.
. 되도록이면 짧은 값이면 좋겠습니다. (마지막 두개는 해당 키를 인덱스로 사용할 경우에 대비해서 고려되는 조건입니다.)
일단, 키라면, Candidate Key(CK, 후보키)에 해당합니다.

1) Primary Key
Primary Key는 테이블을 대표하는 키값입니다. 이 값만 있다면 어떤 레코드라도 정확하게 꺼낼 수 있습니다.
학생 테이블에서 학번, 국민 테이블에서 주민번호등이 Primary Key로 사용될 수 있습니다. (물론 선택은 모델러에 따라 다를 수 있습니다. 아래에 설명할 인조키가 성능면에서 유리할 수 있기 때문입니다.)

2) Foreign Key
다른 테이블의 Primary Key 이며, 이 값을 참조해야만 하는 경우에 이 참조한 값을 Foreign Key라고 합니다.
예를 들면, 주문 테이블에 (주문자, 구매상품ID...) 있고 상품 테이블에 (상품ID, 상품 가격...) 이 있다고 할 때 상품테이블에서 상품 가격은 PK이고, 주문 테이블에 구매상품ID는 FK가 될 수 있습니다.
Relationship을 설명할 때, 사용되는 개념으로 두 테이블을 연결하는 고리 역할을 하는 키라고 생각하시면 되겠습니다. 

3) Artificial Key
한국말로는 인조키 입니다. 무의식중에 실은 굉장히 많이 쓰고 있습니다. 회원 테이블에서 '회원 번호' 같은 속성을 많이 사용해 보셨다면, 이 값이 바로 인조키에 해당합니다.
인조키란, 테이블의 UID 후보가 너무 긴 경우에 성능 및 편의상 가짜 키를 하나 추가로 생성해서 사용하는 것을 가리킵니다. 예를들면 주민번호는 유일하지만 PK로 자주 사용하지는 않습니다. 이유는 꽤? 긴편이기 때문에 성능상, 편의상 인조키를 사용하는 것이 유리하기 때문입니다.

4) UID (Unique ID)
테이블을 대표하는 유일한 식별자 입니다.  앞서 Primary Key라는 개념을 설명했습니다. 이것과 같다고 생각하세요.


'데이터베이스' 카테고리의 다른 글

데이터베이스 정규화  (0) 2009.04.17
데이터 모델링에서 사용하는 기본 개념 2  (0) 2009.04.16
객체지향 DBMS 란?  (0) 2009.04.14


객체지향 DBMS 란?

데이터베이스 2009. 4. 14. 09:57 posted by 무병장수권력자


본 포스트는 database.sarang.net 에서 옮겨담은 글임을 밝힙니다.
원문 작성자 : bafi@netsgo.com
원문 작성일 : 2002.01.04

▶ 1. 객체지향 데이터 베이스의 개요

1.1 객체지향의 개념
  (1) 종래의 정보 모델의 문제점 : 데이터와 연산 분리 설계
   - 자료와 연산간의 연관관계 관리 곤란
   - 자료 변환 관리 곤란
   - 구조변환 관련 연산집합 관리 곤란
   - 설계에 중복발생 가능성
   - 유지 보수 복잡
  (2) 기존 데이터베이스 기술의 문제점
   - 멀티미디어 데이터와 같이 비정형 구조 형태의 데이터 처리 불가능
   - 정규화의 원칙성 결여와 성능문제 야기시킴
   - 제한된 자료 type만 사용
  (3) 객체지향 설계 개념 : 실세계에 존재하는 개념적 엔티티를 중심으로 모델링하는 방식
  (4) 객체지향 기술의 장점
   - 빠른 개발속도 : 기존의 객체 사용
   - 시스템의 품질향상 : 이미 증명된 클래스를 재사용
   - 유연성(flexibility)과 관리 용이성(maintainability)
   - 사실적인 모델링
  (5) 객체지향 데이터베이스가 가져야할 기능
   - 복합객체(complex object)
   - 객체 식별자(object identifier)
   - Encapsulation
   - Class
   - Inheritance
   - 확장성
   - DML의 완전성

1.2 관계 DB와 객체지향 DB 의 차이점 비교



1.3  객체지향 데이터베이스의 장단점
  (1) 장점
    ① 데이터 모델링의 다양성 제공
      - 의미 자료 모델 개념으로 복잡한 데이터를 관리하는 응용분야에서 데이터의 설계와
        유지보수등의 작업을 원활히 할 수 있도록 지원, 다양한 모델링 기법 제공     
    ② 재사용성(reusability)와 확장성(extensibility)
      - 재사용성 : 소프트웨어 위기 극복 개념의 부각, 일반화에의해 지원되는 성격, 새로운
                   환경을 모델링할 때 기존에 제작된 모듈을 다시 사용
      - 확장성 : 캪슐화와 상속 기능으로 해결 지원, 기존 시스템에 추가적 요구사항이나
                 환경의 변화에 대응할 수 있는 능력
    ③ 개념적 일치성
      - 의미 자료 모델의 분류화=세분화, 일반화, 집합화=통합화 등의 개념 지원, 이는
        객체지향 언어의 추상화, 상속성, 연관성 개념과 일치된다. 따라서, OODB와 이것을
        관리하는 프로그램 언어간의 개념적 불일치가 상대적으로 적다
    ④ 지원 기능 : query, 복합 객체, 버전 관리, 스키마 변환, 멀티미디어 자료 관리 기능,
                  긴 트란잭션 처리등의 기능 지원
      ㉠ 질의어
         - 질의 대상이 클래스(class-subclass)가 되고 질의 범위는 지정 클래스나 클래스
           계층구조내 모든 부 클래스가 되기도 한다. 질의 결과는 지정된 클래스에 속하며
           조건을 만족하는 인스턴트들의 집합이 된다
         - 질의 결과 생성시 객체일치(object equality), value equality 등의 일치성 존재
      ㉡ 복합 객체(composite object)
         - 객체 집합(집합화)
         - 객체 구성 요소도 객체가 됨
         - 구성 객체내의 관계를 기술함으로써 정의되며 이들의 관계는 복합객체 계층 구성도
           로 표현된다
      ㉢ 버전(version)관리
         - 하나의 객체변화 과정을 기록하며 과거의 상태변화 역사를 보관 관리하는 것
      ㉣ 스키마 변환
         - 모델링 환경에 따라 스키마가 변화할 필요가 있을수 있는데 이런 변화가 시간적,
           외부 조건에 따라 동적으로 발생할 수도 있다
         - 클래스 정의 변경, 상속 관계 변경으로 나누어 생각
      ㉤ 멀티미디어 자료 관리
         - 종래 자료 : 텍스트 기반 자료형태에서
         - 멀티미디어 자료 : 화상, 동영상, 음향(음악) 자료형태가 추가되었다
         - 멀티미디어 자료의 특징 : 대용량, 실시간 처리 요구
         - 멀티미디어 데이터 처리를 위해
           용량 확장성(extnsibilty), 자료형의 유연성(flexibilty), 처리 속도 효율성(efficiency)
           지원
      ㉥ 긴 트랜잭션 처리
         - transaction : 처리 단위
         - CAD/CAE등에의 응용 확장으로 긴 트랜잭션 처리를위한 관리 기법 요구
    ⑤ 기타
       ㉠ 프로그래밍 생산성 향상
       ㉡ 유지보수 용이성
       ㉢ 복잡한 관계성 표현
       ㉣ 다양한 데이터 타입 제공
       ㉤ 멀티미디어 기능 제공
       ㉥ 데이터 추상화 개념 지원
       ㉦ 일반화와 집합화를 쉽게 표현
  (2) 단점
     - 이론 부재 : 데이터 모델 및 질의 모델의 정형화 미개발(수학적 기반 결여)
       . 관계 DB : 정형화된 데이터 모델 및 관계 대수/해석학 기반 질의 모델 확립
       . 구현체마다 개념적 차이 존재 가능, 통합 운영상 장애 가능성
     - 복잡성 : 다양성 장점에 비해 구현 복잡 및 관리 복잡
        -> 실세계 모델링 편리함 제공, 구현 및 관리시 복잡성과 성능 저하 초래
     - 질의 최적화의 복잡성 : 질의어가 일반 PL의 내장형태로 지원 -> 질의 최적화 곤란
     - 표준화의 미비
     - 안전성, 신뢰성 부족

▶ 2. 객체지향 데이터 모델

    - 데이터 모델 : 데이터 베이스의 내용과 의미를 결정하기위한 현실세계의 개체들을
                    설명하고, 개체들간의 관계, 의미 및 여러 제약 조건등을 기술하기위한
                    개념적 도구

2.1 객체
ㅇ 객체(object) : 개념적인 실세계 엔티티(실세계에 존재하며 하나의 개체를 생성하는
                                         DB의 구성 단위)
    - 객체의 상태를 나타내는 속성(attribute)과 애트리뷰트와 객체를 조작하는
      연산집합인 method로 구성, 애트리뷰트 자체도 객체
    - 유일 식별자(object identifier, OID)를 가짐 : 객체를 유일하게 구별하기위해
    - 원시 객체(primitive(simple) object) : 값만 가지는 스트링, 정수형등
            인스탄스 변수 없음
      복합 객체(composite object) : 애트리뷰트로 타 객체 참조, 집합값, 벡터, 매트릭스등
            인스탄스 변수
    - 상태(state)를 포함한 개별(private) 메모리로 구성
      . 개별 메모리는 애트리뷰트나 인스탄스 변수(instance variable) 집합에 대한 값들로
       이루어짐
      . state는 이 값들임, 객체내의 속성의 값
      . 즉 객체는 property( ,  )를 나타내는 instance variable임
      . 인스탄스 변수 값 자체도 객체임
    - 메소드(method, operations) : 객체내의 애트리뷰트 관리 프로시져
                       객체의 행위(behavior)는 메소드내에 갶슐화 됨
                       객체의 상태를 조작하는 코드로 구성됨
                       객체 정의 일부분임
                       메소드와 인스탄스 변수는 객체 밖에서는 볼수 없음 : 변경 불가
    - 클래스에 속하는 객체를 클래스의 인스탄스라 함
    - class 정의의 효과 :
      . 각각 정의시보다  기억장치 중복 방지
      . set-oriented operation 가능 : 질의 처리 가능하기 때문, 이로인해 질의 시간 빠름

2.2 메시지(message)
     - 객체간의 통신 매체(객체간의 인터페이스 역할)
       모든 메시지는 객체에 의해 이해되고, 메시지를 실행하는 일치되는 메소드가 있다
     - "객체에 해당하는 메소드를 수행하라"
     - 객체 접근 권한 제어 기법 : 객체의 내.외부 구분 역할
                                  캪슐화 지원

2.3 클래스
     - 유사한 객체들의 구조와 행동을 기술하는 도구
     - 객체의 속성과 method로 정의
     - 클래스도 하나의 객체임
     - 중복된 정의를 방지함으로써 저장공간 절약과 동적 스키마 변경을 지원
        : 클래스내에 애트리뷰트와 메소드에 관한 정의를 포함하여

2.4 클래스 계층 구조
     - class-hierarchy : class 끼리의 집단화(hierarchy of class)
     - 추상화 기법 :
       . 일반화(generalization) : super-class 생성 과정, 여러 클래스의 공통 속성 추출
       . 특수화(specialization) : subclassing화 과정, 상위 클래스에서 여러개의 하위 클래스로
                               분류되는 것
     - IS-A 관계 : superclass ----> subclass(class)
 
     - 상속 관계(inheritance) : super-class =====> subclass 
                                             +---> property(method & instance variable)
        하위클래스는 상위클래스의 애트리뷰트와 메소드를 상속 받는다

       . 클래스에 대해 정의된 property는 모두 subclass에 상속됨
       . 부가적인 속성은 각각의 subclass에 정의될 수 있다
       .    +--- simple inheritance : 1-superclass로부터 상속, 트리형태
           +--- multiple inheritance : n-superclass로부터 상속
                                     DAG(directed acyclic graph) 형태
                                     효과 : 현실 세계 표현 유리, 자료 중복 제거 역할
       . 상속의 문제점
         - 명칭 충돌(naming conflict) : 모호성 발생 가능(상위클래스:하위클래스),
                                      다중상속에서의 상위클래스간 명칭 충돌
         - 상속의 범위 : 완전/선택 상속 결정 문제
                         선택 상속시 IS-A 개념에 배치되며 상속의 구현 및 관리 복잡
         - 캡슐화 위배 : 서브 클래스가 슈퍼 클래스의 애트리뷰트에 지접 접근시

2.5 다중성(polymorphism)
     - 상위 클래스의 메소드 정의가 하위 클래스에 부적절시 하위 클래스의 메소드를 재정의
     - 동일한 메시지에대해 클래스 마다 서로 다르게 동작하도록 지정할수 있다
       다수의 메소드 가능, 다른 클래스에도 가능

2.6 복합 객체
     - 객체의 애트리뷰트로 다른 객체를 가질 수 있게 함으로써 포함관계를 갖는 객체를
       표현하는데 사용
     - 포함하는 객체와 포함되는 객체 사이에 집합화(aggregation : IS-PART-OF) 관계가
       성립
     - 복합 객체를 관리하기위해서는 동시성제어(concurrency control), 스키마 변경,
       버전제어, 권한검사등의 관리에서 대상 객체와 이를 구성하는 구성 객체까지 제어
       해야 함

2.7 버전 관리
     - 버전이 가능한 객체 : 추상 객체와 하나이상의 버전으로 구성
     - 버전의 종류
        ① 임시 버전(transient) - 버전유도 관계트리에서 단말노드에 위치한 버전으로
                                 갱신과 삭제 가능
        ② 작업 버전(working) - 임시 버전을 유도시킨 과거의 임시 버전으로 갱신을
                                허용하지 않지만 삭제는 허용
        ③ 안정 버전(released) - 작업 버전에서 승격이 되며 안정된 상태에 도달한 버전을
                                나타내며 갱신, 삭제 모두 금지
     - 버전 변경 통보 방법
        : 버전의 변경을 연관된 객체에게 메시지를 보냄으로써 통보(즉시통보 or 사용자가
          지정한 시간까지 연기했다 통보)
        : 타임 스탬프를 이용하는 방법 - 버전 객체에 접근할 때 접근할 객체의 변경통보
                                        시각과 접근하는 객체의 변경 승인 시각을
                                        관리하는 방법

2.8 스키마 변경(schema transformation)
     - 각 사용자의 데어터 베이스 접근 목적이 다르므로 각자의 응용 목적에 따라 데어터
       베이스의 스키마를 변경
  (1) 클래스 정의 변경
      1) 애트리뷰트 변경
         - 애트리뷰트의 추가 및 삭제
         - 애트리뷰트의 명칭, 도메인, 디폴트값 변경
      2) 메소드 변경
         - 메소드의 추가 및 삭제
         - 메소드의 명칭, 코드 변경
      3) 클래스 명칭 변경
  (2) 상속 관계의 변경
      - 상위 클래스의 추가 및 삭제
      - 상위 클래스들의 우선순위 변경
      - 클래스의 추가 및 삭제
      - 여러 클래스로부터 공통점을 추출해 일반화된 상위 클래스로 추가와 통합
      - 클래스를 여러 클래스로 분할
- DB 스키마가 객체지향 데이터 모델과 일관성을 유지하기위해 충족되어야 할 성질
  : 클래스 계층구조의 불변성
  : 명칭의 불변성
  : 근원의 불변성
  : 완전 상속의 불변성
  : 도메인의 불변성

2.9 스키마 버전
     - 스키마 변경의 문제점
        : 변경시 해당되는 객체의 변화를 기록하지 않는다 - 스키마에서 애트리뷰트가
                          제거될 때 해당되는 객체들에 대해서 제거되는 애트리뷰트의
                           값은 모두 제거된다
        : 한 사용자의 스키마 변경이 다른 모든 사용자에게 영향을 준다
     - 문제점을 해결하기 위해 버전의 개념을 도입

2.10 장기간 트랜잭션
     - 단기간 트랜잭션의 문제점
        : 자료의 처리가 사용자와 대화하는 환경에서 이루어 진다(작업처리시간 길어짐)
        : 작업수행 중에도 사용자와 계속된 대화를 해야하므로 전송하지 않은 자료가
          전달될 수 있다
        : 하나의 작업이 작은 작업들로 분할될수 있는 경우가 있다
        : H/W나 S/W의 문제로 더 이상 작업을 할 수 없을 때 전체 작업을 취소시키면
          유실되는 사용자의 작업량이 커진다
        : 대화식 사용 환경을 지원하기 위해서는 동시성 제어를 통한 빠른 응답 시간을
          제공해야 한다
     - 내포형 트랜잭션
     - 객체의 버전을 이용한 공유 DB와 개인 데이터 베이스 간의 장기간 트랜잭션
     - 약성잠금(soft lock : 접근 충돌시 사용자간의 협상을 통하여 잠금을 해제)을 이용한
        장기간 트랜잭션
     - 여러 트랜잭션을 하나의 트랜잭션으로 묶어 관리하여 여러 사용자간의 공동 작업을
        지원하는 그룹 트랜잭션
     - 트랜잭션 복구시 발생하는 작업취소 작업은 연쇄 철회(cascading rollback)가
        발생하는데 이를 방지하기위해 작업취소 적업을 보상할 수 있는 보상 트랜잭션
         (compensating transaction) 지원

▶ 3. OODBMS의 소개

3.1 개발 현황
(1) IRIS
   - C, Pascal로 구현
   - HP68000 workstation상에서 실행
   - C-interface를 통하여 객체 관리 서비스 제공
   - 응용을 위한 SQL, OSQL의 객체지향 확장
   - 관계 저장장치 시스템상에서 객체 관리자(object manager) 실행
   - DAPLEX 함수형 자료모델에 기반
(2) Orion
(3) EXODUS

3.2 UniSQL
A. 상업 모델
(1) GemStone
   - C 언어로 구현
   - client/server 구조 지원
   - VAX | SUN workstation이 서버로 시용
   - IBM-PCs, Apple Macs, Textronix workstation이 client로 사용됨
   - 응용으로 C, C++, Smalltalk 인터페이스 제공
   - DB 시스템에 Smalltalk80이 확장됨
(2) VBase[ANDR87]
   - C 언어로 구현 - UNIX하의 SUN workstation에서 실행
   - client/server 구조
   - SQL 지원
   - 스키마 정의어로 TDL(type definition language)  사용
   - 응용을 위한 C Object Processor(COP) 제공
   - 객체지향형으로 설계 및 구현됨
(3) Statice
   - Common LISP로 구현
   - Symbolics LISP 기계상에서 실행
   - client/server 구조
   - 거의 DAPLEX 함수형 자료모델을 기반으로 구축
B. 산업 연구 시범 모델
(1) IRIS[FISH87]
   - C, Pascal로 구현
   - HP68000 workstation상에서 실행
   - C-interface를 통하여 객체 관리 서비스 제공
   - 응용을 위한 SQL, OSQL의 객체지향 확장
     (backward-compatible with SQL)
   - 관계 저장장치 시스템상에서 객체 관리자(object manager) 실행
   - DAPLEX 함수형 자료모델에 기반
(2) O2
   - C 언어로 구현
   - SUN-OS하의 SUN workstation상에서 실행
   - client/server 환경에서 객체지향 패러다임 채용
   - C-interface(CO2)와 Basic-Interface(BasicO2) 제공
   - Object Manager를 WISS 저장 시스템상에 구현(WISS: wisconcin storage system)
(3) Jasmin
   - Fujitsu, Ltd(Japan) 개발
   - DAPLEX 함수형 자료모델 기반
   - C-interface(Jasmin/C) 제공
C. 대학 연구 시범 모델
(1) POSTRES[STON86, ROWE87]
   - INGRES RDBMS에 SEQUEL 채택
     (backward-compatible with QUEL)
   - ADT, complex object, version 지원
   - 애트리뷰트에 대한 valid type으로 'relation' hierarchy와 'procedure' 포함
                                      (=class)              (=method)
(2) ENCORE/Observer
   - C로 구현
   - ENCORE는 front-end object manager로SUN workstation과 VMS하의 DEC 기종에서 실행
   - OBServer는 back-end object server로, UNIX하의 SUNs에서 실행
(3) AVANCE
   - 완전한 distributed object-oriented DB system
   - users of AVANCE program in PAL, language influenced by Simula, Smalltalk, and CLU
   - 사무 응용 개발을 지원하도록 설게됨
(4) OZ+
   - C와 Turing Plus로 구현
   - UNIX하의 SUNs에서 실행
   - 관계 DB 시스템인 EMPRESS상에 구현
   - 사무 응용의 유용한 기능 구현
(5) EXTRA
   - EXODUS 시스템상에 object manager 구축
   - C++의 확장형인 E 언어로 EXODUS의 구현
   - E 프로그래밍 언어의 기반위에 PL과 DB의 통합
   - 데이터 모델은 O2, Gemstone, POSTGRES, GEM, Orion 데이터 모델의 확장임



윈도우 탐색기 기본 실행 폴더 위치 변경하기

개발 노트 2009. 4. 11. 23:10 posted by 무병장수권력자


작성자 : 김문규
최초 작성일 : 2009. 4.11

하루에 가장 많이 사용하는 탐색기~! 시간 단축, 스트레스 해소를 위해 기본 폴더의 위치는 매우 중요합니다. ^^
이를 바꾸기 위한 방법을 소개합니다.

1. 윈도우 탐색기 속성 열기
2. 대상 항목에 아래 내용 입력
%SystemRoot%\explorer.exe /e,원하는위치
예)
%SystemRoot%\explorer.exe /e,C:\               : C:\를 기본 폴더로
%SystemRoot%\explorer.exe /e,/select,C:\   : 내컴퓨터를 기본 폴더로

참고 자료
http://emale.kr/39