4. 질의어

POSTGRES 에서 사용하는 질의어는 SQL-3 의 변형이다. POSTGRES 의 질어의에는 확장가능한 형태의 시스템, 상속, 함수, 생성규칙과 같은 것을 가지고 있다. 이러한 특징은 원래의POSTGRES 질의어인 POSTQUEL 에서 나왔다. 이장에서는 간단한 작동을 POSTGRES SQL 을 사용하여 시행해 본다.

이 매뉴얼은 SQL 의 행동양식을 보여줄 뿐, 완전한 SQL 교재는 아니다. SQL 에 대한 책은 시중에 많이 나와있다. 그리고 여기에 나오는 몇몇 특징들은 ANSI 표준이 아니다.

아래에 예를 들어보자. 여기에서는, 바로 앞장에서 나왔던 것과 같이 mydb 라는 데이터베이스를 만들어 두었고, psql 을 실행한다고 가정해보자. 이 메뉴얼에 나오는 예제는 /usr/local/postgres95/src/tutorial 에도 나와있다. 이 예제들을 어떻게 사용하는 지는 해당 디렉토리에 있는 README 파일을 잘 읽어 보면 된다. 다음과 같이 따라하자.

    % cd /usr/local/postgres95/src/tutorial % psql -s mydb Welcome to the POSTGRES95 interactive sql monitor:

type \? for help on slash commands type \q to quit type \g or terminate with semicolon to execute query
You are currently connected to the database: jolly

mydb=> \i basics.sql

'\i' 명령을 사용하면 특정한 외부파일에서 질의어를 읽어서 처리할 수 있다. 명령행에서의 '-s' 옵션은 하나의 커리를 backend 로 보내기 전에 정지하는 싱글 스텝 모드로 설정하는 것이다.

4.1 개념

POSTGRES 에서 기본적인 개념은 클래스(class) 이다. 클래스는 객체로서의 인스턴 스 (instances) 의 결집체이다. 각각의 인스턴스는 같은 속성(attributes)의 집합 을 가지고 있고, 각각의 속성은 특정한 형(type)이다. 더 나아가, 각각의 인스턴스는 영구적인 객체 식별자(object identifier - OID)를 가지게 되며, 이 식별자는 설치시부터 중복되지 않는 유일한 것이다. SQL 문법은 테이블(table)을 참조하기 때문에, 클래스(class) 라는 개념대신 테이블(table)이라는 말을 사용할 수 있다. 마 찬 가지로, 열(row) 는 인스턴스(instance)이고, 컬럼(columns)은 속성(attributes)이다.

앞에서 살펴본 바와 같이, 클래스는 그룹화되어 데이터베이스를 이루고, 데이터베 이스의 집합은 하나의 postmaster 프로세스에 의해 관리된다.

4.2 새로운 클래스의 생성

클래스의 이름을 지정하여 새로운 클래스를 만들 수 있다. 이때 모든 속성과 형 을 명시한다.

    CREATE TABLE weather (
        cityvar     char(80),
        temp_lo     int,               - 최저온도
        temp_hi     int,               - 최고온도
        prcp        real,              - 강수량
        date        date
    );

예약어(keyword)에는 무신경해도 되지만 식별자에는 주의하여야 한다. POSTGRES SQL 은 평범한 SQL 타입으로 int, float, real, smallint, char(N), varchar(N), date, time 을 제공한다. 나중에 살펴보겠지만, POSTGRES 에서는 사용자가 데이 터 형을 자신이 마음대로 정할 수 있다. 결과적으로, 형의 명칭은 예약어가 아니다.

나아가, POSTGRES 의 'create' 명령어는 전통적인 관계형 시스템에서 테이블을 생 성 하는 데 사용하는 명령어와 아주 유사하다. 그러나, 클래스는 관계형 모델을 확장하는 독자적인 특성을 가지고 있음을 곧 알아볼 것이다.

4.3 클래스에 인스턴스를 삽입하기

클래스에 인스턴스를 삽입하는 데는 'insert' 구문을 사용한다.

    INSERT INTO weather
        VALUES ('San Francisco', 46, 50, 0.25, '11/27/1994')

'copy' 명령을 사용하면, 평범한 아스키 파일에서 대규모의 데이터를 적재할 수 있다.

4.4 클래스에 질의하기

weather 클래스에 보통의 관계형 선택, 계획 커리를 던질 수 있다. SQL 'select' 구문을 이러한 목적에 사용할 수 있다. 구문은 대상 목록 부분(target list - 반환될 속성 목록부분) 과 질의부분(어떠한 제한을 명시하는 부분)으로 나눌 수 있다. 예를 들자면, weather 의 모든 열(row)을 알아보기 위해서는 다음과 같이 하면 될 것이다.

    SELECT * FROM WEATHER;

그러면, 출력은 다음과 같을 것이다.

city         |temp_lo|temp_hi|prcp|      date
-------------+-------+-------+----+----------
San Francisco|     46|     50|0.25|11-27-1994
San Francisco|     43|     57|   0|11-29-1994
Hayward      |     37|     54|    |11-29-1994
(3 rows)

아울러, 대상 리스트에 표현식을 마음대로 지정할 수 있다. 예를 들면, 다음과 같이 질의를 할 수 도 있다.

    SELECT city, (temp_hi+temp_lo)/2 AS temp_avg, date FROM weather;

쿼리시에 커리부분에 부울런 오퍼레이터(and, or, not) 을 사용할 수 있다. 예를 들면, 다음과 같다.

    SELECT *
      FROM weather
      WHERE city = 'San Francisco'
          and prcp > 0.0;
 
 city         |temp_lo|temp_hi|prcp|      date
 -------------+-------+-------+----+----------
 San Francisco|     46|     50|0.25|11-27-1994
 (1 row)

마지막 참고사항으로, select 의 결과를 순서대로 정렬하거나, 중복되는 인스턴스 를 제거할 수도 있다.

    SELECT * FROM weather ORDER BY city;

4.5 select 결과를 리다이렉트하기

select 커리는 새로운 클래스로 리다이렉트 하도록 사용할 수 있다.

    SELECT * INTO temp from weather;

이러한 select 의 사용은, 묵시적인 create 명령어를 생성하여, 새로운 클래스로 temp 를 생성하는 데, 이 때 속성과 형은 'SELECT INTO' 명령어에서 대상 리스트에 명시된 속성 명칭과 형이 사용된다. 물론, 다른 클래스상에서 결과적으로 생성된 클래스에서도 어떠한 동작도 수행할 수 있다.

4.6 클래스간의 결합

지금까지, 하나의 질의는 한번에 하나의 클래스만을 억세스 해왔다. 질의는 한번에 여러 클래스를 억세스하거나, 클래스의 여러 인스턴스를 동시에 다루는 방법으로 동일한 클래스를 억세스 할 수 있다. 한번에 같은 클래스나 서로다른 클래스의 여러 인스턴스에 접근하는 질의를 '결합 질의(join query)' 라고 부른다.

하나의 예로, 다른 레코드의 온도 범위에 있는 모든 레코드를 찾고 싶을 때를 가정 해보자. 결과적으로, 우리는 각각의 EMP 인스턴스의 temp_lo 와 temp_hi 속성을 다른 모든 EMP 인스턴스의 temp_lo 와 temp_hi 속성과 비교할 필요가 있다.

(주2 - 이것은 단지 개념적인 모델일 뿐이다. 실제적인 결합은 좀더 효율적인 방법으로 이루어 질 것이지만, 사용자의 눈에는 보이지 않는다. )이러한 작업은 다음의 커리로 할 수 있다.

    SELECT W1.city, W1.temp_lo, W1.temp_hi,
           W2.city, W2.temp_lo, W2.temp_hi
    FROM weather W1, weather W2
    WHERE W1.temp_lo < W2.temp_lo
      and W1.temp_hi > W2.temp_hi;
 
 
city         |temp_lo|temp_hi|city         |temp_lo|temp_hi
-------------+-------+-------+-------------+-------+-------
San Francisco|     43|     57|San Francisco|     46|     50
Hayward      |     37|     54|San Francisco|     46|     50
(2 rows)

이 경우에, W1 과 W2 는 클래스 weather 의 인스턴스를 위한 대용이며, 양쪽의 범위는 클래스의 모든 인스턴스를 넘는다. (데이터베이스 시스템의 전문용어로 W1 과 W2 는 "범위 변수(range variables)"라 한다.) 하나의 질의는 클래스 이름과 그의 대용을 자유롭게 포함할 수 있다.

(주3 - 이러한 결합의 의미는, 질의부분은 데카르트의 product 에서 정의한 클래스 식의 진리값의 표현이라는 것이다. 질의부분이 참인 데카르트의 product 에서의 이러한 인스턴스를 위해서, POSTGRES 는 대상 리스트에서 지정한 값을 계산 하여 반환한다. POSTGRES SQL 은 이러한 표현에서 값을 복사하는 데 어떠한 의미도 부여하지 않는다. 이 의미는 POSTGRES 는 가끔 같은 대상 리스트를 여러번 재계산 한다는 것을 의미한다. - 이것은 자주 부울런 표현이 'or' 로 연결되었을 때 나타 난다. 이러한 복사를 피하기 위해서는, 'select distinct' 구문을 사용하여야 한 다.)

4.7 갱신

'update' 명령을 사용하면 존재하는 인스턴스를 갱신할 수 있다. 11월 28일 이후의최고온도와 최저온도를 2도씩 감소시켜야 할 필요성이 있다고 생각해보자. 이러한 갱신은 다음의 질의로 처리할 수 있을 것이다.

    UPDATE weather
    SET temp_hi = temp_hi - 2, temp_lo = temp_lo - 2
    WHERE date > '11/28/1994';

4.8 삭제

삭제는 'delete' 명령을 사용한다.

    DELETE FROM weather WHERE city = 'Hayward';

Hayward 에 관련된 모든 날씨기록은 삭제한다. 다음과 같은 사용은 조심해야 한다.

    DELETE FROM classname;

'delete' 명령은 여러분에게 물어보지도 않고 지정한 클래스의 모든 인스턴스를 간 단히 삭제해서 공허만이 남게 된다. 시스템은 이러한 삭제작업 이전에 확인을 요구하지 않을 것이다.

4.9 전체 함수의 사용

다른 질의어와 마찬가지로, POSTGRES 는 전체 함수를 제공한다. 그러나, 현재의 POSTGRES의 전체 함수는 매우 제한적이다. 특별히, 횟수, 합계, 평균, 최대, 최소 등의 계산에 관련된 전체 함수를 제공한다. 이들 함수는 인스턴스의 집합에 적용되며, 질의의 대상 리스트에만 나타나며, 질의부분(where 절)에는 나타나지 않는다. 예를 들어보자.

    SELECT max(temp_lo) FROM weather;

전체 함수와 함께 'GROUP BY' 절을 사용할 수 있다.

    SELECT city, max(temp_lo) FROM weather GROUP BY city;