プライマリ・コンテンツに移動
Oracle® Fusion Middleware Oracle CQL言語リファレンス
12cリリース(12.2.1.2.0)
E82647-01
目次へ移動
目次

前
前へ
次
次へ

1 Oracle CQLの概要

この章では、データのストリーミングをサポートするコンストラクトが追加された、SQLに基づく問合せ言語であるOracle Continuous Query Language (Oracle CQL)について説明します。Oracle CQLを使用すると、Oracle Stream Analyticsを使用してデータ・ストリームに対する問合せを表現できます。

この章の内容は次のとおりです。

1.1 Oracle CQLの基本

データベースは、格納された有限のデータ・セットに対して問合せを実行するために最適化されています。ただし、最近の多くのアプリケーションは、連続的な無制限のデータ・セットに対して問合せを長時間実行する必要があります。設計上、格納されたデータ・セットは、データの大部分が繰り返し問い合され、更新頻度が比較的低い場合に向いています。これとは対照的に、データ・ストリームは、新規要素の挿入を通じて継続的に、通常は排他的に変化するデータを表します。データの大部分を複数回操作することは、不要であるか、実用的ではありません。

センサー・データ・アプリケーション、財務表示、ネットワーク性能測定ツール、ネットワーク監視およびトラフィック管理アプリケーション、クリックストリーム分析ツールなどの多くの種類のアプリケーションでは、データ・セットのかわりにデータ・ストリームが生成されます。これらの種類のアプリケーション・データを管理および処理する際は、厳密な時間によるフォーカスを使用して、データ管理および問合せ機能を作成します。

こうした要件に対応するために、構造化データ・レコードのストリームと格納されたリレーションの概念をサポートするデータ管理インフラストラクチャのOracle Stream Analyticsが導入されました。

統一的な宣言フレームワークを提供するために、データのストリーミングをサポートするコンストラクトが追加されたSQLに基づく問合せ言語のOracle Continuous Query Language (Oracle CQL)が提供されています。

Oracle CQLは次の理念に基づいて設計されています。

  • 連続するデータ・ストリームと従来の格納されたデータ・セットに対する大量の問合せをサポートするスケーラビリティ。

  • 複雑なシナリオを扱う包括性。たとえば、構成を通じて、問合せの様々な中間ビューを作成できます。

図1-1に、Oracle Stream Analyticsアーキテクチャの簡略化した図を示します。Oracle Stream Analyticsサーバーは、軽量のSpringコンテナをOracle Stream Analyticsアプリケーションに提供します。この図のOracle Stream Analyticsアプリケーションは、イベント・データを入力チャネルに提供するイベント・アダプタで構成されています。入力チャネルは、入力チャネルから提供されるイベントを操作する1つ以上のOracle CQL問合せに関連付けられたOracle CQLプロセッサに接続されています。Oracle CQLプロセッサは、問合せ結果の書込み先となる出力チャネルに接続されています。出力チャネルは、出力チャネルから受信したイベントに基づいてアクションを実行するユーザー定義のPlain Old Java Object (POJO)である、イベントBeanに接続されています。

図1-1 Oracle Stream Analyticsアーキテクチャ

図1-1の説明が続きます
「図1-1 Oracle Stream Analyticsアーキテクチャ」の説明

Oracle Stream Analyticsを使用すると、JMS、リレーショナル・データベース表、ローカル・ファイルシステムのファイルなどの各種データ・ソースに対するイベント・アダプタを定義できます。複数の入力チャネルをOracle CQLプロセッサに接続したり、Oracle CQLプロセッサを複数の出力チャネルに接続できます。出力チャネルを別のOracle CQLプロセッサ、アダプタ、キャッシュまたはイベントBeanに接続できます。

Oracle JDeveloperおよびOracle Stream Analytics Visualizerを使用して、次の操作を行います。

  • 図1-1のようなイベント処理ネットワーク(EPN)を作成します。

  • 1つ以上のOracle CQL問合せをEPNのOracle CQLプロセッサに関連付けます。

  • Oracle Stream Analyticsアプリケーションをパッケージし、Oracle Stream Analyticsサーバーにデプロイして実行します。

次の例のような通常のOracle CQL文があるとします。

<?xml version="1.0" encoding="UTF-8"?>
<n1:config xsi:schemaLocation="http://www.bea.com/ns/wlevs/config/application wlevs_application_config.xsd" 
xmlns:n1="http://www.bea.com/ns/wlevs/config/application" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<processor>
    <name>cqlProcessor</name>
    <rules>
        <view id="lastEvents" schema="cusip bid srcId bidQty ask askQty seq"><![CDATA[ 
            select cusip, bid, srcId, bidQty, ask, askQty, seq 
            from inputChannel[partition by srcId, cusip rows 1]
        ]]></view>
        <view id="bidask" schema="cusip bid ask"><![CDATA[ 
            select cusip, max(bid), min(ask) 
            from lastEvents
            group by cusip
        ]]></view>
            <view ...><![CDATA[
                ...
        ]]></view>
        ...
        <view id="MAXBIDMINASK" schema="cusip bidseq bidSrcId bid askseq askSrcId ask bidQty askQty"><![CDATA[ 
            select bid.cusip, bid.seq, bid.srcId as bidSrcId, bid.bid, ask.seq, ask.srcId as askSrcId, ask.ask, bid.bidQty, ask.askQty 
            from BIDMAX as bid, ASKMIN as ask 
            where bid.cusip = ask.cusip
        ]]></view>
        <query id="BBAQuery"><![CDATA[ 
            ISTREAM(select bba.cusip, bba.bidseq, bba.bidSrcId, bba.bid, bba.askseq, bba.askSrcId, bba.ask, 
                bba.bidQty, bba.askQty, "BBAStrategy" as intermediateStrategy, p.seq as correlationId, 1 as priority 
            from MAXBIDMINASK as bba, inputChannel[rows 1] as p where bba.cusip = p.cusip)
        ]]></query>
    </rules>
</processor>

この例では、複数のリレーションを作成するために複数のビュー(Oracle CQLでの副問合せ)が定義され、各ビューは前のビューに基づいています。ビューは常にinputChannelなどの着信チャネルに対して機能します。lastEventsという最初のビューはinputChannelから直接選択します。後続のビューはinputChannelから直接選択するか、前に定義されたビューから選択します。ビューの選択文で返された結果はビューのリレーションに残ったまま維持され、出力チャネルには転送されません。これは問合せの動作です。この例では、inputChannelからの直接の選択と、前に定義されたビューからの選択の両方を行う問合せBBAQueryが定義されます。問合せのselect句から返された結果は、関連付けられている出力チャネルに転送されます(この例ではoutputChannel)。BBAQueryは、タプルベースのストリームからリレーションへの演算子(またはスライディング・ウィンドウ)を使用します。

これらの要素の詳細は、次の項を参照してください。

Oracle Stream Analyticsサーバーおよびツールの詳細は、「Oracle Stream Analyticsサーバー」を参照してください。

1.1.1 ストリームとリレーション

この項では、Oracle CQLを使用して操作する2つの基本的なOracle Stream Analyticsオブジェクトについて説明します。

Oracle CQLを使用して、ストリームとリレーションの次の操作を実行できます。

1.1.1.1 ストリーム

ストリームは、Oracle CQL問合せでの操作の対象となる主なデータ・ソースです。

ストリームSは要素のバッグ(またはマルチセット)(s,T)のバッグです。sSのスキーマを持ち、Tは時間ドメインに属します。

ストリーム要素は、タイムスタンプのタプル挿入のシークエンスとして表すタプル・タイムスタンプ・ペアです。つまり、ストリームは、タイムスタンプされたタプルのシークエンスです。同じタイムスタンプを持つ複数のタプルがある場合があります。入力ストリームのタプルは、タイムスタンプの昇順にシステムに到着する必要があります。詳細は、「時間」を参照してください。

ストリームには名前付き属性のセットで構成される関連付けられたスキーマがあり、ストリームのすべてのタプルはスキーマに準拠しています。

「ストリームのタプル」という用語はストリーム要素のデータ部分(タイムスタンプ・データは除く)の順序付きリストを表します(<s,t>s)。次の例は、株価表示データ・ストリームがどのように表示されるかを示しています。各ストリーム要素は、<timestamp value><stock symbol>および<stock price>で構成されます。

...
<timestampN>    NVDA,4
<timestampN+1>  ORCL,62
<timestampN+2>  PCAR,38
<timestampN+3>  SPOT,53
<timestampN+4>  PDCO,44
<timestampN+5>  PTEN,50
...

ストリーム要素<timestampN+1> ORCL,62では、タプルはORCL,62です。

定義により、ストリームは無制限です。

この項の内容は、次のとおりです。

詳細は、次を参照してください。

1.1.1.1.1 ストリームおよびチャネル

Oracle Stream Analyticsでは、図1-2に示すようにストリームがチャネルとして表されます。Oracle JDeveloperを使用して、ストリーム・イベント・ソース(PriceAdapter)をチャネル(priceStream)に接続し、チャネルをOracle CQLプロセッサ(filterFanoutProcessor)に接続して、プロセッサにイベントを提供します。Oracle CQLプロセッサをチャネル(filteredStream)に接続し、Oracle CQL問合せ結果を下流コンポーネント(図1-2には表示されていません)に出力します。

図1-2 イベント処理ネットワーク内のストリーム

図1-2の説明が続きます。
「図1-2 イベント処理ネットワーク内のストリーム」の説明

注意:

Oracle Stream Analyticsでは、プッシュ・イベント・ソースをOracle CQLプロセッサに接続して、Oracle CQLプロセッサをイベント・シンクに接続するためにチャネルを使用する必要があります。その他のOracle Stream Analyticsコンポーネントでは、チャネルはオプションです。

1.1.1.1.2 チャネルのスキーマ

ストリームに接続するイベント・ソースにより、ストリームのスキーマが確定します。PriceAdapterアダプタにより、priceStreamストリームのスキーマが確定します。次の例は、PriceAdapterのイベント処理ネットワーク(EPN)アセンブリ・ファイルを示しています。wlevs:event-type要素では、イベント・タイプPriceEventを定義しています。wlevs:property要素では、このイベント・タイプに含まれる各プロパティのプロパティ名と型を定義しています。

...
<wlevs:event-type-repository>
    <wlevs:event-type type-name="PriceEvent">
        <wlevs:properties>
            <wlevs:property name="cusip" type="char" />
            <wlevs:property name="bid" type="double" />
            <wlevs:property name="srcId" type="char" />
            <wlevs:property name="bidQty" type="int" />
            <wlevs:property name="ask" type="double" />
            <wlevs:property name="askQty" type="int" />
            <wlevs:property name="seq" type="bigint" />
            <wlevs:property name="sector" type="char" />
        </wlevs:properties>
    </wlevs:event-type>
</wlevs:event-type-repository>

<wlevs:adapter id="PriceAdapter" provider="loadgen">
    <wlevs:instance-property name="port" value="9011"/>
    <wlevs:listener ref="priceStream"/>
</wlevs:adapter>

<wlevs:channel id="priceStream" event-type="PriceEvent">
    <wlevs:listener ref="filterFanoutProcessor"/>
</wlevs:channel>

<wlevs:processor id="filterFanoutProcessor" provider="cql">
    <wlevs:listener ref="filteredStream"/>
</wlevs:processor>

...
1.1.1.1.3 チャネルの問合せ

イベント・ソース、チャネルおよびプロセッサが接続されると、ストリームを使用するOracle CQL文を作成できます。次の例に、filterFanoutProcessrのOracle CQL文を定義するコンポーネント構成ファイルを示します。

<processor>
    <name>filterFanoutProcessor</name>
    <rules>
        <query id="Yr3Sector"><![CDATA[ 
            select cusip, bid, srcId, bidQty, ask, askQty, seq 
            from priceStream where sector="3_YEAR"
        ]]></query>
        <query id="Yr2Sector"><![CDATA[ 
            select cusip, bid, srcId, bidQty, ask, askQty, seq 
            from priceStream where sector="2_YEAR"
        ]]></query>
        <query id="Yr1Sector"><![CDATA[ 
            select cusip, bid, srcId, bidQty, ask, askQty, seq 
            from priceStream where sector="1_YEAR"
        ]]></query>
    </rules>
</processor>
1.1.1.1.4 ダウンストリーム・チャネルに対する問合せ出力の制御

次の例に示すようにプロセッサの複数の問合せを指定した場合は、すべての問合せ結果がプロセッサの発信チャネルに出力されます(filteredStream)。

オプションで、コンポーネント構成ファイルでchannel要素のselector属性を使用して、出力される問合せ結果を制御できます。この例では、問合せYr3SectorおよびYr2Sectorの問合せ結果はfilteredStreamに出力されますが、問合せYr1Sectorの問合せ結果は出力されません。

<channel>
    <name>filteredStream</name>
    <selector>Yr3Sector Yr2Sector</selector>
</channel>

アップストリーム・プロセッサに問合せを作成する前に、selectorchannel要素を構成することもできます。この場合、selector内の名前と一致する問合せ名を指定する必要があります。

1.1.1.2 リレーション

時間的に変化するリレーションRは、時間ドメインからRのスキーマを持つ無制限のタプルのバッグへのマッピングです。

リレーションは、順序がなく、時間的に変化するタプルのバッグです: 言い換えると、瞬間的な関係です。各瞬間において、リレーションは制限されたセットです。また、リレーションの変化する状態を表すように、挿入、削除、または更新を含む、タイムスタンプを持つタプルのシーケンスとして表すこともできます。

ストリームと同様、リレーションにはすべてのタプルが準拠する固定スキーマがあります。

Oracle Stream Analyticsでは基本および派生ストリームとリレーションがサポートされています。外部ソースは基本のストリームとリレーションにデータを提供します。

基本(明示的な)ストリームはOracle Stream Analyticsアダプタに到着するソース・データ・ストリームであるため、時間は非減少です。つまり、各イベントが同一の時間の値を持つ場合があります。

派生した(暗黙的な)ストリーム/リレーションは、問合せ演算子で生成される中間のストリーム/リレーションです。これらの中間の演算子は(ビューを通じて)指定できるため、以降の問合せで指定できます。

基本リレーションは入力リレーションです。

派生したリレーションは、問合せ演算子で生成される中間のリレーションです。これらの中間の演算子は(ビューを通じて)指定できるため、以降の問合せで指定できます。

Oracle Stream Analyticsで、ユーザー自身は基本リレーションを作成しません。Oracle Stream Analyticsサーバーが、必要に応じて基本リレーションを作成します。

リレーションが時間で変化するタプルのバッグであると言う場合、時間は時間ドメインの瞬間を指します。入力リレーションは、時間の経過に沿ったリレーションの変化を表す、タイムスタンプを持つ更新のシーケンスとしてシステムに提示されます。更新はタプルの挿入または削除のいずれかです。更新は、タイムスタンプの昇順でシステムに到着する必要があります。

詳細は、「時間」を参照してください。

1.1.1.3 リレーションとOracle Stream Analytics Tuple Kindインジケータ

デフォルトで、Oracle Stream Analyticsにはタイムスタンプと、そこから生成されたリレーションのOracle Stream AnalyticsTuple Kindインジケータが含まれます。

Timestamp   Tuple Kind  Tuple
 1000:      +           ,abc,abc
 2000:      +           hihi,abchi,hiabc
 6000:      -           ,abc,abc
 7000:      -           hihi,abchi,hiabc
 8000:      +           hi1hi1,abchi1,hi1abc
 9000:      +           ,abc,abc
13000:      -           hi1hi1,abchi1,hi1abc
14000:      -           ,abc,abc
15000:      +           xyzxyz,abcxyz,xyzabc
20000:      -           xyzxyz,abcxyz,xyzabc

Oracle Stream Analytics Tuple Kindインジケータは、次のとおりです。

  • 挿入タプルの場合は+

  • 削除タプルの場合は-

  • 更新済タプルの場合はU。これは、onUpdateEventcom.bea.wlevs.ede.api.RealtionSinkメソッドを呼び出したときに示されます(詳細は、Oracle Stream Analytics Java APIリファレンスを参照してください)。

1.1.2 リレーションからリレーションへの演算子

Oracle CQLのリレーションからリレーションへの演算子は、SQLで表される従来のリレーショナル問合せから派生しています。

SQL問合せで従来のリレーションが参照される任意の場所において、Oracle CQLでリレーションを参照できます。

次のような、スキーマcar_id integerspeed integerexp_way integerlane integerdir integerおよびseg integerを持つストリームCarSegStrの例があるとします。

次の例では、任意の時点で、この問合せの出力リレーションに直前の30秒間に位置-速度の測定を送信した自動車のセットが含まれます。

<processor>
    <name>cqlProcessor</name>
    <rules>
        <view id="CurCarSeg" schema="car_id exp_way lane dir seg"><![CDATA[ 
            select distinct
                car_id, exp_way, lane, dir, seg 
            from 
                CarSegStr [range 30 seconds]
        ]]></query>
    </rules>
</processor>

distinct演算子はリレーションからリレーションへの演算子です。distinctを使用すると、選択した重複タプルの各セットで1つのコピーのみがOracle Stream Analyticsから返されます。重複タプルとはselectリスト内の各式と一致する値を持つタプルです。distinctはselect_clauseと集計関数で使用できます。

distinctの詳細は、次の項を参照してください。

1.1.3 ストリームからリレーションへの演算子(ウィンドウ)

Oracle CQLでは、スライディング・ウィンドウに基づいた、ストリームからリレーションへの演算がサポートされています。通常、S[W]はリレーションです。時間Tのリレーションには、TまでにストリームSに適用されたウィンドウWのすべてのタプルが含まれます。

同じソース(ストリーム)とウィンドウ指定を持つ問合せは、共通のメモリー領域を共有するために最適化されます。これらのパラメータで新しい問合せが追加されると、この共有ウィンドウのコンテンツ(イベント)が自動的に受信されます。この最適化により、問合せは、新しく追加されたイベントを受信していない場合でも初期イベントを出力できます。

window_type::=

図1-3 window_type

window type

Oracle CQLでは、次の種類の組込みウィンドウがサポートされています。

  • Range: 時間ベース

    S[Range T]またはオプションで、

    S[Range T1 Slide T2]

  • Range: 時間ベース(無制限)

    S[Range Unbounded]

  • Range: 時間ベース(現在)

    S[Now]

  • Range: 定数値

    S[Range C on ID]

  • タプルベース:

    S[Rows N]またはオプションで、

    S[Rows N1 Slide N2]

  • 分割:

    S[Partition By A1 ... Ak Rows N]またはオプションで、

    S[Partition By A1 ... Ak Rows N Range T]または

    S[Partition By A1 ... Ak Rows N Range T1 Slide T2]

この項では、ストリームからリレーションへの演算子の次のプロパティについて説明します。

詳細は、次を参照してください。

1.1.3.1 Range、RowおよびSlide

キーワードRangeおよびRowsは問合せで操作するデータの量を指定します。

  • Rangeでは指定の期間内に到着するタプルの数が指定されます。

  • Rowsではタプルの数が指定されます。

Slideキーワードは、問合せからの出力を参照する頻度を、Rangeキーワードは、問合せイベントまでの時間の範囲を指定します。RangeとSlideを一緒に使用すると、問合せを行うイベントのセットになり、そのセットは、問合せウィンドウのスライド先に基づいて変わります。

したがって、セット時間は、問合せのためにイベントが取り出される時間です。時間間隔は、スライドのために指定した時間で割った実際の時間(イベントのタイムスタンプで測定)です。ここからの残りが0ならば、セット時間は、スライドに指定した時間を掛けた時間間隔です。残りが0より大きい場合、セット時間はスライドに指定した時間を時間間隔+ 1に掛けた値になります。

これを別の方法で表すと、timeInterval = actualTime / slideSpecification if((actualTime % slideSpecification) == 0) // No remainder setTime = timeInterval * slideSpecification else setTime = (timeInterval + 1) * slideSpecificationという式になります。

図1-4で、Rangeの指定は「4秒間に相当するデータを参照する必要がある」ことを示し、Slideの指定は「4秒ごとの結果が必要である」ことを示します。この場合、各Slideの指定の終わりに問合せで結果が返されます(「問合せ開始時と空のリレーションの場合のRange、RowsおよびSlide」で説明されている特定の条件を除く)。

図1-4 RangeおよびSlide: 等しい(定常状態条件)

図1-4の説明が続きます
「図1-4 RangeおよびSlide: 等しい(定常状態条件)」の説明

図1-4で、Rangeの指定は「8秒間に相当するデータを参照する必要がある」ことを示し、Slideの指定は「4秒ごとの結果が必要である」ことを示します。この場合、各Rangeの指定中に2回、問合せで結果が返されます(「問合せ開始時と空のリレーションの場合のRange、RowsおよびSlide」で説明されている特定の条件を除く)。

図1-5 RangeおよびSlide: 異なる(定常状態条件)

図1-5の説明が続きます
「図1-5 RangeおよびSlide: 異なる(定常状態条件)」の説明

表1-1は、範囲ベースとタプル・ベースのストリームからリレーションへのウィンドウ演算子に関するデフォルトのRangeRangeの単位およびSlide(該当する場合)のリストです。

表1-1 デフォルトのRangeおよびタプルベースのストリームからリレーションへの演算子

ウィンドウ演算子 デフォルトのRange デフォルトのRange単位 デフォルトのSlide

範囲ベースのストリームからリレーションへのウィンドウ演算子

Unbounded

seconds

1ナノ秒

タプルベースのストリームからリレーションへのウィンドウ演算子

該当なし

該当なし

1タプル

1.1.3.1.1 問合せ開始時と空のリレーションの場合のRange、RowsおよびSlide

表1-2は、問合せ開始時の時間や空のリレーションなど、特定の場合のRangeRowsおよびSlideの動作のリストです。

表1-2 問合せ開始時と空のリレーションの場合のRange、RowsおよびSlide

演算子または関数 結果

COUNT(*)またはCOUNT(expression)

空のリレーションの場合、RangeまたはRowsに相当するデータの累積前、および最初のSlide前にすぐに0を返します(GROUP BYがない場合)。

SUM(attribute)および他の集計関数

空のリレーションの場合、RangeまたはRowsに相当するデータの累積前、および最初のSlide前にすぐにnullを返します。

詳細および例は、次を参照してください。

1.1.3.2 Partition

キーワードPartition Byでは、Partition Byで指定された属性の同一性に基づいて、データ・ストリームSが異なるサブストリームに論理的に分割されます。たとえば、S[Partition By A,C Rows 2]のように分割を指定すると、ACの値のペアの固有な組合せごとにサブストリームが作成され、それらのサブストリームに対してRowsの指定が適用されます。Rowsの指定は、「2タプルに相当するデータを参照する必要がある」ことを示します。

詳細は、「Range、RowおよびSlide」を参照してください。

1.1.3.3 デフォルトのストリームからリレーションへの演算子

Oracle CQL問合せにおいて、リレーションが予想される場所でストリームを参照する際(一般に、from句で)、デフォルトでストリームにRange Unboundedウィンドウが適用されます。たとえば、次の例の問合せは同一です。

<query id="q1"><![CDATA[ 
    select * from InputChannel
]]></query>
<query id="q1"><![CDATA[ 
    IStream(select * from InputChannel[RANGE UNBOUNDED])
]]></query>

詳細は、「リレーションからストリームへの演算子」を参照してください

1.1.4 リレーションからストリームへの演算子

ストリームからリレーションへの演算結果を、さらに処理を行うためストリームに戻すことができます。

次の例では、selectによってフィルタ条件(viewq3.ACCT_INTRL_ID = ValidLoopCashForeignTxn.ACCT_INTRL_ID)を満たすタプルのストリームが出力されます。nowウィンドウによってviewq3がリレーションに変換され、これはフィルタ条件によってリレーションとして維持されます。リレーションからストリームへのIStream演算子によって、フィルタ出力がストリームに変換されます。

<processor>
    <name>cqlProcessor</name>
    <rules>
        <query id="q3Txns"><![CDATA[ 
            IStream(
                select 
                    TxnId, 
                    ValidLoopCashForeignTxn.ACCT_INTRL_ID, 
                    TRXN_BASE_AM, 
                    ADDR_CNTRY_CD, 
                    TRXN_LOC_ADDR_SEQ_ID 
                from 
                    viewq3[NOW], ValidLoopCashForeignTxn 
                where 
                    viewq3.ACCT_INTRL_ID = ValidLoopCashForeignTxn.ACCT_INTRL_ID
            )
        ]]></query>
    </rules>
</processor>

Oracle CQLでは、リレーションからストリームへの次の演算子がサポートされています。

デフォルトでは、Oracle Stream Analyticsで生成されるリレーションには操作インジケータが含まれるため、挿入、削除および更新(UPDATE SEMANTICSを使用している場合)を識別できます。詳細は、リレーションとOracle Stream Analytics Tuple Kindインジケータを参照してください。

1.1.4.1 デフォルトのリレーションからストリームへの演算子

Oracle CQL問合せでモノトニックなリレーションが作成される際は常に、デフォルトでIStream演算子が追加されます。

リレーションRがモノトニックになるのは、t1 <= t2のときにR(t1)R(t2)のサブセットである場合にかぎられます。

Oracle CQLでは、従来の静的なモノトニック・テストを使用します。たとえば、基本リレーションが追加専用として認識される場合、その基本リレーションはモノトニックです。どのストリームSに対してもS[Range Unbounded]はモノトニックです。

リレーションがモノトニックでない場合(たとえば、S[range 10 seconds]のようなウィンドウがある場合)、問合せ作成者の意図(IStreamDStreamまたはRStream)を判断できないため、このような場合、Oracle CQLはデフォルトではリレーションからストリームへの演算子を追加しません。

1.1.5 ストリームからストリームへの演算子

一般に、ストリームからストリームへの演算は、次のように実行します。

ただし、一部のリレーションからリレーションへの演算子(フィルタやプロジェクトなど)は、ストリームからストリームへの演算子として機能することもできます。入力Sがストリームで、ストリーム要素c1が50を超える場合に出力としてストリームを生成する問合せについて検討します。

<processor>
    <name>cqlProcessor</name>
    <rules>
        <query id="q0"><![CDATA[ 
            select * from S where c1 > 50
        ]]></query>
    </rules>
</processor>

これは、デフォルトのストリームからリレーションへの演算子およびリレーションからストリームへの演算子を適用した結果です。ストリームSにデフォルトの[Range Unbounded]ウィンドウが追加されます。その後、この問合せはモノトニック・リレーションと評価されるため、IStreamが追加されます。

詳細は、次を参照してください。

また、Oracle CQLでは次の直接的なストリームからストリームへの演算子がサポートされています。

  • MATCH_RECOGNIZE: この句を使用して、入力ストリームの各種のパターン認識問合せを作成します。詳細は、「パターン認識」を参照してください。

  • XMLTABLE: この句を使用して、XPath式を使用してxmltypeストリーム要素のデータを解析します。詳細は、「XMLTABLEの問合せ」を参照してください。

1.1.6 問合せ、ビューおよび結合

Oracle CQL問合せは、Oracle CQL構文で表され、1つ以上のストリーム、リレーションまたはビューからデータを取得するためにOracle Stream Analytics CQLプロセッサで実行される操作です。<query>要素で作成した最上位のSELECT文は問合せと呼ばれます。詳細は、「問合せ」を参照してください。

Oracle CQLのビューは、ストリームまたはリレーションに関する代替の選択を表します。Oracle CQLでは、副問合せのかわりにビューを使用します。<view>要素で作成した最上位のSELECT文はビューと呼ばれます。詳細は、「ビュー」を参照してください。

各問合せおよびビューには、問合せおよびビューを含むプロセッサで一意の識別子が必要です。次の例に、idq0の問合せを示します。id値は、指定された仕様に準拠する必要があります。

<processor>
    <name>cqlProcessor</name>
    <rules>
        <query id="q0"><![CDATA[ 
            select * from S where c1 > 50
        ]]></query>
    </rules>
</processor>

結合は、複数のストリーム、ビューまたはリレーションから行を結合する問合せです。詳細は、「結合」を参照してください。

詳細は、「Oracle CQLの問合せ、ビューおよび結合」を参照してください。

1.1.7 パターン認識

Oracle CQL MATCH_RECOGNIZEコンストラクトは、パターン認識を実行するための主な手段です。

入力ストリームの連続するイベントまたはタプルのシーケンスが特定の条件を満たす場合は、パターンが構成されます。Oracle CQLのパターン認識機能では、着信イベントまたはタプルの属性に条件を定義し、相関変数と呼ばれるString名を使用してこれらの条件を識別できます。照合されるパターンは、これらの相関変数に対する正規表現として指定され、様々な着信タプルが有効な一致として見なされるために満たす必要のある条件のシーケンスまたは順序が決定されます。

詳細は、「MATCH_RECOGNIZEを使用したパターン認識」を参照してください。

1.1.8 イベント・ソースとイベント・シンク

Oracle Stream Analyticsイベント・ソースはOracle CQL問合せが操作するデータのプロデューサを識別します。Oracle CQLイベント・シンクは問合せ結果のコンシューマを識別します。

この項では、Oracle CQL問合せでアクセスできるイベント・ソースとイベント・シンクの種類、およびイベント・ソースとイベント・シンクへの接続方法について説明します。

1.1.8.1 イベント・ソース

Oracle Stream Analyticsイベント・ソースはOracle CQL問合せが操作するデータのプロデューサを識別します。

Oracle Stream Analyticsでは、次の要素がイベント・ソースである可能性があります。

  • アダプタ(JMS、HTTPおよびファイル)

  • チャネル

  • プロセッサ

  • キャッシュ

注意:

Oracle Stream Analyticsでは、プッシュ・イベント・ソースをOracle CQLプロセッサに接続して、Oracle CQLプロセッサをイベント・シンクに接続するためにチャネルを使用する必要があります。その他のOracle Stream Analyticsコンポーネント・タイプでは、チャネルはオプションです。詳細は、「ストリームとリレーション」を参照してください。

Oracle Stream Analyticsイベント・ソースは、通常はプッシュ・データ・ソースです。つまり、Oracle Stream Analyticsでは、データの準備ができたイベント・ソースからの通知を待ちます。

Oracle Stream Analyticsのリレーション・データベース表とキャッシュのイベント・ソースはプル・データ・ソースです。つまり、Oracle Stream Analyticsは、データ・ストリーム上でのイベントの到着時にイベント・ソースをプルします。

詳細は、次を参照してください。

1.1.8.2 イベント・シンク

CQLプロセッサに接続されているOracle CQLイベント・シンクは問合せ結果のコンシューマです。

Oracle Stream Analyticsでは、次の要素がイベント・シンクである可能性があります。

  • アダプタ(JMS、HTTPおよびファイル)

  • チャネル

  • プロセッサ

  • キャッシュ

同一の問合せを複数のイベント・シンクや、異なる種類のイベント・シンクに関連付けることができます。

1.1.8.3 イベント・ソースとイベント・シンクの接続

Oracle Stream Analyticsでは、イベント処理ネットワーク(EPN)を作成するために、Oracle JDeveloperを使用してイベント・ソースとイベント・シンクを定義します(図1-6を参照)。このEPNで、アダプタPriceAdapterはチャネルpriceStreamのイベント・ソースであり、チャネルpriceStreamはOracle CQLプロセッサfilterFanoutProcessorのイベント・ソースです。同様に、Oracle CQLプロセッサfilterFanoutProcessorはチャネルpriceStreamのイベント・シンクです。

図1-6 イベント処理ネットワークのイベント・ソースとイベント・シンク

図1-6の説明が続きます
「図1-6 イベント処理ネットワークのイベント・ソースとイベント・シンク」の説明

詳細は、次を参照してください。

1.1.9 表イベント・ソース

Oracle CQLを使用して、次の表データにアクセスできます。

詳細は、「イベント・ソースとイベント・シンク」を参照してください。

1.1.9.1 リレーショナル・データベース表イベント・ソース

Oracle CQLプロセッサを使用すると、リレーショナル・データベース表をイベント・ソースとして指定できます。このイベント・ソースで問合せを実行したり、他のイベント・ソースと結合したりできます。

詳細は、「Oracle CQL問合せとリレーショナル・データベース表」を参照してください。

1.1.9.2 XML表イベント・ソース

Oracle CQLのXMLTABLE句を使用すると、XPath式を使用してxmltypeストリームのデータを列に解析し、列名でデータに容易にアクセスできます。

詳細は、「XMLTABLEの問合せ」を参照してください。

1.1.9.3 関数表イベント・ソース

TABLE句を使用して、リレーションとして、Oracle CQL問合せのFROM句内の組込みまたはユーザー定義関数から配列またはCollection型として返された複数の行にアクセスします。

詳細は、次を参照してください。

1.1.10 表イベント・シンク

表イベント・シンクの機能は、EPNアップストリームからの挿入、削除または更新イベントをサポートし、表に接続しているダウンストリームにイベントを送信します。

Springアセンブリ・ファイル

デフォルトでは、アダプタがSampleEventタイプのイベントを送信し、その他すべてのステージがこのタイプのイベントを受信します。イベント・タイプを他のタイプに変更する場合は、次に示す構成に従う必要があります。

例1-1 イベント・タイプ

<wlevs:event-type type-name="SampleEvent">
	<wlevs:properties>
		<wlevs:property name="eventId" type="int"/>
		<wlevs:property name="msg" type="char[]" length="64"/>
	</wlevs:properties>
</wlevs:event-type>

例1-2 tableタグ

<wlevs:table id="tableSink" event-type="SampleEvent" data-source="test-ds" key-properties="eventId" table-name="TTest">
	<wlevs:listener ref="tableRelationSinkBean"/>
</wlevs:table>

他のチャネルについては、属性は同じです。

例1-3 チャネル

outputChannelは、次のように定義されます。

<wlevs:channel id="outputChannel" event-type="SampleEvent" is-relation="true" primary-key="eventId>
	<wlevs:listener ref="outputChannelRelationSinkBean"/>
	<wlevs:listener ref="tableSink"/>
	<wlevs:source ref="processor"/>
</wlevs:channel>

例1-4 アプリケーション構成ファイル

table-sinkをサポートするには、processorを構成する必要があります。

<processor>
	<name>processor</name>
	<rules>
	<query id="getAllEventsRule">
		<![CDATA[ select * from inputChannel ]]>
	</query>
	</rules>
</processor>

アダプタの初期化フェーズで、アダプタはサーバー構成ファイルに定義されているデータ・ソースに接続し、SQL文を使用して表を作成します。

CREATE TABLE TTest (eventId INTEGER,msg VARCHAR(64))

アダプタは、run()メソッドの内部でRunnableBeanRelationSourceを実装し、ケースに応じてinsertdeleteまたはupdateイベントを送信します。

3つのイベント・シンクBeanが同じJavaクラスBatchRelationSinkを実装し、それによってバッチと非バッチ両方のイベントが受信されます。

例1-5 サーバー構成ファイル

データ・ソースtest-dsを、構成ファイルで定義する必要があります。

<data-source>
	<name>test-ds</name>
	<connection-pool-params>
		<initial-capacity>15</initial-capacity>
		<max-capacity>50</max-capacity>
	</connection-pool-params>
		<driver-params>
			<url>jdbc:derby:testTableSinkDB;create=true</url>
		<driver-name>
			org.apache.derby.jdbc.EmbeddedDriver
		</driver-name>
	</driver-params>
</data-source>

1.1.10.1 Springアセンブリ・ファイル

デフォルトでは、アダプタがSampleEventタイプのイベントを送信し、その他すべてのステージがこのタイプのイベントを受信します。

イベント・タイプを他のタイプに変更する場合は、次に示す構成に従う必要があります。

例1-6 イベント・タイプ

<wlevs:event-type type-name="SampleEvent">
    <wlevs:properties>
        <wlevs:property name="eventId" type="int"/>
<wlevs:property name="msg" type="char[]" length="64"/>
    </wlevs:properties>
</wlevs:event-type>

例1-7 tableタグ

outputChannelは、次のように定義されます。

<wlevs:table id="tableSink" event-type="SampleEvent" data-source="test-ds" key-properties="eventId" table-name="TTest">
<wlevs:listener ref="tableRelationSinkBean"/>
</wlevs:table>

他のチャネルについては、属性は同じです。

例1-8 チャネル

<wlevs:channel id="outputChannel" event-type="SampleEvent" is-relation="true" primary-key="eventId>
    <wlevs:listener ref="outputChannelRelationSinkBean"/> 
    <wlevs:listener ref="tableSink"/>
<    <wlevs:source ref="processor"/>
</wlevs:channel>

1.1.10.2 アプリケーション構成ファイル

表シンクをサポートするには、プロセッサを構成する必要があります。

例1-9 アプリケーションの構成

構成は次のとおりです。

<processor>
    <name>processor</name>
    <rules>
      <query id="getAllEventsRule">
        <![CDATA[ select * from inputChannel ]]>
      </query>
    </rules>
</processor>

アダプタの初期化フェーズで、アダプタはサーバー構成ファイルに定義されているデータ・ソースに接続し、SQL文を使用して表を作成します。

CREATE TABLE TTest (eventId INTEGER,msg VARCHAR(64))

アダプタは、run()メソッドの内部でRunnableBeanRelationSourceを実装し、ケースに応じてinsert、deleteまたはupdateイベントを送信します。

3つのイベント・シンクBeanが同じJavaクラスBatchRelationSinkを実装し、それによってバッチと非バッチ両方のイベントが受信されます。test-dsという名前のデータ・ソースが、次の構成ファイルで定義されます。

例1-10 サーバー構成ファイル

<data-source>
    <name>test-ds</name>
    <connection-pool-params>
      <initial-capacity>15</initial-capacity>
      <max-capacity>50</max-capacity>
    </connection-pool-params>
    <driver-params>
      <url>jdbc:derby:testTableSinkDB;create=true</url>
      <driver-name>
        org.apache.derby.jdbc.EmbeddedDriver
      </driver-name>
    </driver-params>
</data-source>

1.1.11 キャッシュ・イベント・ソース

Oracle CQLプロセッサを使用すると、Oracle Stream Analyticsキャッシュをイベント・ソースとして指定できます。nowウィンドウを使用する場合にのみ、このイベント・ソースで問合せを実行したり、他のイベント・ソースと結合できます。

詳細は、次を参照してください。

1.1.12 関数

ファンクションは、データ項目を操作し、結果を戻すという点で演算子に似ています。関数が演算子と異なるのは引数の形式です。この形式により、0、1、2個、またはより多数の引数を操作できます。

function(argument, argument, ...) 

引数を持たない関数は疑似列と同じです(「疑似列」を参照)。ただし、疑似列ではリレーションの各タプルで異なる値が返されますが、引数を持たない関数では各タプルに対して通常は同じ値が返されます。

Oracle CQLには、ストリーム・データの操作を実行する、次のような広範な組込み関数が用意されています。

  • 問合せのストリームまたはビューの各行ごとに単一の結果行を返す単一行関数

  • 単一のタプルのかわりにタプルのグループに基づいて単一の集計結果を返す集計関数

  • Coltオープン・ソース・ライブラリに基づいた、高性能な科学技術計算のための単一行の統計的かつ高度な算術演算

  • Coltオープン・ソース・ライブラリに基づいた、高性能な科学技術計算のための集計の統計的かつ高度な算術演算

  • java.lang.Mathクラスに基づいた統計的かつ高度な算術演算

アプリケーションで必要な機能がOracle CQL組込み関数に用意されていない場合は、oracle.cep.extensibility.functionsパッケージのクラスを使用して、ユーザー定義関数をJavaで簡単に作成できます。ユーザー定義の集計関数および単一行関数を作成できます。オーバーロード関数の作成、および組込み関数のオーバーライドができます。

Oracle CQL関数の所定のデータ型以外のデータ型の引数でOracle CQL関数を呼び出した場合、Oracle Stream AnalyticsではOracle CQL関数を実行する前に、その引数を所定のデータ型に変換しようと試みます。

Oracle CQLには、Coltオープン・ソース・ライブラリに基づいた、高性能な科学技術計算のための様々な組込みの単一行関数および集計関数が用意されています。Coltライブラリの一部として使用可能な関数は、Big Decimalデータ型またはNULL入力値はサポートしません。また、関数の値計算は増分形式ではありません。詳細は、COLTのWebサイトを参照してください。

注意:

関数名では、大/小文字が区別されます。

  • 組込み関数: 小文字のみを使用できます。

  • ユーザー定義関数: welvs:function要素のfunction-name属性で、大/小文字の区別が決定されます。

詳細は、次を参照してください。

1.1.13 時間

タイムスタンプはOracle Stream Analyticsストリームの重要な部分です。ただし、タイプスタンプは必ずしもクロック・タイムと同じである必要はありません。たとえば、アプリケーション・ドメインで時間を定義し、シーケンス番号で表すことができます。タイムスタンプは、タイムスタンプの値が増加する順に更新がシステムに到着することだけを保証するよう要求されます。

タイムスタンプの順序の要件は、1つのストリームまたはリレーションに固有のものです。たとえば、異なるストリームのタプルは任意の順序で相互配置できます。同じタイムスタンプのタプルの処理順序は、複数ストリームを処理している場合は保証されません。さらに、負のタイムスタンプの動作は定義されていません。t = 0の場合、全順序を想定してイベントはただちに出力されます。

Oracle Stream Analyticsでは、アプリケーション時間またはシステム時間を監視できます。

システムがタイムスタンプを付けたリレーションまたはストリームでは、時間は、リレーションまたはストリームのソース上のデータの受信に依存します。指定された時間(たとえば1分など)が経過してもアクティビティが発生しない(ストリームまたはリレーションのソースにデータが到着しない)場合、Oracle Stream Analyticsによりシステム・タイムスタンプを持つリレーションまたはストリームにハートビートが生成されます。リレーションまたはストリームに指定のソースによってデータが移入されるか、またはOracle Stream Analyticsによってハートビートが毎分生成されます。これにより、リレーションまたはストリームの遅れが1分を超えることはなくなります。

システム・タイムスタンプを持つストリームとリレーションの場合、2つのイベントが同じ時間値を持つことがないようにシステムによって時間が割り当てられます。ただし、アプリケーション・タイムスタンプを持つストリームとリレーションの場合は、イベントが同じ時間値を持つ場合があります。

アプリケーションのタイムスタンプが(非減少ではなく)厳密に増加することが分かっている場合は、wlevs:channel属性is-total-ordertrueに設定できます。これにより、Oracle Stream Analyticsエンジンでは特定の最適化を行えるようになり、通常は処理の待機時間の減少につながります。

Oracle Stream Analyticsスケジューラは、スケジュールのアルゴリズムと頻度に従って、各Oracle CQL問合せを連続的に実行します。

1.2 Oracle CQL文

Oracle CQLには、問合せやビューを作成する文が用意されています。

この項の内容は、次のとおりです。

詳細は、次を参照してください。

1.2.1 表記規則

Oracle JDeveloperまたはOracle Stream Analytics Visualizerを使用して、Oracle Stream Analytics CQLプロセッサに関連付けられたXML構成ファイルにOracle CQL文を書き込みます。このXMLファイルは構成ソースと呼ばれます。

構成ソースはwlevs_application_config.xsdスキーマに準拠している必要があり、ruleviewまたはquery要素のみを含むことができます。

<?xml version="1.0" encoding="UTF-8"?>
<n1:config xsi:schemaLocation="http://www.bea.com/ns/wlevs/config/application wlevs_application_config.xsd" 
    xmlns:n1="http://www.bea.com/ns/wlevs/config/application" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<processor>
    <name>cqlProcessor</name>
    <rules>
        <view id="lastEvents" schema="cusip bid srcId bidQty ask askQty seq"><![CDATA[ 
            select cusip, bid, srcId, bidQty, ask, askQty, seq 
            from inputChannel[partition by srcId, cusip rows 1]
        ]]></view>
        <view id="bidask" schema="cusip bid ask"><![CDATA[ 
            select cusip, max(bid), min(ask) 
            from lastEvents
            group by cusip
        ]]></view>
            <view ...><![CDATA[
                ...
        ]]></view>
        ...
        <view id="MAXBIDMINASK" schema="cusip bidseq bidSrcId bid askseq askSrcId ask bidQty askQty"><![CDATA[ 
            select bid.cusip, bid.seq, bid.srcId as bidSrcId, bid.bid, ask.seq, ask.srcId as askSrcId, ask.ask, bid.bidQty, ask.askQty 
            from BIDMAX as bid, ASKMIN as ask 
            where bid.cusip = ask.cusip
        ]]></view>
        <query id="BBAQuery"><![CDATA[ 
            ISTREAM(select bba.cusip, bba.bidseq, bba.bidSrcId, bba.bid, bba.askseq, 
                bba.askSrcId, bba.ask, bba.bidQty, bba.askQty, "BBAStrategy" as intermediateStrategy, 
                p.seq as correlationId, 1 as priority 
            from MAXBIDMINASK as bba, inputChannel[rows 1] as p where bba.cusip = p.cusip)
        ]]></query>
    </rules>
</processor>

Oracle CQLプロセッサのコンポーネント構成ファイルでOracle CQL問合せを作成する場合は、次のルールに従います。

  • viewまたはquery要素ごとに1つのOracle CQL文を指定できます。

  • Oracle CQL文はセミコロン(;)で終わることはできません

  • Oracle CQL文は<![CDATA[および]]>で囲む必要があります。

  • Oracle CQLを発行する場合は、文の定義内でスペースを使用する任意の場所に、1つ以上のタブ、キャリッジ・リターン、またはスペースを含めることができます。pcbpel/cep/test/sql/tklinroadbm3hrs_5000000.cqlx.new

    <processor>
        <name>cqlProcessor</name>
        <rules>
            <query id="QTollStr"><![CDATA[ 
                RSTREAM(select cars.car_id, SegToll.toll from CarSegEntryStr[now] as cars, SegToll 
                    where (cars.exp_way = SegToll.exp_way and cars.lane = SegToll.lane 
                        and cars.dir = SegToll.dir and cars.seg = SegToll.seg))
            ]]></query>
        </rules>
    </processor>
    
    <processor>
        <name>cqlProcessor</name>
        <rules>
            <query id="QTollStr"><![CDATA[ 
                RSTREAM(
                    select
                        cars.car_id, 
                        SegToll.toll 
                    from 
                        CarSegEntryStr[now]
                    as
                        cars, SegToll 
                    where (
                        cars.exp_way = SegToll.exp_way and 
                        cars.lane = SegToll.lane and 
                        cars.dir = SegToll.dir and 
                        cars.seg = SegToll.seg
                    )
                )
            ]]></query>
        </rules>
    </processor>
    
  • 予約語、キーワード、識別子およびパラメータでは大文字と小文字は区別されません。ただし、テキスト・リテラルと引用名では大文字と小文字が区別されます。

    詳細は、次を参照してください。

  • Oracle CQL文ではコメントは許可されていません。詳細は、「コメント」を参照してください。

1.2.2 構文のショートカットとデフォルト

Oracle CQLの問合せ、ビューおよび結合を作成する際、問合せを簡易化するためにOracle CQLで用意されている構文のショートカットとデフォルトを使用できます。

詳細は、次を参照してください。

1.2.3 ドキュメントの表記規則

このリファレンスのすべてのOracle CQL文は(「Oracle CQL文」を参照)、次の項に編成されています。

構文

構文図では、文を構成するキーワードとパラメータを示します。

注意:

すべてのキーワードとパラメータがすべての状況で有効なわけではありません。各文および句の「セマンティクス」を参照し、構文上の制限を理解するようにしてください。

目的

「目的」では文の基本的な使用について示します。

前提条件

「前提条件」項では、必要な権限、および文を使用する前に実行する必要のある手順を示します。

セマンティクス

「セマンティクス」では構文を構成するキーワード、パラメータおよび句の目的と、それらに適用されることのある制限などの使用上の注意点を示します。(この章で使用されているキーワードやパラメータの表記規則の説明は、このリファレンスの「はじめに」を参照してください。)

「例」では文の様々な句とパラメータの使用例を示します。

1.3 Oracle CQLとSQL標準

Oracle CQLは新しいテクノロジですが、SQL99のサブセットに基づいています。

Oracleでは業界に受け入れられた標準への準拠に努め、SQL標準調査会に積極的に参加しています。OracleではOracle CQLの標準化を積極的に推進しています。

1.4 Oracle Stream Analyticsサーバー

Oracle Stream Analyticsサーバーは、Oracle Stream Analyticsアプリケーションに軽量のSpringコンテナを提供して、サーバーとアプリケーションのライフサイクルを管理し、セキュリティ、Jetty、JMX、JDBC、HTTPパブリッシュ/サブスクライブ、ロギングおよびデバッグなど広範な必須サービスも管理します。