10 Registering Application Data Usage with the Database
This chapter details how you can use a centralized database-centric entity called schema annotations to register information about the intended application data usage.
Oracle Database 19c introduces a centralized, database-centric approach to handling intended data usage information using schema annotations. You can add schema annotations centrally in the database to register data usage intent, which is then accessible to various applications and tools.
See Also:
-
Oracle Database Concepts for information about Schema Annotations
-
Oracle Database SQL Language Reference for the syntactic and semantic information about schema annotations
10.1 Schema Annotations
This section explains how you can use schema annotations (hereinafter "annotations") for database objects.
For many applications, it is important to maintain additional property metadata for database objects such as tables, views, table columns, and indexes. Annotations enable your applications to store and retrieve additional user-specific metadata about database objects and table columns. Applications can use such metadata to help render effective user interfaces and customize application logic.
10.1.1 Overview of Annotations
What are annotations and where can you use them?
Annotations are a lightweight declarative facility for developers to centrally register usage properties for database schema objects. Annotations are stored in dictionary tables and are available to any application looking to standardize behavior across common data in related applications. Annotations are not interpreted by the database in any way. They are custom data properties for database metadata - included for table columns, tables, and indexes, that applications can use as additional property metadata to render user interfaces or customize application logic.
Being a mechanism to define and store application metadata centrally in the
database, annotations enable you to share the metadata information across applications,
modules and microservices. You can add annotations to schema objects when you create new
objects (using the CREATE
statements) or modify existing objects (using
the ALTER
statements).
Annotating the data model with metadata provides additional data integrity, consistency and data model documentation benefits. Your applications can store user-defined metadata for database objects and table columns that other applications or users can retrieve and use. Storing the metadata along with the data guarantees consistency and universal accessibility to any user or application that uses the data.
An individual annotation has a name and an optional value. The name and the
optional value are freeform text fields. For example, you can have an annotation with a
name and value pair, such as Display_Label ‘Employee Salary’
, or you
can have a standalone annotation with only a name, such as UI_Hidden
,
which does not need a value because the name is self-explanatory.
The following are further details about annotations.
-
When an annotation name is specified for a schema object using the
CREATE
DDL statement, an annotation is automatically created. -
Annotations are additive, meaning that you can specify multiple annotations for the same schema object.
-
You can add multiple annotations at once to a schema object using a single DDL statement. Similarly, a single DDL statement can drop multiple annotations from a schema object.
-
An annotation is represented as a subordinate element to the database object to which the annotation is added. Annotations do not create a new object type inside the database.
-
You can add annotations to any schema object that supports annotations provided you own or have alter privileges on the schema object. You do not need to schema qualify the annotation name.
-
You can issue SQL queries on dictionary views to obtain all annotations, including their names and values, and their usage with schema objects.
10.1.2 Annotations and Comments
You can also annotate database objects such as tables and table columns using
the COMMENT
command. Comments that are associated with schema objects
are stored in data dictionaries along with the metadata of the objects.
Annotations are simpler to use and have a broader scope than comments. Following are the major differences between comments and annotations:
-
Comments are a commenting mechanism used to add metadata to only certain schema objects, such as tables and columns. Comments are not available for other schema objects, such as indexes, procedures, and triggers.
-
Comments do not have a name, they have only a freeform value.
-
Comments are not additive meaning that you cannot add multiple comments for the same object. Specifying a new comment overwrites the prior comment for the corresponding table or column.
-
You need separate DDL statements for comments whereas you can combine multiple annotations into one DDL statement.
-
A separate set of dictionary views exists for different entities. For instance, there is a view for table comments and another view for column comments. Annotations, on the other hand, are unified across all object types, which makes them simpler to query and use.
See Also:
Comments for more information about using
COMMENTS
.
10.1.3 Supported Database Objects
Annotations are supported for the following database objects.
-
Tables and table columns
-
Views and view columns
-
Materialized views and materialized view columns
-
Indexes
10.1.4 Privileges Required for Using Annotations
To add or drop annotations, you require the CREATE
or
ALTER
privilege on the schema object for which the annotation is
specified in the CREATE
or ALTER
DDL statements.
You cannot create or remove annotations explicitly. Annotations are automatically created when they are used for the first time. Since annotations are stored as subordinate elements within the database object on which they are defined, adding annotations does not create a new object type inside the database.
10.1.5 DDL Statements for Annotations
This section explains the annotation syntax and provides the DDL statements to define or alter annotations for tables, table columns, views, materialized views, and indexes.
Topics:
10.1.5.1 Annotation Syntax
The following snippet illustrates the annotation syntax that is used in DDL statements to define annotations for tables, table columns, views, materialized views, and indexes.
annotations ::= 'ANNOTATIONS' '(' annotations_list ')' annotations_list ::= ( 'ADD' ('IF NOT EXISTS' | 'OR REPLACE' )? | 'DROP' 'IF EXISTS'? | REPLACE)? annotation ( ',' ( 'ADD' ('IF NOT EXISTS' | 'OR REPLACE' )? | 'DROP' 'IF EXISTS'? | REPLACE)? annotation )* annotation ::= annotation_name annotation_value? annotation_name ::= identifier annotation_value ::= character_string_literal
<annotation_value
> is a character string literal that can hold up
to 4000 characters.
<annotation_name
> is an identifier and has the
following requirements:
-
An identifier can have up to 1024 characters.
-
If an identifier is a reserved word, you must provide the annotation name in double quotes.
-
An identifier with double quotes can contain white characters.
-
An identifier that contains only white characters is not allowed.
10.1.5.2 DDL Statements to Annotate a Table
You can use the following DDL statements to annotate a table when creating or altering the table.
Using the CREATE TABLE
Statement
The following are examples of the CREATE TABLE
statement
with annotations.
The following example adds an annotation: Operation
with a JSON value, and another annotation: Hidden
, which is
standalone and has no value.
CREATE TABLE Table1 ( T NUMBER) ANNOTATIONS(Operations '["Sort", "Group"]', Hidden);
Adding an annotation can be preceded by the ADD
keyword. The ADD
keyword is considered to be the default operation,
if nothing is specified.
The following example uses the optional ADD
keyword to
add the Hidden
annotation (which is also standalone) to
Table2
.
CREATE TABLE Table2 ( T NUMBER) ANNOTATIONS (ADD Hidden);
The ADD
keyword is an implicit operation when
annotations are defined, and can be omitted.
Using the ALTER TABLE
Statement
In the following example, the ALTER TABLE
command drops
all annotation values for the following annotation names:
Operations
and Hidden
.
ALTER TABLE Table1 ANNOTATIONS(DROP Operations, DROP Hidden);
The following example has the ALTER TABLE
command to
add JoinOperations
annotation with Join
value, and
to drop the annotation name: Hidden
. When dropping an annotation,
you need to only include the annotation name with the DROP
command.
ALTER TABLE Table1 ANNOTATIONS(ADD JoinOperations 'Join', DROP Hidden);
Due to the Hidden annotation being dropped in the earlier statement, the output is:
ORA-11553: Annotation name 'HIDDEN' does not exist for the object
'Table1'
. To avoid this error: when the annotation does not exist, you
can use the IF EXISTS clause.
ALTER TABLE Table1 ANNOTATIONS(ADD JoinOperations 'Join', DROP IF EXISTS Hidden);
Multiple ADD
and DROP
keywords can be
specified in one DDL statement.
ALTER TABLE Table1 ANNOTATIONS(ADD JoinOperations 'Join Ops');
The output is:
ORA-11552: Annotation name 'JOINOPERATIONS' already exists for the object 'TABLE1'.
REPLACE
keyword. The following statement
replaces the value of JoinOperations
with 'Join
Ops
':ALTER TABLE Table1 ANNOTATIONS(REPLACE JoinOperations 'Join Ops');
The output is
Table altered.
IF NOT EXISTS
clause. The following statement adds the
JoinOperations
annotation only if it does not exist. If the
annotation exists, the annotation value is unchanged and no error is
raised.ALTER TABLE Table1 ANNOTATIONS(ADD IF NOT EXISTS JoinOperations 'Join Ops');
ALTER TABLE Table1 ANNOTATIONS(DROP Title);
The output is:
ORA-11553: Annotation name 'TITLE' does not exist.
IF EXISTS
clause can be used, as
follows:ALTER TABLE Table1 ANNOTATIONS(DROP IF EXISTS Title);
The output is:
Table altered.
See Also:
CREATE TABLE and ALTER TABLE in SQL Language Reference for complete clause changes and definitions.
10.1.5.3 DDL Statements to Annotate a Table Column
You can use the following DDL statements to annotate a table column when creating or altering the table.
Using the CREATE TABLE
Statement
To add column-level annotations using a CREATE TABLE
statement, specify the annotations as a part of the
column_definition
clause. Annotations are specified at the end,
after inline constraints.
The following examples specify annotations for columns at table creation.
CREATE TABLE Table1 (T NUMBER ANNOTATIONS(Operations 'Sort', Hidden)); CREATE TABLE Table2 (T NUMBER ANNOTATIONS (Hidden));
The following example specifies table-level and column-level annotations for the
Employee
table.
CREATE TABLE Employee ( Id NUMBER(5) ANNOTATIONS(Identity, Display 'Employee ID', "Group" 'Emp_Info'), Ename VARCHAR2(50) ANNOTATIONS(Display 'Employee Name', "Group" 'Emp_Info'), Sal NUMBER ANNOTATIONS(Display 'Employee Salary', UI_Hidden) ) ANNOTATIONS (Display 'Employee Table');
The Employee
table in the previous example has
column-level and object-level annotations with Display
annotations
defined at the column level and object level. You can define a new annotation with
the same name as long as it corresponds to a different object, column pair. For
instance, you cannot define another annotation with the Display
name for the Employee
table but you can define new annotations with
Display
name for every column of the Employee
table. You can also define other annotations such as "Group
" for
the Sal
column. The annotation "Group
" needs to be
double quoted because it is a reserved word.
Using the ALTER TABLE
Statement
To add column-level annotations using an ALTER TABLE
statement, specify the annotations as a part of the
modify_col_properties
clause. Annotations are specified at the
end, after inline constraints.
The following example adds a new Identity
annotation for the column
T of Table1
table.
ALTER TABLE Table1 MODIFY T ANNOTATIONS(Identity 'ID');
The following example adds a Label
annotation and drops the
Identity
annotation.
ALTER TABLE Table1 MODIFY T ANNOTATIONS(ADD Label, DROP Identity);
See Also:
CREATE TABLE and ALTER TABLE in SQL Language Reference for complete clause changes and definitions.
10.1.5.4 DDL Statements to Annotate Views and Materialized Views
You can use the following DDL statements to annotate a view and a materialized view.
Views and materialized views support annotations at the view level and column level. Column-level annotations are only supported for table views as a part of the column alias definition clause.
Using the CREATE
VIEW
Statement
The following example shows the view-level and column-level annotations:
CREATE OR REPLACE VIEW HighWageEmp ( Id ANNOTATIONS(Identity, Display 'Employee ID', "Group" 'Emp_Info'), Ename ANNOTATIONS (Display 'Employee Name', "Group" 'Emp_Info'), Sal ANNOTATIONS (Display 'Emp Salary') ) ANNOTATIONS (Title 'High Wage Employee View') AS SELECT * FROM EMPLOYEE WHERE Sal > 100000;
Using the CREATE
MATERIALIZED VIEW
Statement
The following example adds annotation at the view level in the
Materialized View
statement:
CREATE MATERIALIZED VIEW MView1 ANNOTATIONS (Title 'Tab1 MV1', ADD Snapshot) AS SELECT * FROM Table1;
The following example adds annotation at the view level and column level
in the Materialized View
statement:
CREATE MATERIALIZED VIEW MView1( T ANNOTATIONS (Hidden)) ANNOTATIONS (Title 'Tab1 MV1', ADD Snapshot) AS SELECT * FROM Table1;
Using the ALTER
VIEW
Statement
To provide support for annotations, the ALTER VIEW
statement has a new sub-clause added to it that allows altering annotations at the
view level. Other sub-clauses that are supported in the ALTER VIEW
statement are: modifying view constraints, enabling recompilation, and changing
EDITIONABLE
property.
Column-level annotations for views cannot be altered. Previously added column-level annotations can be dropped only by dropping the view and recreating a new one.
The following example is an ALTER VIEW
statement that
drops the Title
annotation and adds the Identity
annotation at the view level.
ALTER VIEW HighWageEmp ANNOTATIONS(DROP Title, ADD Identity);
Using the ALTER
MATERIALIZED VIEW
Statement
The ALTER MATERIALIZED VIEW
statement has a new
sub-clause that is added to alter annotations globally at the materialized view
level. Column-level annotations can be dropped only by dropping and recreating the
materialized view.
The following ALTER MATERIALIZED VIEW
statement drops
Snapshot
annotation from MView1
.
ALTER MATERIALIZED VIEW MView1 ANNOTATIONS(DROP Snapshot);
See Also:
CREATE VIEW, ALTER VIEW, CREATE MATERIALIZED VIEW, and ALTER MATERIALIZED VIEW in SQL Language Reference for complete clause changes and definitions.
10.1.5.5 DDL Statements to Annotate Indexes
You can use the following DDL statements to annotate an index.
Using the CREATE INDEX
Statement
The following are examples of creating index-level annotations.
CREATE TABLE DEPARTMENT( DEPT_ID NUMBER, UNIT NUMBER); CREATE INDEX I_DEPT_ID ON DEPARTMENT(DEPT_ID) ANNOTATIONS(Display 'Department Index'); CREATE UNIQUE INDEX UI_UNIT ON DEPARTMENT(UNIT) ANNOTATIONS(Display 'Department Unique Index');
Using the ALTER INDEX
Statement
The following is an example of altering an index-level annotation.
ALTER INDEX I_DEPT_ID ANNOTATIONS(DROP Display, ADD ColumnGroup 'Group1');
See Also:
CREATE INDEX and ALTER INDEX in SQL Language Reference for complete clause changes and definitions.
10.1.6 Dictionary Table and Views
A dictionary table called ANNOTATIONS_USAGE$
includes all
the usage of annotations with schema objects, such as tables and views. When a new
annotation name, value, or both are specified to a schema object, a new entry in
ANNOTATIONS_USAGE$
table is created. Similarly, when a schema
object drops an annotation, the corresponding entry is dropped from the
ANNOTATIONS_USAGE$
table.
The following dictionary views track the list of annotations and their usage across all schema objects:
-
{DBA|USER|ALL|CDB}_ANNOTATIONS
-
{DBA|USER|ALL|CDB}_ANNOTATIONS_USAGE
-
{DBA|USER|ALL|CDB}_ANNOTATIONS_VALUES
10.1.6.1 Querying Dictionary Views
You can run queries on dictionary views to obtain the list of annotations that are used for specific schema objects.
Here are examples of query statements issued on an 'EMP' table:
SELECT * FROM USER_ANNOTATIONS_USAGE WHERE Object_Name = 'EMPLOYEE' AND Object_Type = 'TABLE' AND Column_Name IS NULL;
SELECT * FROM USER_ANNOTATIONS_USAGE WHERE Object_Name = 'EMPLOYEE' AND Object_Type = 'TABLE' AND Column_Name IS NOT NULL;
SELECT U.Column_Name, JSON_ARRAYAGG(JSON_OBJECT(U.Annotation_Name, U.Annotation_Value)) FROM USER_ANNOTATIONS_USAGE U WHERE Object_Name = 'EMPLOYEE' AND Object_Type = 'TABLE' AND Column_Name IS NOT NULL GROUP BY Column_Name;