When To Use JSON-Type Columns for a Duality View
Whether to store some of the data underlying a duality view as
JSON data type and, if so, whether to enforce its structure and
typing, are design choices to consider when defining a JSON-relational duality
view.
By storing some JSON data that contributes to the JSON documents supported by (generated by) a duality view, you can choose the granularity and complexity of the building blocks that define the view. Put differently, you can choose the degree of normalization you want for the underlying data. Different choices involve different tradeoffs.
When the table data underlying a duality view is completely normalized, in which case the table columns contain only values of scalar SQL data types, the structure of the documents supported by the view, and the types of its fields, are fixed and strictly defined using relational constructs.
Although normalization reduces schema flexibility, complete normalization gives you the most flexibility in terms of combining data from multiple tables to support different kinds of duality view (more generally, in terms of combining some table data with other table data, outside of any use for duality views).
And in an important particular use case, complete normalization lets you access the data in existing relational tables from a document-centric application, as JSON documents.
On the other hand, the greater the degree of normalization, the more tables you have, which means more decomposition when inserting or updating JSON data and more joining (recomposition) when querying it. If an application typically accesses complex objects as a whole, then greater normalization can thus negatively impact performance.
Like any other column in a table underlying a duality view, a
JSON-type column can be shared among different duality
views, and thus its values can be shared in their different resulting (generated) JSON
documents.
By default, a JSON value is free-form: its structure and typing are not defined by, or forced to conform to, any given pattern/schema. In this case, applications can easily change the shape and types of the values as needed — schema flexibility.
You can, however, impose typing and structure on the data in a JSON-type
column, using JSON Schema. JSON Schema gives you a full spectrum of control:
-
From fields whose values are completely undefined to fields whose values are strictly defined.
-
From scalar JSON values to large, complex JSON objects and arrays.
-
From simple type definitions to combinations of JSON-language types. For example:
-
A value that satisfies
anyOf,allOf, oroneOfa set of JSON schemas -
A value that does
notsatisfy a given JSON schema
-
Note:
Using, in a duality-view definition, a JSON-type column
that's constrained by a JSON schema to hold only data of a particular JSON
scalar type (date, string, etc.) that corresponds to a SQL scalar type
(DATE, VARCHAR2, etc.) has the same effect
on the JSON documents supported by the view as using a column of the
corresponding SQL scalar type.
However, code that acts directly on such stored
JSON-type data won't necessarily recognize and take into
account this correspondence. The SQL type of the data is, after all,
JSON, not DATE, VARCHAR2,
etc. To extract a JSON scalar value as a value of a SQL scalar data type, code needs
to use SQL/JSON function json_value. See SQL/JSON Function JSON_VALUE in Oracle AI Database JSON
Developer’s Guide.
Let's summarize some of the tradeoffs between using SQL scalar columns
and JSON-type columns in a table underlying a duality view:
-
Flexibility of combination. For the finest-grain combination, use completely normalized tables, whose columns are all SQL scalars.
-
Flexibility of document type and structure. For maximum flexibility of JSON field values at any given time, and thus also for changes over time (evolution), use
JSON-type columns with no JSON-schema constraints. -
Granularity of field definition. The finest granularity requires a column for each JSON field, regardless of where the field is located in documents supported by the duality view. (The field value could nevertheless be a JSON object or array, if the column is
JSON-type.)
If it makes sense for your application to share some complex JSON data
among different kinds of documents, and if you expect to have no need for combining
only parts of that complex data with other documents or, as SQL scalars, with
relational data, then consider using JSON data type for the columns
underlying that complex data.
In other words, in such a use case consider sharing JSON documents, instead of sharing the scalar values that constitute them. In still other words, consider using more complex ingredients in your duality-view recipe.
Note that the granularity of column data — how complex the data in it can be
— also determines the granularity of updating operations and ETAG-checking (for
optimistic concurrency control). The smallest unit for such operations is an individual
column underlying a duality view; it's impossible to annotate
individual fields inside a JSON-type column.
Update operations can selectively apply to particular fields
contained in the data of a given JSON-type column, but control of
which update operations can be used with a given view is defined at the level of
an underlying column or whole table — nothing smaller. So if you need finer grain
updating or ETAG-checking then you need to break out the relevant parts of the
JSON data into their own JSON-type columns.
See Also:
-
Validating JSON Documents with a JSON Schema for information about using JSON schemas to constrain or validate JSON data
-
json-schema.org for information about JSON Schema