제6장 객체 타입의 사용

내용 목차

6.1. 개요
6.2. 주요 개념
6.2.1. 객체 타입
6.2.2. 객체 타입 값(객체)
6.2.3. 테이블 생성에 객체 타입 사용
6.2.4. 컬렉션 사용
6.3. 객체 구성요소
6.3.1. SQL 내에서의 객체 사용
6.3.2. 객체 타입 메소드
6.4. 객체의 동작
6.4.1. 객체의 저장
6.4.2. 객체 생성자

본 장에서는 Tibero의 객체 타입과 구성요소 동작방식에 대해서 설명한다.

Tibero 객체 타입은 사용자 정의 타입으로서 주문 또는 고객과 같은 실세계에 존재하는 개체를 표현하는 데 사용된다. NUMBER, VARCHAR 와 같은 기존 타입들을 사용하여 새로운 객체 타입을 정의할 수 있으며, 이전에 정의했던 객체 타입 혹은 컬렉션 타입도 타입을 정의하는데 이용할 수 있다.

또한 테이블을 생성할 때 컬럼의 타입으로 객체 타입을 명시하거나 해당 객체 타입 값만을 저장할 수 있도록 테이블을 생성할 수가 있다. 이러한 테이블을 객체 테이블이라고 한다.

Tibero는 객체를 관계형 모델의 확장으로써 구현한다. 이를 위해 SQL 문법이 확장되었으며, PSM 역시 확장되었다.

테이블에서 객체를 저장하는 형태는 테이블을 생성할 때 결정되며, 다음의 두 가지로 나눌 수 있다.

다음은 객체 테이블을 생성하는 CREATE TABLE 문의 예제이다.


객체 테이블을 생성하면 객체 타입의 속성에 해당하는 컬럼이 해당 테이블의 컬럼으로 생성된다. 그러므로 위의 예에서 customer_type_tab 테이블은 사용자 입장에서 3개의 컬럼을 가지는 테이블로 조회된다.


객체 테이블은 객체를 저장하고 있으므로, 실제 객체를 테이블에서 꺼내올 수도 있게 되는데, 이 때 사용하는 문법이 VALUE(x) 표현식이다.

다음과 같이 객체 테이블 별칭(x)을 인자로 표현식에 주어서 객체 테이블에 저장되어 있는 객체에 접근할 수가 있다.


위의 예에서 보는 것처럼, 객체 테이블에 Insert를 수행할 때는 객체 표현식(위에서는 디폴트 생성자를 사용했다) 하나만을 명시해도 Insert가 가능하고, 각각의 속성 값을 일일이 지정하는 형태로도 Insert가 가능함을 알 수가 있다.

본 절에서는 Tibero 객체를 구성하는 여러 가지 요소에 해서 설명한다.

본 절에서는 SQL 내에서 사용되는 객체의 구성요소에 대해서 설명한다.

객체의 값 자체가 NULL일 경우 쪼갤 수 없는 객체 혹은 NULL 객체라고 한다. 쪼갤 수 없는 객체는 모든 속성값이 NULL인 객체와는 다른 객체이다(즉, 이 경우는 NULL이 아닌 객체이다). NULL이 아닌 객체의 경우, 특정 속성의 값은 NULL을 가질 수도 있으며 이 속성값은 프러시저 혹은 함수를 통해 NULL이 아닌 값으로 변경될 수 있다. 그러나 NULL 객체인 경우 객체의 속성값을 바꾸는 것은 불가능하며, 객체의 메소드를 호출하는 것도 불가능하다.

다음은 컬럼 객체를 가지는 테이블의 객체 컬럼에 NULL 객체와 NULL 속성값을 가지는 NULL이 아닌 객체를 Insert하는 예제이다.


주의

객체 테이블의 행 객체는 NULL 객체일 수가 없다. 또한 컬렉션의 경우 NULL 컬렉션과 구성 요소가 하나도 들어있지 않은 빈 컬렉션은 NULL 컬렉션이 아니며 서로 다른 컬렉션이다.

객체 타입의 메소드는 PSM 함수 혹은 프러시저일 수 있으며 해당 객체에 대해 수행할 연산을 명시한다.

다음은 객체의 멤버 메소드를 호출하는 예이다.

SELECT x.cust_obj.tostring() FROM customer x;

해당 함수 혹은 프러시저가 현재 주어진 객체의 값에 따른 연산을 수행할 때 멤버 메소드를 통해 이러한 연산을 정의한다. CREATE TYPE 문 내에서 멤버 메소드를 정의할 때는 MEMBER FUNCTION 또는 MEMBER PROCEDURE와 같이 앞에 MEMBER를 명시한다. 이렇게 정의된 멤버 메소드는 다음과 같이 객체 표현식 다음에 점(.) 표기법을 사용하여 호출할 수 있다.


점 앞에 오는 것은 해당 객체의 값을 가질 수 있는 객체 표현식이고, 점 다음에는 그 객체의 객체 타입에서 정의하고 있는 멤버 메소드의 이름을 명시한다 SQL에서 멤버 메소드를 호출할 때는 메소드에 건네줄 매개변수가 없는 경우에도 다음과 같이 항상 괄호를 붙여 주어야 한다.


멤버 메소드와 SELF 매개변수

멤버 메소드에는 첫 번째 매개변수로서 정해진 하나의 매개변수가 항상 전달되는 것으로 간주되는데, 이 매개변수를 SELF고 한다. 이 SELF 매개변수에는 멤버 메소드를 호출할 때 명시한 대상 객체의 값이 매개변수의 값으로 전달이 된다.

멤버 메소드를 정의할 때 첫 번째 매개변수로 이 SELF 매개변수를 직접 명시할 수 있으나, 명시하지 않아도 명시한 것으로 간주하며 문법 에러는 발생하지 않는다. 타입의 BODY에서 대상 객체의 속성 값을 명시할 때 SELF 및 점(.) 표기법을 이용해 속성 값을 명시할 수도 있고, SELF와 점을 생략해도 명시가 가능하다. (매개 변수와 이름이 겹치지 않을 경우)


객체 테이블에 저장되어 있는 객체에 대한 멤버 메소드를 호출하는 경우 테이블 별칭과 점(.) 표기법을 이용하여 다음과 같이 호출할 수가 있다. 또한 행 객체를 나타내는 VALUE(x) 표현식으로도 가능하다.


멤버 메소드와 객체 비교

객체를 비교하거나 또는 정렬하려면 일단 두 객체의 기반이 되는 객체 타입이 같아야 하며, 정해진 형태의 멤버 메소드를 통해서 비교 연산이 수행된다. 만일 이러한 멤버 메소드가 존재하지 않을 경우 에러가 발생한다(단, 동등 비교(equal) 및 비동등 비교(inequal)에 대해서는 특수한 규칙을 통해 허용된다).

비교를 수행하는 멤버 메소드는 두 가지(map 메소드/order 메소드) 형태로 존재하는데, 하나의 객체 타입에 대해서 이 둘 중 하나만을 정의할 수 있다.

생성자 메소드는 수행의 결과로 해당 타입의 객체를 반환하는 함수이다. 이것은 미리 정의되어 있는 디폴트 생성자와 사용자가 정의하는 사용자 정의 생성자로 나눌 수 있다.

본 절에서는 Tibero 객체의 실제 동작과 관련한 몇 가지 내용을 설명한다.

객체는 속성들의 집합으로 구성되며, 각각의 속성 역시 객체가 될 수 있기 때문에(단, 순환 참조는 허용하지 않는다) 객체 타입을 정의하고 나면 이것은 객체 간의 포함 관계를 나타내는 하나의 Tree로 표현이 가능해진다. Tree에서 단말에 위치하는 속성은 객체 타입 속성일 수 없으며 내장 타입을 가지는 속성이 된다.

객체가 테이블에 저장될 때는 한 객체가 하나의 값으로 합쳐져서 저장되지 않고 Tree에서 단말에 위치하는 내장 타입 속성들의 각 값으로 찢어져서 저장된다. 다시 말해, 객체가 저장되어 있는 테이블의 하나의 컬럼이 객체 자체에 대한 컬럼이 될 수는 없으며 NUMBER, VARCHAR2와 같은 내장 타입 컬럼과 가변 배열 컬럼들로 구성된 여러 개의 컬럼들을 사용해 해당 객체를 저장하게 된다.

테이블을 생성하는 경우 사용자가 명시한 컬럼의 타입이 객체 타입일 경우 Tibero는 내부적으로 이런 내장 타입 컬럼들을 숨겨진 컬럼의 형태로 만들고 추가로 컬럼을 하나 더 추가하게 되는데, 이 컬럼(NULL 지시자 컬럼)에는 해당 객체를 구성하는 객체들 중(객체의 속성 값 또한 임의의 객체 타입의 객체가 될 수 있으므로) 누가 NULL이고 누가 NULL이 아닌지에 대한 정보를 담게 된다. 그러나 단말 속성(내장 타입 속성)이 NULL 여부에 대한 정보는 NULL 지시자 컬럼에 들어가지 않고, 나머지 (내장 타입에 대한) 숨겨진 컬럼을 사용해 이 정보를 저장한다.

객체 테이블의 경우 객체 테이블이 기반하는 객체 타입을 구성하는 각각의 속성에 대해서 객체 테이블의 컬럼을 생성하며 컬럼의 이름은 속성의 이름을 따라간다. 기반 객체 타입의 특정 속성이 객체 타입 속성일 경우 위에서 기술한 대로(즉, 일반 테이블에 사용자가 객체 타입의 컬럼을 명시했을 때와 같이) 숨겨진 컬럼들이 내부적으로 추가된다.

객체 테이블에서 VALUE(x) 표현식을 사용하여 객체 테이블의 객체에 접근할 경우 이 객체는 객체의 포함관계 Tree 맨 아래에 있는 객체부터 디폴트 생성자를 사용하여 객체들을 생성하고, 마지막으로 가장 상위 단계의 객체들 그리고 내장 타입 속성 값들을 모아 최종 객체 타입의 디폴트 생성자를 호출해서 객체 테이블의 객체를 생성한다.

주의

이때 디폴트 생성자가 사용자에 의해 가려졌을 경우(매개변수의 타입과 갯수, 순서가 디폴트 생성자와 동일한 생성자)라 하더라도 여전히 시스템에서 정의한 디폴트 생성자로 객체를 생성한다.