In diesem Dokument wird beschrieben, wie Sie effiziente Abfragen erstellen, indem Sie Best Practices für das Entwerfen von Spanner Graph-Schemas anwenden. Sie können Ihr Schemadesign iterativ verbessern. Wir empfehlen daher, zuerst kritische Abfragemuster zu ermitteln, um Ihr Schemadesign zu optimieren.
Allgemeine Informationen zu Best Practices für das Spanner-Schemadesign finden Sie unter Best Practices für das Schemadesign.
Kantenübergang optimieren
Edge Traversal (Kantendurchlauf) ist der Prozess, bei dem ein Graph durchlaufen wird, indem seinen Kanten gefolgt wird. Dabei wird an einem bestimmten Knoten begonnen und entlang verbundener Kanten zu anderen Knoten bewegt. Die Richtung der Kante wird durch das Schema definiert. Das Durchlaufen von Kanten ist ein grundlegender Vorgang in Spanner Graph. Daher ist die Verbesserung der Effizienz des Durchlaufens von Kanten entscheidend für die Leistung Ihrer Anwendung.
Sie können eine Kante in zwei Richtungen durchlaufen:
Vorwärtskanten-Traversal: Folgt ausgehenden Kanten des Quellknotens.
Reverse Edge Traversal (Rückwärtskanten-Traversal): Folgt eingehenden Kanten des Zielknotens.
Die folgende Beispielabfrage führt für eine Person eine Vorwärtskantentraversierung von Owns
-Kanten durch:
GRAPH FinGraph
MATCH (person:Person {id: 1})-[owns:Owns]->(accnt:Account)
RETURN accnt.id;
Mit der folgenden Beispielabfrage wird für ein Konto ein Reverse-Edge-Traversal von Owns
-Kanten ausgeführt:
GRAPH FinGraph
MATCH (accnt:Account {id: 1})<-[owns:Owns]-(person:Person)
RETURN person.name;
Durch Interleaving die Traversierung der Vorwärtskante optimieren
Um die Leistung der Vorwärtskanten-Traversierung zu verbessern, verschränken Sie die Kanten-Eingabetabelle mit der Eingabetabelle des Quellknotens, um Kanten mit Quellknoten zu platzieren. Die Verschränkung ist eine Speicheroptimierungstechnik in Spanner, bei der Zeilen der untergeordneten Tabelle physisch mit den entsprechenden übergeordneten Zeilen im Speicher platziert werden. Weitere Informationen zum Interleaving finden Sie unter Schemas – Übersicht.
Das folgende Beispiel veranschaulicht diese Best Practices:
CREATE TABLE Person (
id INT64 NOT NULL,
name STRING(MAX),
) PRIMARY KEY (id);
CREATE TABLE PersonOwnAccount (
id INT64 NOT NULL,
account_id INT64 NOT NULL,
create_time TIMESTAMP,
) PRIMARY KEY (id, account_id),
INTERLEAVE IN PARENT Person ON DELETE CASCADE;
Reverse-Edge-Traversal mit Fremdschlüssel optimieren
Um Reverse-Kanten effizient zu durchlaufen, erstellen Sie eine erzwungene Fremdschlüsselbeschränkung zwischen der Kante und dem Zielknoten. Dieser erzwungene Fremdschlüssel erstellt einen sekundären Index für die Kante, die mit den Zielknotenschlüsseln versehen ist. Der sekundäre Index wird bei der Ausführung von Abfragen automatisch verwendet.
Das folgende Beispiel veranschaulicht diese Best Practices:
CREATE TABLE Person (
id INT64 NOT NULL,
name STRING(MAX),
) PRIMARY KEY (id);
CREATE TABLE Account (
id INT64 NOT NULL,
create_time TIMESTAMP,
) PRIMARY KEY (id);
CREATE TABLE PersonOwnAccount (
id INT64 NOT NULL,
account_id INT64 NOT NULL,
create_time TIMESTAMP,
CONSTRAINT FK_Account FOREIGN KEY (account_id) REFERENCES Account (id),
) PRIMARY KEY (id, account_id),
INTERLEAVE IN PARENT Person ON DELETE CASCADE;
Reverse-Edge-Traversal mit sekundärem Index optimieren
Wenn Sie keinen erzwungenen Fremdschlüssel für den Edge erstellen möchten, z. B. aufgrund der strengen Datenintegrität, die er erzwingt, können Sie direkt einen sekundären Index für die Edge-Eingabetabelle erstellen, wie im folgenden Beispiel gezeigt:
CREATE TABLE PersonOwnAccount (
id INT64 NOT NULL,
account_id INT64 NOT NULL,
create_time TIMESTAMP,
) PRIMARY KEY (id, account_id),
INTERLEAVE IN PARENT Person ON DELETE CASCADE;
CREATE INDEX AccountOwnedByPerson
ON PersonOwnAccount (account_id), INTERLEAVE IN Account;
Mit INTERLEAVE IN
wird eine Datenlokalitätsbeziehung zwischen dem sekundären Index und der Tabelle deklariert, in die er verschachtelt ist (Account
im Beispiel). Beim Interleaving werden Zeilen des sekundären Index AccountOwnedByPerson
zusammen mit den entsprechenden Zeilen der Tabelle Account
gespeichert. Weitere Informationen zum Verschachteln finden Sie unter Über- und untergeordnete Tabellenbeziehungen. Weitere Informationen zum Verschachteln von Indexen finden Sie unter Indexe und Verschachtelung.
Edge-Traversal mit informativen Fremdschlüsseln optimieren
Wenn in Ihrem Szenario Engpässe bei der Schreibgeschwindigkeit auftreten, die durch erzwungene Fremdschlüssel verursacht werden, z. B. wenn Sie häufig Hubknoten aktualisieren, die viele verbundene Kanten haben, sollten Sie informative Fremdschlüssel verwenden. Wenn Sie informative Fremdschlüssel für die Referenzspalten einer Edge-Tabelle verwenden, kann der Query-Optimierer redundante Knotentabellenscans entfernen. Da für informative Fremdschlüssel jedoch keine sekundären Indexe in der Edge-Tabelle erforderlich sind, wird die Geschwindigkeit von Suchvorgängen nicht verbessert, wenn in einer Abfrage versucht wird, Edges anhand von Endknoten zu finden. Weitere Informationen finden Sie unter Vergleich von Fremdschlüsseltypen.
Wenn Ihre Anwendung keine referenzielle Integrität garantieren kann, kann die Verwendung von informativen Fremdschlüsseln zur Abfrageoptimierung zu falschen Abfrageergebnissen führen.
Im folgenden Beispiel wird eine Tabelle mit einem informativen Fremdschlüssel für die Spalte account_id
erstellt:
CREATE TABLE PersonOwnAccount (
id INT64 NOT NULL,
account_id INT64 NOT NULL,
create_time TIMESTAMP,
CONSTRAINT FK_Account FOREIGN KEY (account_id)
REFERENCES Account (id) NOT ENFORCED
) PRIMARY KEY (id, account_id),
INTERLEAVE IN PARENT Person ON DELETE CASCADE;
Wenn das nicht möglich ist, können Sie beide Edge-Referenzen mit informativen Fremdschlüsseln markieren, wie im folgenden Beispiel:
CREATE TABLE PersonOwnAccount (
id INT64 NOT NULL,
account_id INT64 NOT NULL,
create_time TIMESTAMP,
CONSTRAINT FK_Person FOREIGN KEY (id)
REFERENCES Person (id) NOT ENFORCED,
CONSTRAINT FK_Account FOREIGN KEY (account_id)
REFERENCES Account (id) NOT ENFORCED
) PRIMARY KEY (id, account_id);
Lose Kanten nicht zulassen
Eine nicht verbundene Kante ist eine Kante, die weniger als zwei Knoten verbindet. Eine freihängende Kante kann auftreten, wenn ein Knoten gelöscht wird, ohne die zugehörigen Kanten zu entfernen, oder wenn eine Kante erstellt wird, ohne sie richtig mit ihren Knoten zu verknüpfen.
Das Verhindern von nicht verbundenen Kanten bietet folgende Vorteile:
- Erzwingt die Integrität der Diagrammstruktur.
- Verbessert die Abfrageleistung, da der zusätzliche Aufwand zum Herausfiltern von Kanten vermieden wird, bei denen keine Endpunkte vorhanden sind.
Verwaiste Kanten mit referenziellen Einschränkungen nicht zulassen
Wenn Sie verhindern möchten, dass Kanten ohne Verbindung entstehen, geben Sie Einschränkungen für beide Endpunkte an:
- Verschachteln Sie die Eingabetabelle für Kanten in die Eingabetabelle für Quellknoten. So wird sichergestellt, dass der Quellknoten einer Kante immer vorhanden ist.
- Erstellen Sie eine erzwungene Fremdschlüsseleinschränkung für Kanten, um sicherzustellen, dass der Zielknoten einer Kante immer vorhanden ist.
Im folgenden Beispiel werden Interleaving und ein erzwungener Fremdschlüssel verwendet, um die referenzielle Integrität zu erzwingen:
CREATE TABLE PersonOwnAccount (
id INT64 NOT NULL,
account_id INT64 NOT NULL,
create_time TIMESTAMP,
CONSTRAINT FK_Account FOREIGN KEY (account_id) REFERENCES Account (id) ON DELETE CASCADE,
) PRIMARY KEY (id, account_id),
INTERLEAVE IN PARENT Person ON DELETE CASCADE;
Mit ON DELETE CASCADE Kanten beim Löschen eines Knotens automatisch entfernen
Wenn Sie Interleaving oder einen erzwungenen Fremdschlüssel verwenden, um verwaiste Kanten zu verhindern, verwenden Sie die ON DELETE
-Klausel, um das Verhalten zu steuern, wenn Sie einen Knoten mit Kanten löschen möchten, die noch angehängt sind. Weitere Informationen finden Sie unter Kaskadierendes Löschen für verschränkte Tabellen und Fremdschlüsselaktionen.
Sie können ON DELETE
auf folgende Arten verwenden:
ON DELETE NO ACTION
(oder Auslassen derON DELETE
-Klausel): Das Löschen eines Knotens mit Kanten schlägt fehl.ON DELETE CASCADE
: Wenn Sie einen Knoten löschen, werden die zugehörigen Kanten in derselben Transaktion automatisch entfernt.
Kaskadierendes Löschen für Kanten, die verschiedene Knotentypen verbinden
Kanten löschen, wenn der Quellknoten gelöscht wird. Mit
INTERLEAVE IN PARENT Person ON DELETE CASCADE
werden beispielsweise alle ausgehendenPersonOwnAccount
-Kanten des zu löschenden KnotensPerson
gelöscht. Weitere Informationen finden Sie unter Verschachtelte Tabellen erstellen.Kanten löschen, wenn der Zielknoten gelöscht wird. Mit
CONSTRAINT FK_Account FOREIGN KEY(account_id) REFERENCES Account(id) ON DELETE CASCADE
werden beispielsweise alle eingehendenPersonOwnAccount
-Kanten in den zu löschenden KnotenAccount
gelöscht.
Kaskadierendes Löschen für Kanten, die Knoten desselben Typs verbinden
Wenn die Quell- und Zielknoten einer Kante denselben Typ haben und die Kante in den Quellknoten verschachtelt ist, können Sie ON DELETE CASCADE
nur für den Quell- oder Zielknoten (aber nicht für beide Knoten) definieren.
Um in beiden Fällen verwaiste Kanten zu entfernen, erstellen Sie einen erzwungenen Fremdschlüssel für den Quellknotenverweis der Kante, anstatt die Kanten-Eingabetabelle in die Quellknoten-Eingabetabelle einzufügen.
Wir empfehlen die Interleaving-Technik, um das Durchlaufen der Vorwärtskante zu optimieren.
Prüfen Sie vor dem Fortfahren, wie sich die Änderung auf Ihre Arbeitslasten auswirkt. Im folgenden Beispiel wird AccountTransferAccount
als Edge-Eingabetabelle verwendet:
--Define two Foreign Keys, each on one end Node of Transfer Edge, both with ON DELETE CASCADE action:
CREATE TABLE AccountTransferAccount (
id INT64 NOT NULL,
to_id INT64 NOT NULL,
amount FLOAT64,
create_time TIMESTAMP NOT NULL,
order_number STRING(MAX),
CONSTRAINT FK_FromAccount FOREIGN KEY (id) REFERENCES Account (id) ON DELETE CASCADE,
CONSTRAINT FK_ToAccount FOREIGN KEY (to_id) REFERENCES Account (id) ON DELETE CASCADE,
) PRIMARY KEY (id, to_id);
Mit Sekundärindexen nach Knoten- oder Kantenattributen filtern
Sekundärindexe sind für eine effiziente Abfrageverarbeitung unerlässlich. Sie unterstützen schnelle Suchvorgänge für Knoten und Kanten basierend auf bestimmten Attributwerten, ohne dass die gesamte Diagrammstruktur durchlaufen werden muss. Das ist wichtig, wenn Sie mit großen Diagrammen arbeiten, da das Durchlaufen aller Knoten und Kanten sehr ineffizient sein kann.
Filtern von Knoten nach Attribut beschleunigen
Um das Filtern nach Knotenattributen zu beschleunigen, erstellen Sie sekundäre Indexe für Attribute. Mit der folgenden Abfrage werden beispielsweise Konten für einen bestimmten Alias gesucht. Ohne sekundären Index werden alle Account
-Knoten gescannt, um die Filterkriterien zu erfüllen.
GRAPH FinGraph
MATCH (acct:Account)
WHERE acct.nick_name = "abcd"
RETURN acct.id;
Um die Abfrage zu beschleunigen, erstellen Sie einen sekundären Index für das gefilterte Attribut, wie im folgenden Beispiel gezeigt:
CREATE TABLE Account (
id INT64 NOT NULL,
create_time TIMESTAMP,
is_blocked BOOL,
nick_name STRING(MAX),
) PRIMARY KEY (id);
CREATE INDEX AccountByNickName
ON Account (nick_name);
Tipp:Verwenden Sie NULL-gefilterte Indexe für spärliche Attribute. Weitere Informationen finden Sie unter Indexierung von NULL-Werten deaktivieren.
Traversal der Vorwärtskante mit Filterung nach Kanteneigenschaften beschleunigen
Wenn Sie eine Kante durchlaufen und dabei nach ihren Attributen filtern, können Sie die Abfrage beschleunigen, indem Sie einen sekundären Index für die Kantenattribute erstellen und den Index in den Quellknoten einfügen.
Mit der folgenden Abfrage werden beispielsweise Konten gefunden, die einer bestimmten Person nach einem bestimmten Zeitpunkt gehören:
GRAPH FinGraph
MATCH (person:Person)-[owns:Owns]->(acct:Account)
WHERE person.id = 1
AND owns.create_time >= PARSE_TIMESTAMP("%c", "Thu Dec 25 07:30:00 2008")
RETURN acct.id;
Standardmäßig werden mit dieser Abfrage alle Kanten der angegebenen Person gelesen und dann die Kanten herausgefiltert, die die Bedingung für create_time
erfüllen.
Im folgenden Beispiel wird gezeigt, wie Sie die Abfrageeffizienz verbessern können, indem Sie einen sekundären Index für die Referenz des Quellknotens (id
) und die Kantenattribute (create_time
) erstellen. Verschachteln Sie den Index in der Eingabetabelle des Quellknotens, um ihn mit dem Quellknoten zu platzieren.
CREATE TABLE PersonOwnAccount (
id INT64 NOT NULL,
account_id INT64 NOT NULL,
create_time TIMESTAMP,
) PRIMARY KEY (id, account_id),
INTERLEAVE IN PARENT Person ON DELETE CASCADE;
CREATE INDEX PersonOwnAccountByCreateTime
ON PersonOwnAccount (id, create_time)
INTERLEAVE IN Person;
Mit diesem Ansatz können in der Abfrage effizient alle Kanten gefunden werden, die die Bedingung für create_time
erfüllen.
Reverse-Edge-Traversal mit Filterung nach Edge-Attributen beschleunigen
Wenn Sie eine umgekehrte Kante durchlaufen und nach ihren Attributen filtern, können Sie die Abfrage beschleunigen, indem Sie einen sekundären Index mit dem Zielknoten und den Kantenattributen zum Filtern erstellen.
Die folgende Beispielabfrage führt eine umgekehrte Kantendurchquerung mit Filterung nach Kanteneigenschaften durch:
GRAPH FinGraph
MATCH (acct:Account)<-[owns:Owns]-(person:Person)
WHERE acct.id = 1
AND owns.create_time >= PARSE_TIMESTAMP("%c", "Thu Dec 25 07:30:00 2008")
RETURN person.id;
Um diese Abfrage mit einem sekundären Index zu beschleunigen, haben Sie folgende Möglichkeiten:
Erstellen Sie einen sekundären Index für den Knotenverweis des Edge-Ziels (
account_id
) und das Edge-Attribut (create_time
), wie im folgenden Beispiel gezeigt:CREATE TABLE PersonOwnAccount ( id INT64 NOT NULL, account_id INT64 NOT NULL, create_time TIMESTAMP, ) PRIMARY KEY (id, account_id), INTERLEAVE IN PARENT Person ON DELETE CASCADE; CREATE INDEX PersonOwnAccountByCreateTime ON PersonOwnAccount (account_id, create_time);
Dieser Ansatz bietet eine bessere Leistung, da die umgekehrten Kanten nach
account_id
undcreate_time
sortiert werden. So kann die Abfrage-Engine effizient Kanten füraccount_id
finden, die die Bedingung fürcreate_time
erfüllen. Wenn jedoch verschiedene Abfragemuster nach unterschiedlichen Attributen filtern, ist für jedes Attribut möglicherweise ein separater Index erforderlich, was zusätzlichen Aufwand bedeutet.Erstellen Sie einen sekundären Index für die Referenz des Zielknotens der Kante (
account_id
) und speichern Sie die Kanteneigenschaft (create_time
) in einer Speicherspalte, wie im folgenden Beispiel gezeigt:CREATE TABLE PersonOwnAccount ( id INT64 NOT NULL, account_id INT64 NOT NULL, create_time TIMESTAMP, ) PRIMARY KEY (id, account_id), INTERLEAVE IN PARENT Person ON DELETE CASCADE; CREATE INDEX PersonOwnAccountByCreateTime ON PersonOwnAccount (account_id) STORING (create_time);
Mit diesem Ansatz können mehrere Attribute gespeichert werden. Bei der Abfrage müssen jedoch alle Kanten des Zielknotens gelesen und dann nach Kantenattributen gefiltert werden.
Sie können diese Ansätze kombinieren, indem Sie die folgenden Richtlinien beachten:
- Verwenden Sie Edge-Properties in Indexspalten, wenn sie in leistungsrelevanten Abfragen verwendet werden.
- Fügen Sie Attribute, die in weniger leistungsintensiven Abfragen verwendet werden, in die Spalten für die Speicherung ein.
Knoten- und Kantentypen mit Labels und Attributen modellieren
Knoten- und Kantentypen werden in der Regel mit Labels modelliert. Sie können jedoch auch Eigenschaften verwenden, um Typen zu modellieren. Angenommen, es gibt viele verschiedene Arten von Konten, z. B. BankAccount
, InvestmentAccount
und RetirementAccount
. Sie können die Konten in separaten Eingabetabellen speichern und als separate Labels modellieren oder sie in einer einzelnen Eingabetabelle speichern und eine Property verwenden, um zwischen den Typen zu unterscheiden.
Beginnen Sie mit der Modellierung der Typen mit Labels. In den folgenden Szenarien kann es sinnvoll sein, Properties zu verwenden.
Schemaverwaltung verbessern
Wenn Ihr Diagramm viele verschiedene Knoten- und Kantentypen enthält, kann die Verwaltung einer separaten Eingabetabelle für jeden Typ schwierig werden. Um die Schemabearbeitung zu vereinfachen, modellieren Sie den Typ als Attribut.
Modelltypen in einer Property verwalten, um häufige Änderungen zu berücksichtigen
Wenn Sie Typen als Labels modellieren, müssen Sie das Schema ändern, wenn Sie Typen hinzufügen oder entfernen. Wenn Sie zu viele Schemaaktualisierungen in kurzer Zeit durchführen, kann es sein, dass Spanner die Verarbeitung der in die Warteschlange eingereihten Schemaaktualisierungen drosselt. Weitere Informationen finden Sie unter Häufigkeit von Schemaaktualisierungen begrenzen.
Wenn Sie das Schema häufig ändern müssen, empfehlen wir, den Typ in einer Property zu modellieren, um Einschränkungen bei der Häufigkeit von Schemaaktualisierungen zu umgehen.
Abfragen beschleunigen
Wenn Sie Modelltypen mit Attributen verwenden, können Abfragen beschleunigt werden, wenn im Knoten- oder Kantenmuster auf mehrere Labels verwiesen wird. Mit der folgenden Beispielabfrage werden alle Instanzen von SavingsAccount
und InvestmentAccount
gefunden, die einem Person
gehören. Dabei wird davon ausgegangen, dass Kontotypen mit Labels modelliert werden:
GRAPH FinGraph
MATCH (:Person {id: 1})-[:Owns]->(acct:SavingsAccount|InvestmentAccount)
RETURN acct.id;
Das Knotenmuster acct
verweist auf zwei Labels. Wenn es sich um eine leistungsrelevante Abfrage handelt, sollten Sie Account
mit einer Eigenschaft modellieren. Dieser Ansatz kann die Abfrageleistung verbessern, wie im folgenden Beispiel zu sehen ist. Wir empfehlen, beide Abfragen zu vergleichen.
GRAPH FinGraph
MATCH (:Person {id: 1})-[:Owns]->(acct:Account)
WHERE acct.type IN ("Savings", "Investment")
RETURN acct.id;
Speichern Sie den Typ im Knotenelementschlüssel, um Abfragen zu beschleunigen.
So beschleunigen Sie Abfragen mit Filterung nach dem Knotentyp, wenn ein Knotentyp mit einem Attribut modelliert wird und sich der Typ während der Lebensdauer des Knotens nicht ändert:
- Fügen Sie das Attribut als Teil des Knotenelementschlüssels ein.
- Fügen Sie den Knotentyp in die Edge-Eingabetabelle ein.
- Nehmen Sie den Knotentyp in die Referenzschlüssel für die Kanten auf.
Im folgenden Beispiel wird diese Optimierung auf den Knoten Account
und die Kante AccountTransferAccount
angewendet.
CREATE TABLE Account (
type STRING(MAX) NOT NULL,
id INT64 NOT NULL,
create_time TIMESTAMP,
) PRIMARY KEY (type, id);
CREATE TABLE AccountTransferAccount (
type STRING(MAX) NOT NULL,
id INT64 NOT NULL,
to_type STRING(MAX) NOT NULL,
to_id INT64 NOT NULL,
amount FLOAT64,
create_time TIMESTAMP NOT NULL,
order_number STRING(MAX),
) PRIMARY KEY (type, id, to_type, to_id),
INTERLEAVE IN PARENT Account ON DELETE CASCADE;
CREATE PROPERTY GRAPH FinGraph
NODE TABLES (
Account
)
EDGE TABLES (
AccountTransferAccount
SOURCE KEY (type, id) REFERENCES Account
DESTINATION KEY (to_type, to_id) REFERENCES Account
);
TTL für Knoten und Kanten konfigurieren
Die Gültigkeitsdauer (Time to Live, TTL) in Spanner ist ein Mechanismus, der das automatische Ablaufen und Entfernen von Daten nach einem bestimmten Zeitraum unterstützt. Dies wird häufig für Daten verwendet, die eine begrenzte Lebensdauer oder Relevanz haben, z. B. Sitzungsinformationen, temporäre Caches oder Ereignisprotokolle. In diesen Fällen trägt die TTL dazu bei, die Datenbankgröße und ‑leistung aufrechtzuerhalten.
Im folgenden Beispiel wird die TTL verwendet, um Konten 90 Tage nach ihrer Schließung zu löschen:
CREATE TABLE Account (
id INT64 NOT NULL,
create_time TIMESTAMP,
close_time TIMESTAMP,
) PRIMARY KEY (id),
ROW DELETION POLICY (OLDER_THAN(close_time, INTERVAL 90 DAY));
Wenn die Knotentabelle eine TTL und eine verschränkte Kantentabelle hat, muss die Verschachtelung mit ON DELETE CASCADE
definiert werden. Wenn die Knotentabelle eine TTL hat und über einen Fremdschlüssel von einer Kantentabelle referenziert wird, muss der Fremdschlüssel entweder mit ON DELETE CASCADE
definiert werden, um die referenzielle Integrität aufrechtzuerhalten, oder als informativer Fremdschlüssel, um die Existenz von verwaisten Kanten zu ermöglichen.
Im folgenden Beispiel wird AccountTransferAccount
bis zu zehn Jahre lang gespeichert, solange ein Konto aktiv ist. Wenn ein Konto gelöscht wird, wird auch der Überweisungsverlauf gelöscht.
CREATE TABLE AccountTransferAccount (
id INT64 NOT NULL,
to_id INT64 NOT NULL,
amount FLOAT64,
create_time TIMESTAMP NOT NULL,
order_number STRING(MAX),
) PRIMARY KEY (id, to_id),
INTERLEAVE IN PARENT Account ON DELETE CASCADE,
ROW DELETION POLICY (OLDER_THAN(create_time, INTERVAL 3650 DAY));
Knoten- und Edge-Eingabetabellen zusammenführen
Sie können dieselbe Eingabetabelle verwenden, um mehrere Knoten und Kanten in Ihrem Schema zu definieren.
In den folgenden Beispieltabellen haben die Account
-Knoten einen zusammengesetzten Schlüssel (owner_id, account_id)
. Es gibt eine implizite Kantendefinition: Der Knoten Person
mit dem Schlüssel (id
) ist der Eigentümer des Knotens Account
mit dem zusammengesetzten Schlüssel (owner_id, account_id)
, wenn id
gleich owner_id
ist.
CREATE TABLE Person (
id INT64 NOT NULL,
) PRIMARY KEY (id);
-- Assume each account has exactly one owner.
CREATE TABLE Account (
owner_id INT64 NOT NULL,
account_id INT64 NOT NULL,
) PRIMARY KEY (owner_id, account_id);
In diesem Fall können Sie die Eingabetabelle Account
verwenden, um den Knoten Account
und die Kante PersonOwnAccount
zu definieren, wie im folgenden Schema-Beispiel gezeigt.
Damit alle Elementtabellennamen eindeutig sind, wird in diesem Beispiel für die Definition der Edge-Tabelle der Alias Owns
verwendet.
CREATE PROPERTY GRAPH FinGraph
NODE TABLES (
Person,
Account
)
EDGE TABLES (
Account AS Owns
SOURCE KEY (owner_id) REFERENCES Person
DESTINATION KEY (owner_id, account_id) REFERENCES Account
);
Nächste Schritte
- Spanner Graph-Schema erstellen, aktualisieren oder löschen
- Spanner Graph-Daten einfügen, aktualisieren oder löschen