Abfragen für kontinuierlich aktualisierte materialisierte Ansichten
Wenn Sie eine kontinuierlich aktualisierte materialisierte Ansicht einer Bigtable-Tabelle erstellen möchten, führen Sie eine SQL-Abfrage aus, die die kontinuierlich aktualisierte materialisierte Ansicht definiert.
In diesem Dokument werden Konzepte und Muster beschrieben, die Ihnen bei der Vorbereitung Ihrer SQL-Abfrage für kontinuierlich aktualisierte materialisierte Ansichten helfen. Bevor Sie dieses Dokument lesen, sollten Sie mit kontinuierlich aktualisierten materialisierten Ansichten und GoogleSQL für Bigtable vertraut sein.
Kontinuierlich aktualisierte materialisierte Ansichten verwenden eine eingeschränkte SQL-Syntax. Das folgende Muster zeigt, wie Sie eine SQL-Abfrage für eine kontinuierlich aktualisierte materialisierte Ansicht erstellen:
SELECT
expression AS alias [, ...]
FROM from_item
[ WHERE bool_expression ]
GROUP BY expression [, ...];
from_item:
{
table_name [ as_alias ]
| field_path
}
as_alias:
[ AS ] alias
Wenn Sie eine SQL-Abfrage für eine kontinuierlich aktualisierte materialisierte Ansicht als asynchronen sekundären Index erstellen möchten, verwenden Sie die ORDER BY-Klausel:
SELECT
expression AS alias [, ...]
FROM from_item
[ WHERE bool_expression ]
ORDER BY expression [, ...];
from_item:
{
table_name [ as_alias ]
| field_path
}
as_alias:
[ AS ] alias
SQL-Abfragen, die nicht deterministische Funktionen verwenden, unterscheiden sich semantisch von anderen Abfragen für kontinuierlich aktualisierte materialisierte Ansichten. Weitere Informationen finden Sie im Abschnitt Nicht deterministische Abfragen in diesem Dokument.
Abfragebeschränkungen
Die folgenden Regeln gelten für eine SQL-Abfrage, die zum Erstellen einer kontinuierlich aktualisierten materialisierten Ansicht verwendet wird:
- Muss eine
SELECT-Anweisung sein. - Muss eine
GROUP BY-Klausel oder für Abfragen für asynchrone sekundäre Indizes eineORDER BY-Klausel enthalten, aber nicht beides. - Darf nur unterstützte Aggregatfunktionen verwenden.
- Kann mehrere Aggregationen pro Gruppe enthalten.
Unterstützte Aggregationen
Sie können die folgenden Aggregatfunktionen in einer SQL-Abfrage verwenden, die eine kontinuierlich aktualisierte materialisierte Ansicht definiert:
COUNTSUMMINMAXHLL_COUNT.INITHLL_COUNT.MERGEHLL_COUNT.MERGE_PARTIALANY_VALUEBIT_ANDBIT_ORBIT_XORAVG
Wenn Sie SELECT COUNT(*) verwenden, müssen Sie einen Zeilenschlüssel definieren, wie im folgenden Beispiel:
SELECT
'*' AS _key,
COUNT(*) AS count
FROM
foo
GROUP BY
_key;
Nicht unterstützte SQL-Features
Sie können die folgenden SQL-Features nicht verwenden:
- Alle Features, die von GoogleSQL für Bigtable nicht unterstützt werden
ARRAYARRAY_AGGARRAY_CONCAT_AGGCOUNT_IFCURRENT_TIMEund die meisten anderen nicht deterministischen Funktionen, mit Ausnahmen.DATE,DATETIMEals Ausgabespalten (TIMESTAMPverwenden oder einen String speichern)DESC-Sortierung in der AusgabeDISTINCT-Option, wie inSUM(*DISTINCT* value)LIMIT/OFFSETSELECT *OVER-Anweisung zum Erstellen einer FensteraggregationSTRUCT
Außerdem können Sie GROUP BY- oder ORDER BY-Klauseln nicht verschachteln oder Map-Spalten erstellen. Weitere
Beschränkungen finden Sie unter
Beschränkungen.
Ausgeschlossene Zeilen vermeiden
Eingabezeilen werden unter den folgenden Umständen aus einer kontinuierlich aktualisierten materialisierten Ansicht ausgeschlossen:
- Aus der Zeile werden mehr als 1 MiB Daten ausgewählt. Wenn Ihre
Abfrage
SELECT apple AS apples , SUM(banana) AS sum_bananas FROM my_table GROUP BY appleslautet, werden alle Zeilen, die mehr als 1 MiB Daten in denappleundbananaSpalten enthalten, aus der kontinuierlich aktualisierten materialisierten Ansicht ausgeschlossen. - Aus der Zeile werden mehr als 1 MiB Daten ausgegeben. Dies kann vorkommen, wenn Sie Abfragen wie
SELECT REPEAT(apple, 1000)verwenden oder große Konstanten verwenden. - Es werden mehr als zehnmal so viele Daten ausgegeben als ausgewählt wurden.
- Die Abfrage stimmt nicht mit Ihren Daten überein. Dazu gehört der Versuch, durch null zu teilen, ein Ganzzahlüberlauf oder die Erwartung eines Zeilenschlüsselformats, das nicht in jedem Zeilenschlüssel verwendet wird.
Ausgeschlossene Zeilen erhöhen den Messwert für Nutzerfehler, wenn sie zum ersten Mal verarbeitet werden. Weitere Informationen zu Messwerten, mit denen Sie Ihre kontinuierlich aktualisierten materialisierten Ansichten überwachen können, finden Sie unter Messwerte.
Abfragedetails
In diesem Abschnitt wird eine Abfrage für eine kontinuierlich aktualisierte materialisierte Ansicht beschrieben und wie die Ergebnisse aussehen können, wenn die Ansicht abgefragt wird. Die Daten in der Quelltabelle sind die Eingabe und die Ergebnisdaten in der kontinuierlich aktualisierten materialisierten Ansicht sind die Ausgabe. Ausgabedaten sind entweder aggregiert oder nicht aggregiert (im definierten Schlüssel).
SELECT-Anweisung
Mit der SELECT-Anweisung werden die Spalten und Aggregationen konfiguriert, die in der kontinuierlich aktualisierten materialisierten Ansicht verwendet werden. Die Anweisung muss entweder eine GROUP BY-Klausel zum Aggregieren über Zeilen hinweg oder eine ORDER BY-Klausel zum Erstellen eines asynchronen sekundären Index verwenden.
SELECT * wird nicht unterstützt, SELECT COUNT(*) aber schon.
Wie in einer typischen SELECT-Anweisung können Sie mehrere Aggregationen pro gruppiertem Datensatz haben. Die nicht gruppierten Spalten müssen ein Aggregationsergebnis sein.
Hier ist ein Beispiel für eine Standard-GROUP BY-Aggregationsabfrage in SQL:
SELECT
myfamily["node"] AS node,
myfamily["type"] AS type,
COUNT(clicks) AS clicks_per_key
FROM
mytable
GROUP BY
node,
type
Zeilenschlüssel und nicht aggregierte Daten
Sie können _key als Zeilenschlüssel für eine kontinuierlich aktualisierte materialisierte Ansicht angeben. Andernfalls bilden die Spalten in der GROUP BY-Klausel den Schlüssel in der Ansicht.
Zeilenschlüssel, die durch eine _key-Spalte definiert werden
Optional können Sie eine _key-Spalte angeben, wenn Sie Ihre kontinuierlich aktualisierte materialisierte Ansicht definieren. (Dies unterscheidet sich von der _key
Spalte, die Sie erhalten, wenn
Sie eine SQL-Abfrage für eine Bigtable-Tabelle ausführen.) Wenn Sie _key angeben, gelten die folgenden Regeln:
- Sie müssen nach
_keygruppieren und können optional nur nach_timestampgruppieren. Weitere Informationen finden Sie unter Zeitstempel. - Die Spalte
_keymuss vom TypBYTESsein.
Die Angabe von _key ist nützlich, wenn Sie die Ansicht mit ReadRows und nicht mit SQL lesen möchten, da Sie so das Format des Zeilenschlüssels steuern können. Andererseits muss bei einer SQL-Abfrage für eine Ansicht mit einem definierten _key der _key möglicherweise explizit decodiert werden, anstatt nur strukturierte Schlüsselspalten zurückzugeben.
Zeilenschlüssel, die durch die GROUP BY- oder ORDER BY-Klausel definiert werden
Wenn Sie keinen _key angeben, werden die nicht aggregierten Spalten in Ihrer SELECT-Liste zum Zeilenschlüssel in der Ansicht. Sie können den Schlüsselspalten beliebige Namen zuweisen, die den SQL-Konventionen entsprechen. Verwenden Sie diesen Ansatz, wenn Sie die Ansicht mit SQL abfragen möchten und keine ReadRows-Anfrage verwenden möchten.
Nicht aggregierte Ausgabespalten in der SELECT Liste müssen in der GROUP
BY Klausel enthalten sein. Die Reihenfolge, in der die Spalten in der GROUP BY-Klausel geschrieben werden, ist die Reihenfolge, in der die Daten im Zeilenschlüssel der kontinuierlich aktualisierten materialisierten Ansicht gespeichert werden. Zum Beispiel, GROUP BY a, b, c entspricht implizit ORDER BY a ASC, b ASC, c
ASC.
Wenn Sie anstelle einer GROUP BY-Klausel eine ORDER BY-Klausel verwenden, um einen asynchronen sekundären Index zu erstellen, werden die Spalten in Ihrer SELECT-Liste, die Teil der ORDER BY-Klausel sind, zum Zeilenschlüssel in der Ansicht. Die Reihenfolge, in der die Spalten in der ORDER BY-Klausel geschrieben werden, ist die Reihenfolge, in der die Daten im Zeilenschlüssel der kontinuierlich aktualisierten materialisierten Ansicht gespeichert werden. Bei ORDER BY a, b, c werden die Daten mit Zeilenschlüsseln gespeichert, die nach a ASC, dann nach b ASC und dann nach c ASC sortiert sind.
Ihr SQL-Filter muss potenzielle NULL-Werte oder andere ungültige Werte entfernen, die Fehler verursachen können. Eine ungültige Zeile, z. B. eine Zeile mit einer NULL-Schlüsselspalte, wird aus den Ergebnissen entfernt und im Messwert materialized_view/user_errors gezählt. Wenn Sie Nutzerfehler beheben möchten, führen Sie die SQL-Abfrage außerhalb einer kontinuierlich aktualisierten materialisierten Ansicht aus.
Aggregierte Daten
Aggregatspalten in der Abfrage definieren die Berechnungen, mit denen die Daten in der kontinuierlich aktualisierten materialisierten Ansicht generiert werden.
Der Alias für eine Aggregatspalte wird in der kontinuierlich aktualisierten materialisierten Ansicht als Spaltenqualifizierer behandelt.
Beispiel:
SELECT
fam["baz"] AS baz,
SUM(fam["foo"]) AS sum_foo,
SUM(fam["bar"]) AS sum_bar
FROM
TABLE
GROUP BY
baz;
Die Abfrageausgabe hat die folgenden Merkmale:
- Die Ausgabe für jedes
bazbefindet sich in einer separaten Zeile in der Reihenfolgebaz ASC. - Wenn ein bestimmtes
bazmindestens einfoohat, istsum_fooin der Ausgabespalte kein NULL-Wert. - Wenn ein bestimmtes
bazmindestens einbarhat, istsum_barin der Ausgabespalte kein NULL-Wert. - Wenn ein bestimmtes
bazkeinen Wert für eine der beiden Spalten hat, wird es aus den Ergebnissen entfernt.
Wenn Sie die Ansicht dann mit SELECT * abfragen, sieht das Ergebnis so ähnlich aus:
| baz | sum_foo | sum_bar |
|---|---|---|
| baz1 | sum_foo1 | sum_bar1 |
| baz2 | sum_foo2 | sum_bar2 |
Zeitstempel
Der Standardzeitstempel für eine Ausgabezelle in einer kontinuierlich aktualisierten materialisierten Ansicht ist 0 (1970-01-01 00:00:00Z). Dieser Zeitstempel ist sichtbar, wenn Sie die Ansicht mit ReadRows lesen, aber nicht, wenn Sie sie mit SQL abfragen.
Wenn Sie einen anderen Zeitstempel in der Ausgabe verwenden möchten, können Sie der SELECT-Liste der Abfrage eine Spalte vom Typ TIMESTAMP hinzufügen und sie _timestamp nennen.
Wenn Sie die kontinuierlich aktualisierte materialisierte Ansicht mit ReadRows abfragen, wird _timestamp zum Zeitstempel für die anderen Zellen in der Zeile.
Ein Zeitstempel darf nicht NULL sein, muss größer oder gleich null sein und muss ein Vielfaches von 1.000 sein (Millisekundengenauigkeit). Bigtable unterstützt keine Zellzeitstempel, die vor der Unix-Epoche (1970-01-01T00:00:00Z) liegen.
Betrachten Sie das folgende Beispiel, in dem aggregierte Daten nach Tag neu abgetastet werden. Die Abfrage verwendet die Funktion UNPACK.
SELECT
_key,
TIMESTAMP_TRUNC(_timestamp, DAY) AS _timestamp,
SUM(sum_family["sum_column"]) AS sum_column,
SUM(sum_family["foo"]) AS second_sum_column
FROM
UNPACK(
SELECT
*
FROM
my_table(with_history => TRUE))
GROUP BY
1,
2
Wenn ein bestimmtes SUM für einen bestimmten Tag eine nicht leere Eingabe hat, enthält die Ausgabespalte einen aggregierten Wert mit einem Zeitstempel, der mit dem abgeschnittenen Tag übereinstimmt.
Wenn Sie die Ansicht mit SELECT * abfragen, sieht das Ergebnis so ähnlich aus:
| _key | _timestamp | sum_column | second_sum_column |
|---|---|---|---|
| 1 | 2024-05-01 00:00:00Z | 23 | 99 |
| 2 | 2024-05-02 00:00:00Z | 45 | 201 |
| 3 | 2024-05-03 00:00:00Z | NULL | 56 |
| 4 | 2024-05-04 00:00:00Z | 8 | NULL |
Nicht deterministische Abfragen
Kontinuierlich aktualisierte materialisierte Ansichten unterstützen die folgenden nicht deterministischen SQL-Funktionen.
Die Funktion für Clusterattribute
Mit der Funktion CLUSTER_ATTRIBUTE() können Sie programmatisch auf Metadaten zum Bigtable-Cluster zugreifen, der die Abfrage für die kontinuierlich aktualisierte materialisierte Ansicht ausführt. Das Attribut cluster_id gibt die String-ID des Clusters zurück, der die Ansicht verarbeitet.
Ansicht auf einen einzelnen Cluster beschränken
Wenn Sie die Berechnung und Speicherung von kontinuierlich aktualisierten materialisierten Ansichten auf einen einzelnen
Cluster beschränken möchten, z. B. einen dedizierten Analyse- oder Berichtscluster, vergleichen Sie
CLUSTER_ATTRIBUTE('cluster_id') mit einem konstanten Stringliteral, das die
Cluster-ID enthält:
SELECT
metrics['sensor_id'] AS sensor_id,
COUNT(1) AS reading_count
FROM `TABLE_ID`
WHERE CLUSTER_ATTRIBUTE('cluster_id') = 'CLUSTER_ID'
GROUP BY 1
Ersetzen Sie Folgendes:
TABLE_ID: Die eindeutige ID der Bigtable-Tabelle.CLUSTER_ID: Die ID des Clusters, in dem Sie die Ansicht materialisieren möchten.
Diese Abfrage verhält sich in Ihrer Instanz so:
- Designierter Cluster: Auf dem Cluster, der mit
CLUSTER_IDübereinstimmt, wird dieWHEREBedingung alstrueausgewertet. Bigtable aggregiert alle Daten aus der Quelltabelle, unabhängig davon, welcher Cluster sie aufgenommen oder repliziert hat, und materialisiert diese Daten in der Kopie der Ansicht dieses Clusters. - Andere Cluster: Auf allen anderen Clustern in der Instanz wird
CLUSTER_ATTRIBUTE('cluster_id')zu den jeweiligen Cluster-IDs ausgewertet, wodurch dieWHEREBedingungfalsewird. Diese Cluster berechnen oder speichern keine Zeilen für die kontinuierlich aktualisierte materialisierte Ansicht, wodurch Rechen- und Speicherressourcen gespart werden.
Daten nach Clusterursprung filtern
Wenn Ihre Anwendung Cluster-Metadaten in die Zeilen der Quelltabelle schreibt, z. B. in eine Spalte mit dem Namen origin_cluster, können Sie den Ursprungscluster der Zeile mit dem verarbeitenden Cluster vergleichen:
SELECT
metrics['sensor_id'] AS sensor_id,
COUNT(1) AS reading_count
FROM `TABLE_ID`
WHERE metrics['origin_cluster'] = CLUSTER_ATTRIBUTE('cluster_id')
GROUP BY 1
In dieser Abfrage ist metrics['origin_cluster'] eine Property der Daten, die
in der Zeile gespeichert sind, während CLUSTER_ATTRIBUTE('cluster_id') eine Property des
Clusters ist, der die Ansicht verarbeitet. Das Replikat der kontinuierlich aktualisierten materialisierten Ansicht jedes Clusters aggregiert nur die Zeilen, in denen der gespeicherte origin_cluster mit der ID dieses Clusters übereinstimmt.
Wenn für einige Zeilen kein Ursprungscluster angegeben ist, können Sie mit IF_NULL einen Fallback-Cluster zuweisen:
SELECT
metrics['sensor_id'] AS sensor_id,
COUNT(1) AS reading_count
FROM `TABLE_ID`
WHERE IF_NULL(metrics['origin_cluster'], 'DEFAULT_CLUSTER_ID') = CLUSTER_ATTRIBUTE('cluster_id')
GROUP BY 1
Abfragemerkmale
Abfragen mit CLUSTER_ATTRIBUTE haben die folgenden Merkmale:
- Da
sensor_idin derGROUP BY-Klausel enthalten ist, wird sie Teil des Zeilenschlüssels in der kontinuierlich aktualisierten materialisierten Ansicht. - Wenn Sie diese nicht deterministische Funktion verwenden möchten, müssen Sie beim Erstellen der Ansicht das Flag
ignore_warningsauftruesetzen. Weitere Informationen finden Sie unter Kontinuierlich aktualisierte materialisierte Ansicht erstellen.
Wenn Sie die Ansicht mit SELECT * abfragen, sieht das Ergebnis so ähnlich aus:
| sensor_id | reading_count |
|---|---|
| sensor-1234 | 25 |
| sensor-5678 | 68 |
Beschränkungen
Die Verwendung der nicht deterministischen Funktion CLUSTER_ATTRIBUTE führt zu strengen Routinganforderungen:
- Multi-Cluster-Routing wird nicht unterstützt: Da die Ausgabe der Funktion davon abhängt, welcher physische Cluster die Abfrage ausführt, würde Multi-Cluster-Routing nicht deterministische Ergebnisse liefern.
- Single-Cluster-Routing verwenden: Wenn Sie eine kontinuierlich aktualisierte materialisierte Ansicht abfragen
die
CLUSTER_ATTRIBUTEverwendet, verwenden Sie ein Anwendungsprofil, das für Single-Cluster-Routing konfiguriert ist. - An den designierten Cluster weiterleiten: Wenn Sie eine Ansicht auf einen bestimmten
Cluster beschränken, z. B.
WHERE CLUSTER_ATTRIBUTE('cluster_id') = 'my-reporting-cluster', verweisen Sie das Anwendungsprofil direkt auf diesen Cluster. Wenn Sie einen anderen Cluster abfragen, werden leere Ergebnisse zurückgegeben, da die Ansicht nicht auf anderen Clustern gefüllt ist.
Codierung
Wenn Sie Ihre kontinuierlich aktualisierte materialisierte Ansicht mit SQL abfragen, müssen Sie nicht wissen, wie aggregierte Werte codiert werden, da SQL die Ergebnisse als typisierte Spalten bereitstellt.
Wenn Sie mit ReadRows aus der Ansicht lesen, müssen Sie die aggregierten Daten in Ihrer Leseanfrage decodieren. Weitere Informationen zu ReadRows-Anfragen finden Sie unter
Lesevorgänge.
Aggregierte Werte in einer kontinuierlich aktualisierten materialisierten Ansicht werden gemäß der in der folgenden Tabelle beschriebenen Codierung gespeichert, basierend auf dem Ausgabetyp der Spalte aus der Ansichtsdefinition.
| Typ | Codierung |
|---|---|
| BOOL | 1-Byte-Wert, 1 = true, 0 = false |
| BYTES | Keine Codierung |
| INT64 (oder INT, SMALLINT, INTEGER, BIGINT, TINYINT, BYTEINT) | 64-Bit-Big-Endian |
| FLOAT64 | 64-Bit-IEEE 754, ohne NaN und +/-inf |
| STRING | UTF-8 |
| TIME/TIMESTAMP | 64-Bit-Ganzzahl, die die Anzahl der Mikrosekunden seit der Unix-Epoche darstellt (entspricht GoogleSQL) |
Nächste Schritte
- Kontinuierlich aktualisierte materialisierte Ansichten erstellen und verwalten
- GoogleSQL für Bigtable – Referenzdokumentation