24 データ・ユースケース・ドメインの管理

ドメインの作成、ドメインの使用、ドメインの削除などのタスクを実行できます。

24.1 データ・ユースケース・ドメインについて

データ・ユースケース・ドメイン(または単にドメイン)は、ビジネス価値を記述します。

ドメインは、アプリケーション、開発者、DBAなどのデータ・コンシューマに、値を正しく一貫して処理するのに役立つ追加のコンテキストを提供します。

ドメインにはデータ型と、次のオプションのプロパティがあります:
  • STRICT
  • NOT NULL制約およびCHECK制約
  • デフォルト照合(拡張データ型が有効な場合のキャラクタ・タイプのみ)
  • デフォルト値
  • 注釈
  • 表示式と順序式

ドメインを同じデータ型の表列に関連付けることができます。

データ・ユースケース・ドメインの使用の詳細は、『Oracle Database開発ガイド』を参照してください。

24.2 ドメインを管理するためのガイドライン

これらのガイドラインに従うと、ドメインの管理が容易になります。

24.2.1 ドメインのタイプの指定

ユースケース・ドメインのタイプを指定する必要があります。

次のタイプのユースケース・ドメインを作成できます:
  • 単一列 – 単一値の説明
  • 複数列 - コンポジット値の説明
  • 列挙ドメイン – 名前と値のペアのリスト
  • フレキシブル(フレックス)ドメイン – サブドメイン間で選択するドメイン
  • JSONスキーマ・ドメイン – JSON値の説明

24.2.2 組込みドメインの使用の検討

組込みドメインを使用すると、共通ドメインを簡単に実装できます。

Oracle Databaseには、リリース23ai以降、電子メール・アドレス、クレジット・カード番号、社会保障番号などの一般的な値のドメインが用意されています。

組込みドメインの使用の詳細は、『Oracle Database開発ガイド』を参照してください。

24.2.3 厳密なドメイン列の定義の検討

厳密なドメイン列は、完全に一致する型を提供します。

デフォルトでは、ドメインを同じデータ型の列に関連付けることができます。厳密なドメイン列は、完全に一致する型を持つ表の列にのみ関連付けることができます。これには、データ型の位取り、精度および長さが含まれます。

標準化された長さまたは位取りと精度を持つ値には、厳密なプロパティを使用することを検討してください。たとえば、ISOの国コードと通貨コード、それぞれ2文字と3文字です。

24.2.4 ドメインでの注釈の定義

注釈は、ドメインの追加ドキュメントを提供します。

注釈を追加してドメインをドキュメント化し、メタデータを追加して値を詳細に記述します。たとえば、UIの値に名前を付ける方法、および値に対して許可されるDML操作などです。

24.2.5 コンポジット値の複数列ドメインの検討

複数の列をまとめて制約する必要がある場合は、複数列ドメインを作成します。

たとえば、金額と値、通貨、為替レート、国コードと国内番号を含む電話番号、および緯度や経度などの地理的なポイントなどです。

24.2.6 表示式および順序式の定義の検討

ドメイン値を表示および順序付けするためのルールを作成できます。

DISPLAY句およびORDER句でドメイン値を表示およびソートするためのカスタム・ルールをそれぞれ定義できます。これらのルールは、DOMAIN_DISPLAY関数およびDOMAIN_ORDER関数を使用してドメイン値を問い合せる場合に使用します。

これらの式を使用して、ドメイン値の式を標準化します。たとえば、金額の通貨換算ロジックです。

24.2.7 小さい静的リストに対する列挙ドメインの使用の検討

列挙ドメインを使用して、小さい静的リストの値を制限できます。

たとえば、曜日や血液型などです。

24.2.8 タイプごとに異なるルールを持つ値に対するフレックス・ドメインの使用の検討

タイプに基づいて柔軟なルールを作成するには、フレックス・ドメインを使用します。

たとえば、温度、距離、重さなどの単位が異なる測定値、または国によって異なる住所や電話番号書式などの国際化です。

24.2.9 JSONデータに対するJSONスキーマ・ドメインの使用の検討

JSONデータを検証するには、JSONスキーマ・ドメインを使用します。

たとえば、部門とそのスタッフを記述するJSONドキュメントに、名前付き従業員の配列が含まれていることを確認する場合などです。

24.3 ドメインの作成

スキーマにドメインを作成する際には、CREATE DOMAIN権限が必要です。別のスキーマにドメインを作成するには、CREATE ANY DOMAIN権限が必要です。

24.3.1 単一列ドメインの作成

単一列ドメインは値を記述します。

例: 単一列ドメインの作成

これにより、次のプロパティで挿入タイムスタンプ値を記述する単一の列ドメインが作成されます:
  • データ型は、TIMESTAMP WITH TIME ZONEです。

  • これにはNOT NULL制約があります。

  • デフォルト値はSYSTIMESTAMPです。

  • システムが生成されることを示す注釈があり、SELECTがこれらの値で許可される唯一の操作です。

ノート:

注釈はメタデータのみです。つまり、これらのプロパティを考慮するのはユーザーです。適切な権限を持つユーザーがこれらの値を挿入および更新できます。
CREATE USECASE DOMAIN insert_timestamp_d AS 
  TIMESTAMP WITH LOCAL TIME ZONE 
  NOT NULL
  DEFAULT SYSTIMESTAMP
  ANNOTATIONS (
    system_generated,
    allowed_operations '["select"]' );

24.3.2 複数列ドメインの作成

複数列ドメインを使用して、多数の部分を持つ値を記述します。

例: 複数列ドメインの作成

たとえば、価格、通貨、金銭価値の為替レートなどです。複数列ドメインには、値の各コンポーネントの列があります。表と同様に、列レベルおよびドメイン・レベルで制約および注釈を定義できます。

この例では、次のプロパティを使用して通貨値を記述する複数列ドメインを作成します:
  • これには、金額、通貨およびこの通貨からUSドルへの為替レートの列があります。

  • ISO_CURRENCY_CODEには厳密なプロパティがあります。つまり、CHAR(3 CHAR)として定義された列、またはデータベースの文字セット内の1文字当たりの同等のバイト数にのみ関連付けることができます。

  • AMOUNT列およびUSD_EXCHANGE_RATE列は厳密でないため、INTEGERNUMBER(16,2)DECIMALなどの数値型の列に関連付けることができます。

  • すべての列は必須です。

  • 通貨コードが3文字の大文字であることを確認するためのチェック制約があります。

  • USD為替レートはゼロより大きく、デフォルトは1である必要があります。

  • USD値のUSD為替レートが1であることを確認するためのドメイン・レベルの制約があります。

  • 変換元通貨からUSDに金額を換算するための表示式および順序式があります。

CREATE USECASE DOMAIN currency_d AS (
  amount AS NUMBER NOT NULL,
  iso_currency_code AS CHAR(3 CHAR) STRICT NOT NULL
    CONSTRAINT from_curr_3_uppercase_letters_ck
    CHECK ( regexp_like ( iso_currency_code, '[[:upper:]]{3}' ) ),
  usd_exchange_rate AS NUMBER NOT NULL
    CONSTRAINT ex_rate_gt_zero_ck 
    CHECK ( usd_exchange_rate > 0 )
    DEFAULT 1 )
CONSTRAINT currency_usd_ex_rate_one_ck
CHECK ( CASE 
  WHEN iso_currency_code = 'USD' THEN 1 
  ELSE usd_exchange_rate END = usd_exchange_rate )
DISPLAY TO_CHAR ( amount * usd_exchange_rate, '$999,999,990.00' ) || '(' || iso_currency_code || ')'
ORDER TO_CHAR ( amount * usd_exchange_rate, '999,999,990.00' ) || iso_currency_code;

24.3.3 列挙ドメインの作成

列挙ドメインを使用して、名前付きの値リストを作成します。

各値には多数の名前を関連付けることができます。名前は有効なSQL識別子である必要があります。

列挙値には、ドメインでサポートされる任意のデータ型にすることができます。列挙内のすべての値は、同じデータ型を使用する必要があります。値を省略すると、1から始まる整数になります。値は、列挙の各エントリに対して1ずつ増加します。

例: 列挙ドメインの作成

この例では、曜日に対する列挙を作成します。
  • 各値には、曜日の完全な名前と2文字の略称の2つの名前が関連付けられています。

  • 日曜日の値はゼロです。その他の値は未指定であるため、エントリごとに1ずつ増加します。したがって、月曜日= 1、火曜日= 2、土曜日= 6のようになります。

CREATE DOMAIN days_of_week_d AS ENUM (
  Sunday    = Su = 0,
  Monday    = Mo,
  Tuesday   = Tu,
  Wednesday = We,
  Thursday  = Th,
  Friday    = Fr,
  Saturday  = Sa );

例: SQL文での列挙名の使用

列挙を表のように問い合せることで、その列挙のすべての名前と値のペアを表示できます。たとえば:
SELECT * FROM days_of_week_d;

例: SQL文での列挙名の使用

列挙名を使用して、リテラル値のかわりにSQL文内の値にアクセスできます。たとえば:
SELECT * 
FROM   product_prices 
WHERE  discount_day IN ( days_of_week_d.saturday, days_of_week_d.sunday );

例: 列挙値の名前の取得

列挙ドメインには、その値を最初の使用可能な名前に変換する暗黙的な表示式があります。たとえば:
SELECT DOMAIN_DISPLAY ( CAST ( 1 AS days_of_week_d ) );

24.3.4 フレックス・ドメインの作成

フレキシブル・ドメインは、識別子列の値に基づいてドメインのセットから選択されます。

フレックス・ドメインを作成するには、最初にそのサブドメインを作成する必要があります。次に、CASE式またはDECODE式を使用してフレックス・ドメインを作成し、使用するサブドメインを決定します。サブドメインがフレックス・ドメインと同じスキーマ内にあるか、フレックス・ドメイン所有者がサブドメインに対してEXECUTE権限を持っている必要があります。

各サブドメインは、フレックス・ドメイン内の列のサブセットにマップできます。フレックス列ごとに、関連するすべてのサブドメイン列のデータ型が一致している必要があります。

フレックス・ドメインには、制約やデフォルトなどの他のプロパティはありません。データベースは、選択したサブドメインに基づいて表の列にプロパティを適用します。

フレックス・ドメインを割り当てるには、CREATE TABLEおよびALTER TABLEDOMAIN句を使用します。USING句は、識別子列を示します。

例: フレックス・ドメインの作成

この例では、温度単位の摂氏、華氏および絶対温度のドメインを作成します。これらの各ドメインには、その温度スケールで絶対零度の値を定義するチェック制約と、単位を表示する表示式があります。フレックス・ドメイン温度は、単位識別子列の値に基づいて、適用するドメインを選択します。
CREATE DOMAIN celcius_d AS NUMBER
  CONSTRAINT abs_zero_c_ck
    CHECK ( celcius_d >= -273.15 )
  DISPLAY celcius_d || ' °C';
   
CREATE DOMAIN fahrenheit_d AS NUMBER
  CONSTRAINT abs_zero_f_ck
    CHECK ( fahrenheit_d >= -459.67 )
  DISPLAY fahrenheit_d || ' °F';
   
CREATE DOMAIN kelvin_d AS NUMBER
  CONSTRAINT abs_zero_k_ck
    CHECK ( kelvin_d >= 0 )
  DISPLAY kelvin_d || ' K';

CREATE FLEXIBLE DOMAIN temperature_d ( temp )
CHOOSE DOMAIN USING ( units CHAR(1) ) 
FROM (
  CASE units
    WHEN 'C' THEN celcius_d ( temp )
    WHEN 'F' THEN fahrenheit_d ( temp )
    WHEN 'K' THEN kelvin_d ( temp )
  END );

例: フレックス・ドメインと表の列の関連付け

データベースは、単位に対応するサブドメインを使用して、温度に対する絶対零度チェックを適用します。たとえば、temperature_unitsにKを挿入すると、KELVIN_Dドメインに制約が適用されます。したがって、温度の値はゼロ以上である必要があります。

TEMPERATURE_UNITSの値は制約がないため、C、FおよびK以外の文字を挿入できます。他の文字を挿入すると、温度の値も制約されません。

READING_DATETIMEでは、「単一列ドメインの作成」で定義されたINSERT_TIMESTAMP_Dドメインが使用されることに注意してください。これは、デフォルトのSYSTIMESTAMPを持つ必須のTIMESTAMP WITH TIME ZONEであることを意味します。

次に、フレックス・ドメインを表の列に関連付ける必要があります:
CREATE TABLE temperature_readings (
  reading_datetime   insert_timestamp_d, 
  temperature        NUMBER,
  temperature_units  CHAR(1 CHAR),
  DOMAIN temperature_d ( temperature ) 
    USING ( temperature_units ) );

24.3.5 JSONスキーマ・ドメインの作成

JSONスキーマ・ドメインは、JSONドキュメントの構造を検証します。

例: JSONスキーマ・ドメインの作成

この例では、部門のスタッフを記述するJSONドキュメントを定義します。これは、次の2つの属性のみを含むオブジェクトです:
  • 文字列departmentName

  • 配列employees。この配列の要素は、任意の有効なJSON値にすることができます。

CREATE DOMAIN department_json_d AS JSON 
  VALIDATE USING '{
    "type": "object",
    "properties": {
      "departmentName": { "type": "string" },
      "employees": { "type": "array" }
    },
    "required" : [ "departmentName", "employees" ],
    "additionalProperties": false
  }';

24.4 ドメインの使用

表の作成および変更時に、ドメインを新しい列に関連付けることができます。

24.4.1 ドメインの表DDL

ドメインを完全に制御できるように、Oracle DDLが拡張されました。

ドメインが自分のスキーマ内にあるか、ユーザーにEXECUTE ANY DOMAIN権限が必要です。

例: 表作成時のドメインの関連付け

この文は、「複数列ドメインの作成」で定義された通貨ドメインを、表のPRICECURRENCY_CODEおよびUSD_EXCHANGE_RATE列に関連付けます。

表およびドメイン内の列名は異なる場合があり、データベースはこれらを位置によって関連付けます。したがって、PRICEは、AMOUNTCURRENCY_CODE ISO_CURRENCY_CODEに関連付けられ、USD_EXCHANGE_RATEUSD_EXCHANGE_RATEに関連付けられます。

CREATE TABLE product_prices (
  product_id        INTEGER,
  insert_datetime   TIMESTAMP WITH LOCAL TIME ZONE,
  price             NUMBER(10, 2),
  currency_code     CHAR(3 CHAR), 
  usd_exchange_rate NUMBER,
  DOMAIN currency_d ( price, currency_code, usd_exchange_rate ) );

例: 新しい列の追加時のドメインの関連付け

この例では、「列挙ドメインの作成」の項で定義された列挙に関連付けられた列DISCOUNT_DAYを追加します。このドメインの値は数値であるため、列のデータ型はNUMBERになります。列挙では、チェック制約も適用され、DISCOUNT_DAY (整数0から6)にのみ値を格納できます。

ALTER TABLE product_prices ADD 
  discount_day DOMAIN days_of_week_d;

ドメインを既存の列に関連付けるには、ALTER TABLEを使用してドメインを既存の列にリンクできます。これを行うと、制約や注釈などのすべてのドメイン・プロパティがドメインから列にコピーされます。

例: 既存の列へのドメインの関連付け

これにより、「単一列ドメインの作成」で定義されたINSERT_TIMESTAMP_DドメインがINSERT_DATETIME列に関連付けられます。これを成功させるには、insert_datetimeで次の条件が必要です:
  • データ型がTIMESTAMP WITH LOCAL TIME ZONEであること。

  • デフォルトがないか、ドメイン(SYSTIMESTAMP)と同じであること。

  • 他のドメインに関連付けられていないこと。

ALTER TABLE product_prices 
  MODIFY ( insert_datetime ) 
  ADD DOMAIN insert_timestamp_d;
列は1つのドメインにのみ関連付けることができます。2つ目のドメインを列に関連付けようとすると、文でエラーが発生します。

例: ドメインの関連付け削除

ALTER TABLEを使用して列からドメインを削除することで、列からドメインの関連付けを削除できます。この文は、DISCOUNT_DAY列からドメインを削除します。これにより、列から制約も削除されます。
ALTER TABLE product_prices
  MODIFY ( discount_day ) 
  DROP DOMAIN;

24.4.2 ドメイン関数

Oracle Databaseには、ドメインを操作するための5つのドメイン関数が用意されています。

ドメイン関数は次のとおりです:
  • DOMAIN_CHECK – ドメインのデータ型と一致するように値を変換できるかどうか、およびドメインの制約を満たしているかどうかをテストします。

  • DOMAIN_CHECK_TYPE – ドメインのデータ型と一致するように値を変換できるかどうかをテストします。

  • DOMAIN_NAME - 値に関連付けられたドメインの名前を返します。

  • DOMAIN_DISPLAY – 表示式をドメイン値に適用します。

  • DOMAIN_ORDER – 順序式をドメイン値に適用します。

例: 値がドメインに準拠しているかどうかの確認

この問合せでは、「列挙ドメインの作成」で作成した列挙ドメインに対して値42がチェックされます。
  • DOMAIN_CHECKFALSEを返します。これは、42がドメインDAYS_OF_WEEK_Dの許容値のリスト外にあるためです。

  • DOMAIN_CHECK_TYPEは、データ型に互換性があるかどうかのみをチェックします。値42とドメインDAYS_OF_WEEK_Dの両方が数値型を使用するため、TRUEが返されます。

    SELECT DOMAIN_CHECK ( days_of_week_d, 42 ),
           DOMAIN_CHECK_TYPE ( days_of_week_d, '42' );

例: 列に関連付けられたドメインの名前の取得

この問合せは、表の列INSERT_DATETIMEに関連付けられたドメインのスキーマ修飾名を返します。関連付けられたドメインがない場合、問合せはNULLを返します。

SELECT DOMAIN_NAME ( insert_datetime )
FROM   product_prices;

例: 問合せでのドメインの表示式および順序式の使用

「複数列ドメインの作成」で定義されたドメインを使用して、USドルに変換された通貨値がソートされて表示されます。

SELECT price, currency_code,
       DOMAIN_DISPLAY ( price, currency_code, usd_exchange_rate ) price_in_usd
FROM   product_prices 
ORDER  BY DOMAIN_ORDER ( price, currency_code, usd_exchange_rate );

24.5 ドメインの変更

ドメインでは、表示式と順序式、および注釈のみを追加、変更または削除できます。

別のスキーマのドメインを変更するには、ドメインが自分のスキーマ内にあるか、ALTER ANY DOMAIN権限を持っている必要があります。

例: ドメインでの表示式の変更

ALTER USECASE DOMAIN currency_d
  MODIFY DISPLAY TO_CHAR ( floor ( amount * usd_exchange_rate ), '$999,999,990.00' ) 
    || ' (' || iso_currency_code || ')';

24.6 ドメインの削除

ドメインを削除するには、DROP DOMAIN文を使用します。

ドメインが自分のスキーマ内にあるか、ユーザーにDROP ANY DOMAIN権限が必要です。

例: ドメインの削除

ドメインを削除するには、DROP USECASE DOMAIN文を使用します。たとえば:
DROP USECASE DOMAIN currency_d;
ドメインが表の列に関連付けられている場合は、エラーが発生します。FORCEオプションを使用して、列からドメインの関連付けを削除し、ドメインを削除します。たとえば:
DROP USECASE DOMAIN currency_d FORCE;
これにより、列からデフォルトの照合以外のすべてのドメイン・プロパティも削除されます。これらのプロパティを保持するには、FORCE PRESERVEオプションを使用します。たとえば:
DROP USECASE DOMAIN currency_d FORCE PRESERVE;

24.7 ドメインの展開

ドメインでは、注釈、表示式および順序式のみを変更できます。

制約などの他のプロパティを変更する場合は、新しいドメインを作成する必要があります。

ドメインを展開させるプロセスは次のとおりです:
  • 新しいプロパティを使用して新しいドメインを作成します。
  • FORCEオプションを指定して既存のドメインを削除します。オプションで、PRESERVEを使用して、ドメインに関連付けられた列のドメイン・プロパティを保持します。
  • 新しいドメインを列に関連付けます。
  • 元のドメインの不要なプロパティを表の列から削除します。

例: ドメインの展開

たとえば、挿入タイムスタンプのデフォルトを変更するには、新しいドメインINSERT_TIMESTAMP_ON_NULL_Dを作成します。次に、FORCEオプションを指定して元のドメインを削除します。これにより、表の列からドメインの関連付けが削除され、ドメインのデフォルトが削除されます。この場合、ドメインと列のデフォルトが一致する必要があるため、デフォルトを保持できません。

その後、新しいドメインが表の列に関連付けられます。
CREATE USECASE DOMAIN insert_timestamp_on_null_d AS 
  TIMESTAMP WITH LOCAL TIME ZONE 
  DEFAULT ON NULL FOR INSERT ONLY SYSTIMESTAMP
  ANNOTATIONS (
    system_generated,
    allowed_operations '["select"]' );

DROP DOMAIN insert_timestamp_d FORCE;

ALTER TABLE product_prices
  MODIFY ( insert_datetime ) 
  ADD DOMAIN insert_timestamp_on_null_d;

24.8 ドメインのデータ・ディクショナリ・ビュー

データ・ディクショナリ・ビューのセットを問い合せて、表についての情報を取得できます。

次のビューには、ドメインに関する情報が表示されます:
ビュー 説明

DBA_DOMAINS

ALL_DOMAINS

USER_DOMAINS

データベース内のドメインとそのプロパティのリスト。

DBA_DOMAIN_COLS

ALL_DOMAIN_COLS

USER_DOMAIN_COLS

各ドメインに関連付けられた列のリスト。

DBA_DOMAIN_CONSTRAINTS

ALL_DOMAIN_CONSTRAINTS

USER_DOMAIN_CONSTRAINTS

各ドメインに関連付けられた制約のリスト。

DBA_ANNOTATIONS_USAGE

ALL_ANNOTATIONS_USAGE

USER_ANNOTATIONS_USAGE

これらのビューを使用して、object_type = 'DOMAIN'のドメインの注釈を確認します。