In diesem Dokument wird beschrieben, wie Sie mithilfe von Best Practices effiziente Abfragen erstellen. zum Entwerfen von Spanner Graph-Schemas. Schemadesign kann iterativ sein. Wir empfehlen daher, dass Sie zuerst kritische Abfragemuster identifizieren, als Leitfaden für das Entwerfen des Schemas.
Allgemeine Informationen zu Best Practices für das Spanner-Schemadesign finden Sie unter Best Practices für Schemadesign.
Edge Traversal optimieren
Bei Edge Traversal wird der Prozess des Navigierens durch ein Diagramm anhand seines an einem bestimmten Knoten beginnen und sich entlang der miteinander verbundenen Kanten bewegen, um anderen Knoten. „Edge Traversal“ ist ein grundlegender Vorgang in Spanner Graph. Die Verbesserung der Effizienz beim Edge Traversal ist der Schlüssel zu Ihrer Anwendungsleistung.
Sie können eine Kante in zwei Richtungen durchlaufen: vom Quellknoten zu wird der Zielknoten als Forward Edge Traversal bezeichnet, während der Durchlauf Der Zielknoten zum Quellknoten wird als Reverse-Edge-Traversal bezeichnet.
Vorwärtskantendurchlauf mithilfe von Interleaving optimieren
Verschachteln Sie die Edge-Eingabetabelle, um die Leistung beim Forward-Edge-Traversal zu verbessern in die Eingabetabelle des Quellknotens ein, um die Kanten mit den Quellknoten zu verbinden. Verschachtelung ist eine Speicheroptimierungstechnik in Spanner, ordnet untergeordnete Tabellenzeilen den entsprechenden übergeordneten Zeilen in Speicherplatz. Weitere Informationen zur Verschränkung finden Sie unter Schemas
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 Rückkanten effizient zu durchlaufen, erstellen Sie eine Fremdschlüsseleinschränkung zwischen Edge- und Zielknotens. Dieser Fremdschlüssel erstellt automatisch ein sekundärer Index am Edge und den Zielknotenschlüsseln ein. Der sekundäre Index ist die bei der Ausführung von Abfragen automatisch verwendet werden.
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 Fremdschlüssel auf Edge-Geräten erstellen möchten, z. B. aufgrund des Datenintegrität erzwungen wird, können Sie direkt einen sekundären Index Edge-Eingabetabelle hinzu, 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 Reverse_PersonOwnAccount
ON PersonOwnAccount (account_id);
Hängende Kanten nicht zulassen
Eine hängende Kante ist eine Kante, die weniger als zwei Knoten verbindet. Ein baumelndes Edge 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 verbinden.
Das Verhindern von hängenden Kanten bietet folgende Vorteile:
- Erzwingt die Integrität der Grafikstruktur.
- Verbessert die Abfrageleistung, da zusätzliche Arbeit zum Herausfiltern von Kanten vermieden wird bei denen keine Endpunkte vorhanden sind.
Hängende Kanten mit referenziellen Einschränkungen nicht zulassen
Um baumelnde Kanten zu verhindern, geben Sie Einschränkungen für beide an Endpunkte:
- Verschachteln Sie die Edge-Eingabetabelle mit der Eingabetabelle des Quellknotens. Dieses stellt sicher, dass der Quellknoten einer Edge immer vorhanden ist.
- Fremdschlüsseleinschränkung an Kanten erstellen, um sicherzustellen, dass der Zielknoten einer Kante immer existiert.
Im folgenden Beispiel werden Verschränkung und ein Fremdschlüssel verwendet, um referenzielle Integrität:
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;
Verwenden Sie ON DELETE CASCADE, um beim Löschen eines Knotens automatisch Kanten zu entfernen.
Wenn Sie Verschachtelung oder einen Fremdschlüssel verwenden, um baumelnde Kanten zu verbieten, verwenden Sie die Methode
ON DELETE
, um das Verhalten beim Löschen eines Knotens mit
die noch angebracht sind. Weitere Informationen finden Sie unter Kettenlöschung für verschränkte Tabellen und Kettenlöschung mit Fremdschlüsseln.
Sie können ON DELETE
auf folgende Arten verwenden:
ON DELETE NO ACTION
(oderON DELETE
-Klausel auslassen): Löschen eines mit Kanten schlägt fehl.ON DELETE CASCADE
: Durch das Löschen eines Knotens wird automatisch Folgendes entfernt: zugehörige Kanten in derselben Transaktion.
Kaskade für Kanten löschen, die verschiedene Knotentypen verbinden
Kanten löschen, wenn der Quellknoten gelöscht wird. Beispielsweise löscht
INTERLEAVE IN PARENT Person ON DELETE CASCADE
alle ausgehendenPersonOwnAccount
Ränder vomPerson
-Knoten wird gelöscht. Weitere Informationen finden Sie unter Verschränkte Tabellen erstellenKanten löschen, wenn der Zielknoten gelöscht wird. Beispiel:
CONSTRAINT FK_Account FOREIGN KEY(account_id) REFERENCES Account(id) ON DELETE CASCADE
löscht alle eingehendenPersonOwnAccount
-Ränder in denAccount
-Knoten ein, der gelöscht wird. Weitere Informationen finden Sie unter Fremdschlüssel:
Kaskade für Kanten löschen, die denselben Knotentyp verbinden
Wenn 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 definieren, aber nicht für beide Knoten.
Um in beiden Fällen automatisch hängende Kanten zu entfernen, erstellen Sie einen Fremdschlüssel auf Referenz des Edge-Quellknotens, anstatt die Edge-Eingabetabelle Quellknoten-Eingabetabelle.
Wir empfehlen Verschachtelung für
„Forward-Edge Traversal“ optimieren.
Prüfen Sie unbedingt die Auswirkungen auf Ihre Arbeitslasten, bevor Sie fortfahren. Weitere Informationen finden Sie in der
Im folgenden Beispiel, in dem AccountTransferAccount
als Edge-Eingabe verwendet wird
Tabelle:
--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);
Nach Knoten- oder Edge-Attributen mit sekundären Indexen filtern
Sekundäre Indexe sind für eine effiziente Abfrageverarbeitung unerlässlich. Sie unterstützen schnelle Suche nach Knoten und Kanten basierend auf bestimmten Eigenschaftswerten, ohne die gesamte Diagrammstruktur durchlaufen zu müssen. Das ist wichtig, wenn arbeiten Sie mit großen Diagrammen, da alle Knoten und Kanten durchlaufen werden, sehr ineffizient sein.
Knoten nach Attribut schneller filtern
Um das Filtern nach Knotenattributen zu beschleunigen, erstellen Sie sekundäre Indexe auf
Eigenschaften. Mit der folgenden Abfrage werden beispielsweise Konten für
Alias. Ohne einen sekundären Index werden alle Account
-Knoten entsprechend gescannt
die Filterkriterien.
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 folgt: Beispiel:
CREATE TABLE Account (
id INT64 NOT NULL,
create_time TIMESTAMP,
is_blocked BOOL,
nick_name STRING(MAX),
) PRIMARY KEY (id);
CREATE INDEX AccountByEmail
ON Account (nick_name);
Tipp:Verwenden Sie nach NULL gefilterte Indexe für dünnbesetzte Attribute. Weitere Informationen Siehe Indexierung von NULL-Werten deaktivieren.
Vorwärts-Edge-Traversal mit Filtern nach Edge-Eigenschaften beschleunigen
Wenn Sie einen Kantenknoten durchlaufen und dabei nach seinen Eigenschaften filtern, können Sie die Abfrage beschleunigen, indem Sie einen sekundären Index für die Kanteneigenschaften erstellen und den Index in den Quellknoten einfügen.
Mit der folgenden Abfrage werden beispielsweise Konten gefunden, die nach einem bestimmten Zeitraum zu einer bestimmten Person 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.
Das folgende Beispiel zeigt, wie Sie die Abfrageeffizienz verbessern können, indem Sie
einen sekundären Index in der Referenz des Edge-Quellknotens (id
) und das Edge-Attribut
(create_time
). Index unter der Eingabetabelle des Quellknotens verschachteln, um
Fügen Sie den Index mit dem Quellknoten zusammen.
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 kann die Abfrage effizient alle Kanten finden, die die
Bedingung für create_time
.
Durch Filterung nach Kanteneigenschaften die umgekehrte Kantendurchquerung beschleunigen
Wenn Sie eine umgekehrte Kante durchlaufen, während Sie nach ihren Eigenschaften filtern, können Sie die Abfrage zu beschleunigen, indem Sie mithilfe des Zielknotens einen sekundären Index Edge-Eigenschaften zum Filtern hinzufügen.
Die folgende Beispielabfrage führt einen umgekehrten Edge-Traversal mit Filterung durch Edge-Eigenschaften:
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;
Sie können diese Abfrage mit einem sekundären Index beschleunigen. Verwenden Sie dazu eine der folgenden Optionen:
Sekundären Index in der Referenz des Edge-Zielknotens erstellen (
account_id
) und die Edge-Eigenschaft (create_time
), wie in den folgendes Beispiel: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 Abfragemaschine effizienter Kanten füraccount_id
finden, die die Bedingung fürcreate_time
erfüllen. Wenn jedoch mit unterschiedlichen Abfragemustern ist möglicherweise für jedes Attribut ein separater Index erforderlich, der Mehraufwand.Sekundären Index in der Referenz des Edge-Zielknotens erstellen (
account_id
) und speichern Sie das Edge-Attribut (create_time
) in einem Speicherspalte Dies wird 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);
Bei diesem Ansatz können mehrere Eigenschaften gespeichert werden. Die Abfrage muss jedoch alle Kanten des Zielknotens lesen und dann nach Edge-Eigenschaften filtern.
Sie können diese Ansätze miteinander kombinieren, indem Sie sich an die folgenden Richtlinien halten:
- Verwenden Sie Edge-Attribute in Indexspalten, wenn sie in leistungskritische Abfragen.
- Fügen Sie Attribute, die in weniger leistungssensiblen Abfragen verwendet werden, den Speicherspalten hinzu.
Modellknoten- und Edgetypen mit Labels und Attributen
Knoten- und Edge-Typen werden normalerweise mit Labels modelliert. Sie können jedoch auch
zu Modelltypen hinzufügen. Nehmen wir ein Beispiel mit vielen verschiedenen
Kontotypen wie BankAccount
, InvestmentAccount
und
RetirementAccount
Sie können die Konten in separaten Eingabetabellen speichern und
als separate Labels modellieren oder die Konten in einer einzigen Eingabe speichern
und verwenden Sie eine Eigenschaft, um zwischen den Typen zu unterscheiden.
Beginnen Sie den Modellierungsprozess, indem Sie die Typen mit Labels modellieren. Erwägen Sie in den folgenden Szenarien verwenden.
Schemaverwaltung verbessern
Wenn das Diagramm viele verschiedene Knoten- und Kantentypen hat, ist die Verwaltung einer separaten Eingabe kann es schwierig werden. Um die Schemaverwaltung zu vereinfachen, den Typ als Eigenschaft an.
Modelltypen in einer Property, um sich häufig ändernde Typen zu verwalten
Wenn Sie Typen als Labels modellieren, müssen Sie das Schema ändern, wenn Sie Typen hinzufügen oder entfernen möchten. Wenn Sie in kurzer Zeit zu viele Schemaaktualisierungen durchführen, Spanner könnte throttle die Verarbeitung von Schemaaktualisierungen in der Warteschlange. Weitere Informationen finden Sie unter Häufigkeit von Schemaaktualisierungen begrenzen.
Wenn Sie das Schema häufig ändern müssen, empfehlen wir, dass Sie das Modell des Geben Sie eine Eigenschaft ein, um Einschränkungen bei der Häufigkeit von Schemas zu umgehen. Aktualisierungen.
Abfragen beschleunigen
Modellierungstypen mit Attributen können Abfragen beschleunigen, wenn der Knoten- oder Edge-Muster
auf mehrere Labels verweist. Mit der folgenden Beispielabfrage werden alle Instanzen von SavingsAccount
und InvestmentAccount
gefunden, die zu einem Person
gehören. Dabei wird davon ausgegangen, dass Kontotypen mit Labels modelliert sind:
GRAPH FinGraph
MATCH (:Person {id: 1})-[:Owns]->(acct:SavingsAccount|InvestmentAccount)
RETURN acct.id;
Das Knotenmuster acct
verweist auf zwei Labels. Wenn dies ein
leistungskritische Abfrage sollten Sie die Account
anhand einer Property modellieren. Dieser Ansatz kann zu einer besseren Abfrageleistung führen, wie das folgende Abfragebeispiel zeigt. 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
Beschleunigen von Abfragen durch Filtern des Knotentyps, wenn ein Knotentyp modelliert wird mit einer Eigenschaft verwenden und der Typ sich während der Knotenlebensdauer nicht ändert, folgen Sie diese Schritte:
- Fügen Sie das Attribut als Teil des Knotenelementschlüssels ein.
- Fügen Sie den Knotentyp in die Edge-Eingabetabelle ein.
- Fügen Sie den Knotentyp in die Schlüssel für die Kantenreferenzen ein.
Im folgenden Beispiel wird diese Optimierung auf den Knoten Account
und den
Rand AccountTransferAccount
.
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 auf Knoten und Edges konfigurieren
Spanner Die Gültigkeitsdauer (TTL) ist ein Mechanismus, der automatische Ablauf und Löschen von Daten nach Ablauf eines bestimmten Zeitraums. Dies wird häufig für Daten verwendet, Lebensdauer oder Relevanz, wie Sitzungsinformationen, temporäre Caches oder Ereignisse Logs. In diesen Fällen hilft TTL dabei, die Datenbankgröße und -leistung aufrechtzuerhalten.
Im folgenden Beispiel werden Konten mithilfe der TTL 90 Tage nach der Sperrung:
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 hat und eine Edge-Tabelle darin verschränkt ist,
Verschränkung muss definiert werden mit
ON DELETE CASCADE
Ähnlich verhält es sich, wenn die Knotentabelle eine TTL hat und von einer Edge-Tabelle referenziert wird.
durch einen Fremdschlüssel muss der Fremdschlüssel mit
ON DELETE CASCADE
Im folgenden Beispiel wird AccountTransferAccount
bis zu zehn Jahre lang gespeichert.
solange ein Konto aktiv bleibt. Wenn ein Konto gelöscht wird, wird die Übertragung
wird ebenfalls 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 mit derselben Eingabetabelle mehr als einen Knoten und eine Kante in Ihrem Schema.
In den folgenden Beispieltabellen haben die Account
-Knoten einen zusammengesetzten Schlüssel
(owner_id, account_id)
. Es gibt eine implizite Edge-Definition: Person
-Knoten
mit Schlüssel (id
) besitzt den Account
-Knoten mit zusammengesetztem 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 Account
-Eingabetabelle verwenden, um den Account
zu definieren.
Knoten und PersonOwnAccount
-Edge, wie im folgenden Schemabeispiel gezeigt.
Um sicherzustellen, dass alle Elementtabellennamen eindeutig sind, wird im Beispiel der Rand
Tabellendefinition den Alias Owns
.
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
- Erstellen, aktualisieren oder löschen Sie ein Spanner-Diagrammschema.
- Daten des Spanner-Diagramms einfügen, aktualisieren oder löschen