| .. Licensed to the Apache Software Foundation (ASF) under one |
| .. or more contributor license agreements. See the NOTICE file |
| .. distributed with this work for additional information |
| .. regarding copyright ownership. The ASF licenses this file |
| .. to you under the Apache License, Version 2.0 (the |
| .. "License"); you may not use this file except in compliance |
| .. with the License. You may obtain a copy of the License at |
| .. |
| .. http://www.apache.org/licenses/LICENSE-2.0 |
| .. |
| .. Unless required by applicable law or agreed to in writing, software |
| .. distributed under the License is distributed on an "AS IS" BASIS, |
| .. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| .. See the License for the specific language governing permissions and |
| .. limitations under the License. |
| |
| .. highlight:: cql |
| |
| .. _materialized-views: |
| |
| Materialized Views |
| ------------------ |
| |
| Materialized views names are defined by: |
| |
| .. productionlist:: |
| view_name: re('[a-zA-Z_0-9]+') |
| |
| |
| .. _create-materialized-view-statement: |
| |
| CREATE MATERIALIZED VIEW |
| ^^^^^^^^^^^^^^^^^^^^^^^^ |
| |
| You can create a materialized view on a table using a ``CREATE MATERIALIZED VIEW`` statement: |
| |
| .. productionlist:: |
| create_materialized_view_statement: CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] `view_name` AS |
| : `select_statement` |
| : PRIMARY KEY '(' `primary_key` ')' |
| : WITH `table_options` |
| |
| For instance:: |
| |
| CREATE MATERIALIZED VIEW monkeySpecies_by_population AS |
| SELECT * FROM monkeySpecies |
| WHERE population IS NOT NULL AND species IS NOT NULL |
| PRIMARY KEY (population, species) |
| WITH comment='Allow query by population instead of species'; |
| |
| The ``CREATE MATERIALIZED VIEW`` statement creates a new materialized view. Each such view is a set of *rows* which |
| corresponds to rows which are present in the underlying, or base, table specified in the ``SELECT`` statement. A |
| materialized view cannot be directly updated, but updates to the base table will cause corresponding updates in the |
| view. |
| |
| Creating a materialized view has 3 main parts: |
| |
| - The :ref:`select statement <mv-select>` that restrict the data included in the view. |
| - The :ref:`primary key <mv-primary-key>` definition for the view. |
| - The :ref:`options <mv-options>` for the view. |
| |
| Attempting to create an already existing materialized view will return an error unless the ``IF NOT EXISTS`` option is |
| used. If it is used, the statement will be a no-op if the materialized view already exists. |
| |
| .. note:: By default, materialized views are built in a single thread. The initial build can be parallelized by |
| increasing the number of threads specified by the property ``concurrent_materialized_view_builders`` in |
| ``cassandra.yaml``. This property can also be manipulated at runtime through both JMX and the |
| ``setconcurrentviewbuilders`` and ``getconcurrentviewbuilders`` nodetool commands. |
| |
| .. _mv-select: |
| |
| MV select statement |
| ``````````````````` |
| |
| The select statement of a materialized view creation defines which of the base table is included in the view. That |
| statement is limited in a number of ways: |
| |
| - the :ref:`selection <selection-clause>` is limited to those that only select columns of the base table. In other |
| words, you can't use any function (aggregate or not), casting, term, etc. Aliases are also not supported. You can |
| however use `*` as a shortcut of selecting all columns. Further, :ref:`static columns <static-columns>` cannot be |
| included in a materialized view (which means ``SELECT *`` isn't allowed if the base table has static columns). |
| - the ``WHERE`` clause have the following restrictions: |
| |
| - it cannot include any :token:`bind_marker`. |
| - the columns that are not part of the *base table* primary key can only be restricted by an ``IS NOT NULL`` |
| restriction. No other restriction is allowed. |
| - as the columns that are part of the *view* primary key cannot be null, they must always be at least restricted by a |
| ``IS NOT NULL`` restriction (or any other restriction, but they must have one). |
| |
| - it cannot have neither an :ref:`ordering clause <ordering-clause>`, nor a :ref:`limit <limit-clause>`, nor :ref:`ALLOW |
| FILTERING <allow-filtering>`. |
| |
| .. _mv-primary-key: |
| |
| MV primary key |
| `````````````` |
| |
| A view must have a primary key and that primary key must conform to the following restrictions: |
| |
| - it must contain all the primary key columns of the base table. This ensures that every row of the view correspond to |
| exactly one row of the base table. |
| - it can only contain a single column that is not a primary key column in the base table. |
| |
| So for instance, give the following base table definition:: |
| |
| CREATE TABLE t ( |
| k int, |
| c1 int, |
| c2 int, |
| v1 int, |
| v2 int, |
| PRIMARY KEY (k, c1, c2) |
| ) |
| |
| then the following view definitions are allowed:: |
| |
| CREATE MATERIALIZED VIEW mv1 AS |
| SELECT * FROM t WHERE k IS NOT NULL AND c1 IS NOT NULL AND c2 IS NOT NULL |
| PRIMARY KEY (c1, k, c2) |
| |
| CREATE MATERIALIZED VIEW mv1 AS |
| SELECT * FROM t WHERE k IS NOT NULL AND c1 IS NOT NULL AND c2 IS NOT NULL |
| PRIMARY KEY (v1, k, c1, c2) |
| |
| but the following ones are **not** allowed:: |
| |
| // Error: cannot include both v1 and v2 in the primary key as both are not in the base table primary key |
| CREATE MATERIALIZED VIEW mv1 AS |
| SELECT * FROM t WHERE k IS NOT NULL AND c1 IS NOT NULL AND c2 IS NOT NULL AND v1 IS NOT NULL |
| PRIMARY KEY (v1, v2, k, c1, c2) |
| |
| // Error: must include k in the primary as it's a base table primary key column |
| CREATE MATERIALIZED VIEW mv1 AS |
| SELECT * FROM t WHERE c1 IS NOT NULL AND c2 IS NOT NULL |
| PRIMARY KEY (c1, c2) |
| |
| |
| .. _mv-options: |
| |
| MV options |
| `````````` |
| |
| A materialized view is internally implemented by a table and as such, creating a MV allows the :ref:`same options than |
| creating a table <create-table-options>`. |
| |
| |
| .. _alter-materialized-view-statement: |
| |
| ALTER MATERIALIZED VIEW |
| ^^^^^^^^^^^^^^^^^^^^^^^ |
| |
| After creation, you can alter the options of a materialized view using the ``ALTER MATERIALIZED VIEW`` statement: |
| |
| .. productionlist:: |
| alter_materialized_view_statement: ALTER MATERIALIZED VIEW `view_name` WITH `table_options` |
| |
| The options that can be updated are the same than at creation time and thus the :ref:`same than for tables |
| <create-table-options>`. |
| |
| .. _drop-materialized-view-statement: |
| |
| DROP MATERIALIZED VIEW |
| ^^^^^^^^^^^^^^^^^^^^^^ |
| |
| Dropping a materialized view users the ``DROP MATERIALIZED VIEW`` statement: |
| |
| .. productionlist:: |
| drop_materialized_view_statement: DROP MATERIALIZED VIEW [ IF EXISTS ] `view_name`; |
| |
| If the materialized view does not exists, the statement will return an error, unless ``IF EXISTS`` is used in which case |
| the operation is a no-op. |
| |
| MV Limitations |
| ``````````````` |
| |
| .. Note:: Removal of columns not selected in the Materialized View (via ``UPDATE base SET unselected_column = null`` or |
| ``DELETE unselected_column FROM base``) may shadow missed updates to other columns received by hints or repair. |
| For this reason, we advise against doing deletions on base columns not selected in views until this is |
| fixed on CASSANDRA-13826. |