Auf dieser Seite werden die Anforderungen für das Spanner-Schema und die Verwendung des Schemas erläutert. hierarchische Beziehungen und Schemamerkmale zu erstellen. Außerdem werden die verschränkte Tabellen, was die Abfrageleistung beim Abfragen von Tabellen in eine Über-/Untergeordnet-Beziehung.
Ein Schema ist ein Namespace, der Datenbankobjekte wie Tabellen, Ansichten, Indizes und Funktionen. Mithilfe von Schemas können Sie Objekte organisieren, detaillierte Zugriffssteuerungsberechtigungen anwenden und Namenskollisionen vermeiden. Sie müssen für jede Datenbank in Spanner ein Schema definieren.
Außerdem können Sie Zeilen in Ihrer Datenbanktabelle in verschiedenen geografischen Regionen weiter segmentieren und speichern. Weitere Informationen finden Sie unter Geo-Partitionierung.
Stark typisierte Daten
Daten in Spanner sind stark typisiert. Zu den Datentypen gehören skalare und komplexe Typen, die unter Datentypen in GoogleSQL und PostgreSQL-Datentypen beschrieben werden.
Primärschlüssel auswählen
Spanner-Datenbanken können eine oder mehrere Tabellen enthalten. Tabellen sind strukturiert als Zeilen und Spalten. Das Tabellenschema definiert eine oder mehrere Tabellenspalten Primärschlüssel der Tabelle, der jede Zeile eindeutig identifiziert. Primärschlüssel sind immer für die schnelle Zeilensuche indexiert. Wenn Sie vorhandene Zeilen in einer Tabelle aktualisieren oder löschen möchten, muss die Tabelle einen Primärschlüssel haben. Eine Tabelle ohne primäre Tabelle Schlüsselspalten dürfen nur eine Zeile enthalten. Nur GoogleSQL-Dialekt-Datenbanken können ohne Primärschlüssel verwenden.
Häufig verfügt Ihre Anwendung bereits über ein Feld, das sich gut für das
Primärschlüssel. In einer Customers
-Tabelle kann beispielsweise eine von einer Anwendung bereitgestellte CustomerId
vorhanden sein, die als Primärschlüssel dient. In anderen
müssen Sie beim Einfügen der Zeile möglicherweise einen Primärschlüssel generieren. Dieses
normalerweise ein eindeutiger Ganzzahlwert ohne geschäftliche Signifikanz (ein
Ersatzschlüsselwert).
In allen Fällen sollten Sie darauf achten, keine Hotspots mit der Wahl Ihres Primärschlüssels zu erstellen. Wenn Sie beispielsweise Datensätze mit einer monoton ansteigenden Ganzzahl als Schlüssel einfügen, fügen Sie sie immer am Ende des Schlüsselbereichs ein. Dies ist nicht wünschenswert, da Spanner die Daten zwischen nach Schlüsselbereichen sortiert. Das bedeutet, dass Ihre Einfügungen auf einen einzelnen einen Hotspot erstellt. Mit diesen Verfahren können Sie die Last auf mehrere Server verteilen und Hotspots vermeiden:
- Hashen Sie den Schlüssel und speichern Sie ihn unter eine Spalte. Verwenden Sie die Hash-Spalte (oder die Hash-Spalte und die Spalten mit dem eindeutigen Schlüssel) als Primärschlüssel.
- Vertauschen Sie die Reihenfolge der Spalten im Primärschlüssel.
- Universally Unique Identifier verwenden (UUID) dar. Version 4 UUID wird empfohlen, da hierbei in den Bits höherer Ordnung. Verwenden Sie keinen UUID-Algorithmus (beispielsweise Version 1 der UUID), bei dem der Zeitstempel in den Bits höherer Ordnung gespeichert wird.
- Bit-Umkehrungen für sequenzielle Werte
Hierarchische Tabellenbeziehungen
Es gibt zwei Möglichkeiten, über- und untergeordnete Beziehungen in Spanner: Tabellenverschränkung und Fremdschlüssel.
Die Tabellenverschränkung von Spanner ist für viele
Parent-Child-Beziehungen. Mit Verschränkung kann Spanner physisch
ordnet im Speicher untergeordnete Zeilen mit übergeordneten Zeilen an. Die gemeinsame Anordnung kann die Leistung erheblich verbessern. Beispiel: Sie haben eine Customers
-Tabelle und eine
Invoices
verwendet und Ihre Anwendung ruft häufig alle Rechnungen für eine
können Sie Invoices
als verschränkte untergeordnete Tabelle
Customers
Damit deklarieren Sie eine Datenlokalitätsbeziehung zwischen zwei unabhängigen Tabellen. Sie weisen Spanner an, eine oder mehrere Zeilen von Invoices
mit einer Customers
-Zeile zu speichern.
Sie verknüpfen eine untergeordnete Tabelle mit einer übergeordneten Tabelle mithilfe von DDL, die die untergeordnete Tabelle, da sie mit der übergeordneten Tabelle verschränkt ist, und durch Einbeziehen der übergeordneten Tabelle. Primärschlüssel als ersten Teil des zusammengesetzten Primärschlüssels der untergeordneten Tabelle. Weitere Informationen Informationen zur Verschränkung finden Sie weiter unten im Abschnitt Verschränkte Tabellen erstellen. Seite.
Fremdschlüssel sind eine allgemeinere über-/untergeordnete Lösung, die zusätzliche Anwendungsfälle behandelt. Sie sind nicht auf Primärschlüsselspalten beschränkt und Tabellen können mehrere Fremdschlüsselbeziehungen haben, die in einigen Beziehungen als übergeordnete und in anderen als untergeordnete Beziehungen gelten. Eine Fremdschlüsselbeziehung impliziert jedoch nicht, dass sich die Tabellen auf der Speicherebene befinden.
Google empfiehlt, dass Sie hierarchische Beziehungen entweder als verschränkte Tabellen oder als Fremdschlüssel darstellen, aber nicht beides. Weitere Informationen zu Fremdschlüsseln und ihrem Vergleich mit verschränkten Tabellen finden Sie in der Übersicht über Fremdschlüssel.
Primärschlüssel in verschränkten Tabellen
Für das Interleaving muss jede Tabelle einen Primärschlüssel haben. Wenn Sie eine Tabelle für einer anderen Tabelle untergeordnet sein, muss die Tabelle ein zusammengesetztes Primärschlüssel, der alle Komponenten des Primärschlüssels des übergeordneten Schlüssels enthält, in in derselben Reihenfolge und normalerweise einer oder mehreren zusätzlichen untergeordneten Tabellenspalten.
Spanner speichert Zeilen in einer Reihenfolge nach Primärschlüsselwerten, wobei untergeordnete Zeilen zwischen übergeordneten Zeilen eingefügt werden. Eine Abbildung verschränkter Zeilen finden Sie weiter unten im Abschnitt Verschränkte Tabellen erstellen.
Zusammenfassung: Mit Spanner können Sie Zeilen relationaler Tabellen physisch gemeinsam speichern. Die Schemabeispiele zeigen, wie dieses physische Layout aussieht.
Datenbankaufteilungen
Sie können Hierarchien von über- und untergeordneten Beziehungen bis zu sieben Layers tief sind, was bedeutet, dass Sie Zeilen aus sieben unabhängigen Tabellen ansammeln können. Wenn die Größe der Daten in Ihren Tabellen gering ist, kann Ihre Datenbank wahrscheinlich von einem einzigen Spanner-Server verarbeitet werden. Aber was passiert, wenn Ihre relationalen Tabellen wachsen und die Ressourcengrenzen eines einzelnen Servers erreichen? Spanner ist eine verteilte Datenbank. Das bedeutet, dass die Daten in Spanner bei wachsender Datenbank in Portionen aufgeteilt werden, die als „Splits“ bezeichnet werden. Aufteilungen können sich unabhängig voneinander bewegen und verschiedenen Servern zugewiesen werden, die sich an verschiedenen physischen Standorten befinden können. Ein Split enthält einen Bereich von zusammenhängenden Zeilen. Die Start- und Endschlüssel dieses Bereichs werden als „Split-Grenzen“ bezeichnet. Spanner fügt automatisch Split-Grenzen entsprechend der Größe und Last hinzu und entfernt sie. Dadurch verändert sich die Anzahl der Splits in der Datenbank.
Lastbasierte Aufteilung
Als Beispiel dafür, wie Spanner die lastbasierte Aufteilung zur Vermeidung von Hotspots vornimmt, gehen Sie erst einmal davon aus, dass Ihre Datenbank eine Tabelle mit 10 Zeilen enthält, die öfter gelesen werden als alle anderen Zeilen in der Tabelle. Spanner kann Split-Grenzen zwischen jeder dieser 10 Zeilen einfügen, sodass sie alle von einem anderen Server verarbeitet werden, anstatt dass alle Lesevorgänge dieser Zeilen die Ressourcen eines einzelnen Servers verbrauchen können.
Wenn Sie die Best Practices für das Schemadesign befolgen, kann Spanner Hotspots in der Regel so abmildern, dass sich der Lesedurchsatz alle paar Minuten verbessern sollte, bis die Ressourcen in Ihrer Instanz ausgelastet sind oder keine neuen Split-Grenzen hinzugefügt werden können, weil ein Split nur eine einzelne Zeile ohne verschränkte untergeordnete Zeilen abdeckt.
Benannte Schemas
Mit benannten Schemas können Sie ähnliche Daten organisieren. So können Sie Objekte in der Google Cloud Console schnell finden, Berechtigungen anwenden und Namenskonflikte vermeiden.
Benannte Schemas werden wie andere Datenbankobjekte mithilfe von DDL verwaltet.
Bei benannten Spanner-Schemas können Sie voll qualifizierte Namen (Fully Qualified Names, FQNs) verwenden, um Daten abzufragen. Mit vollständig qualifizierten Objektnamen können Sie den Schemanamen und den Objektnamen kombinieren, um Datenbankobjekte zu identifizieren. Sie könnten beispielsweise ein Schema namens warehouse
für die Lagerabteilung erstellen. Die Tabellen, in denen diese
Schema kann product
, order
und customer information
umfassen. Oder Sie
könnte ein Schema mit dem Namen fulfillment
für die Geschäftseinheit „Fulfillment“ erstellen.
Dieses Schema könnte auch Tabellen mit den Namen product
, order
und customer
information
enthalten. Im ersten Beispiel ist warehouse.product
der vollständige Pfadname und im zweiten Beispiel fulfillment.product
. So wird vermieden, dass mehrere Objekte denselben Namen haben.
In der DDL-Datei CREATE SCHEMA
erhalten Tabellenobjekte eine FQN. Beispiel:
sales.customers
und einen Kurznamen, z. B. sales
.
Die folgenden Datenbankobjekte unterstützen benannte Schemas:
TABLE
CREATE
INTERLEAVE IN [PARENT]
FOREIGN KEY
SYNONYM
VIEW
INDEX
FOREIGN KEY
SEQUENCE
Weitere Informationen zur Verwendung benannter Schemas finden Sie unter Benannte Schemas verwalten.
Detaillierte Zugriffssteuerung mit benannten Schemas verwenden
Mit benannten Schemas können Sie jedem Objekt im Schema Zugriff auf Schemaebene gewähren. Das gilt für Schemaobjekte, die zum Zeitpunkt der Zugriffsberechtigung vorhanden sind. Sie müssen Zugriff auf Objekte gewähren, die später hinzugefügt werden.
Die detaillierte Zugriffssteuerung schränkt den Zugriff auf ganze Gruppen von Datenbankobjekten ein, z. B. Tabellen, Spalten und Zeilen in der Tabelle.
Weitere Informationen finden Sie unter Gewähren von detaillierten Zugriffssteuerungsberechtigungen für Schemas auf.
Schemabeispiele
Die Schemabeispiele in diesem Abschnitt zeigen, wie Sie übergeordnete und untergeordnete Tabellen mit und ohne Verschachtelung und veranschaulichen die entsprechenden physischen Layouts von Daten.
Übergeordnete Tabelle erstellen
Angenommen, Sie erstellen eine Musikanwendung und benötigen eine Tabelle, in der Zeilen mit Sängerdaten gespeichert werden:
Beachten Sie, dass die Tabelle eine Primärschlüsselspalte SingerId
enthält, die angezeigt wird,
links von der fett gedruckten Linie
Spalten.
Sie können die Tabelle mit der folgenden DDL definieren:
GoogleSQL
CREATE TABLE Singers ( SingerId INT64 NOT NULL, FirstName STRING(1024), LastName STRING(1024), SingerInfo BYTES(MAX), ) PRIMARY KEY (SingerId);
PostgreSQL
CREATE TABLE singers ( singer_id BIGINT PRIMARY KEY, first_name VARCHAR(1024), last_name VARCHAR(1024), singer_info BYTEA );
Beachten Sie Folgendes zum Beispielschema:
Singers
ist eine Tabelle im Stammverzeichnis der Datenbankhierarchie, da sie nicht als verschränktes untergeordnetes Element einer anderen Tabelle definiert ist.- Bei GoogleSQL-Datenbanken sind Primärschlüsselspalten in der Regel mit
NOT NULL
annotiert. Sie können diese Annotation jedoch weglassen, wennNULL
-Werte in Schlüsselspalten zulässig sein sollen. Weitere Informationen finden Sie unter Schlüsselspalten. - Nicht im Primärschlüssel enthaltene Spalten werden als Nicht-Schlüsselspalten bezeichnet und können die optionale Annotation
NOT NULL
enthalten. - Spalten, die den Typ
STRING
oderBYTES
in GoogleSQL verwenden, müssen mit einer Länge definiert, die die maximale Anzahl von Unicode-Zeichen Zeichen, die im Feld gespeichert werden können. Die Längenspezifikation ist für die PostgreSQL-Typenvarchar
undcharacter varying
optional. Weitere Informationen finden Sie unter Skaläre Datentypen für Datenbanken mit GoogleSQL-Dialekt und PostgreSQL-Datentypen für Datenbanken mit PostgreSQL-Dialekt.
Wie sieht das physische Layout der Zeilen in der Tabelle Singers
aus? Das folgende Diagramm zeigt Zeilen der Tabelle Singers
, die nach dem Primärschlüssel gespeichert wurden („Sänger(1)“ und dann „Sänger(2)“, wobei die Zahl in Klammern der Primärschlüsselwert ist.
Das obige Diagramm zeigt ein Beispiel für eine Split-Grenze zwischen den Zeilen
durch Singers(3)
und Singers(4)
verschlüsselt, wobei die Daten aus den resultierenden Splits
die verschiedenen Servern zugewiesen sind. Das bedeutet, dass mit dieser Tabelle Zeilen von Singers
-Daten an verschiedenen Standorten gespeichert werden können.
Übergeordnete und untergeordnete Tabellen erstellen
Angenommen, Sie möchten jetzt in der Musikanwendung einige grundlegende Daten zum Album jedes Sängers hinzufügen.
Beachten Sie, dass der Primärschlüssel von Albums
aus zwei Spalten besteht: SingerId
und AlbumId
, um jedes Album mit seinem Sänger zu verknüpfen. Das im Folgenden aufgeführte Beispielschema definiert sowohl die Albums
- als auch die Singers
-Tabelle im Stamm der Datenbankhierarchie. Damit sind diese Tabellen hierarchisch gleichgeordnet.
-- Schema hierarchy: -- + Singers (sibling table of Albums) -- + Albums (sibling table of Singers)
GoogleSQL
CREATE TABLE Singers ( SingerId INT64 NOT NULL, FirstName STRING(1024), LastName STRING(1024), SingerInfo BYTES(MAX), ) PRIMARY KEY (SingerId); CREATE TABLE Albums ( SingerId INT64 NOT NULL, AlbumId INT64 NOT NULL, AlbumTitle STRING(MAX), ) PRIMARY KEY (SingerId, AlbumId);
PostgreSQL
CREATE TABLE singers ( singer_id BIGINT PRIMARY KEY, first_name VARCHAR(1024), last_name VARCHAR(1024), singer_info BYTEA ); CREATE TABLE albums ( singer_id BIGINT, album_id BIGINT, album_title VARCHAR, PRIMARY KEY (singer_id, album_id) );
Das physische Layout der Zeilen von Singers
und Albums
sieht wie folgt aus:
folgendes Diagramm mit Zeilen der Tabelle Albums
, die von zusammenhängenden primären Instanzen gespeichert sind
Schlüssel, dann Zeilen von Singers
, die durch zusammenhängenden Primärschlüssel gespeichert sind:
Ein wichtiger Hinweis zum Schema ist, dass Spanner davon ausgeht,
Datenlokalitätsbeziehungen zwischen den Tabellen Singers
und Albums
,
sind die Tabellen der obersten Ebene. Wenn die Datenbank wächst, kann Spanner Split-Grenzen zwischen allen Zeilen einfügen. Das bedeutet, dass die Zeilen von Albums
Tabelle könnte sich in einem anderen Split als die Zeilen der Tabelle Singers
befinden,
und die beiden Teilungen könnten sich
unabhängig voneinander bewegen.
Je nach den Anforderungen Ihrer Anwendung kann es sinnvoll sein, dass Albums
-Daten auf verschiedenen Splits von Singers
-Daten gespeichert werden. Dies kann jedoch
Leistungseinbußen aufgrund der Notwendigkeit, Lesevorgänge und Aktualisierungen
unterschiedlichen Ressourcen. Wenn Ihre Anwendung häufig Informationen abrufen muss
Alben für einen bestimmten Sänger suchen, sollten Sie Albums
als
eine verschränkte untergeordnete Tabelle von Singers
, die Zeilen aus den beiden
mit der Primärschlüsseldimension. Im nächsten Beispiel wird dies genauer erläutert.
Verschränkte Tabellen erstellen
Eine verschränkte Tabelle ist eine Tabelle, die Sie als verschränkte untergeordnete Tabelle einer anderen Tabelle deklarieren, weil die Zeilen der untergeordneten Tabelle zusammen mit der zugehörigen übergeordneten Zeile gespeichert werden sollen. Wie bereits erwähnt, ist die übergeordnete Tabelle Primärschlüssel muss der erste Teil des zusammengesetzten Primärschlüssels der untergeordneten Tabelle sein.
Angenommen, Sie stellen beim Entwerfen Ihrer Musik-App fest, dass die App häufig auf Zeilen aus der Tabelle Albums
zugreifen muss, wenn sie auf eine Zeile Singers
zugreift. Wenn Sie beispielsweise auf Zeile Singers(1)
zugreifen, müssen Sie auch auf die Zeilen Albums(1, 1)
und Albums(1, 2)
zugreifen. In diesem Fall Singers
und Albums
müssen eine starke Daten-Lokalität-Beziehung haben. Sie können diese Datenlokalitätsbeziehung durch Erstellen der Tabelle Albums
als verschränkte untergeordnete Tabelle von Singers
angeben.
-- Schema hierarchy: -- + Singers -- + Albums (interleaved table, child table of Singers)
Die fett gedruckte Zeile im folgenden Schema zeigt, wie Albums
als
verschränkte Tabelle von Singers
.
GoogleSQL
CREATE TABLE Singers ( SingerId INT64 NOT NULL, FirstName STRING(1024), LastName STRING(1024), SingerInfo BYTES(MAX), ) PRIMARY KEY (SingerId); CREATE TABLE Albums ( SingerId INT64 NOT NULL, AlbumId INT64 NOT NULL, AlbumTitle STRING(MAX), ) PRIMARY KEY (SingerId, AlbumId), INTERLEAVE IN PARENT Singers ON DELETE CASCADE;
PostgreSQL
CREATE TABLE singers ( singer_id BIGINT PRIMARY KEY, first_name VARCHAR(1024), last_name VARCHAR(1024), singer_info BYTEA ); CREATE TABLE albums ( singer_id BIGINT, album_id BIGINT, album_title VARCHAR, PRIMARY KEY (singer_id, album_id) ) INTERLEAVE IN PARENT singers ON DELETE CASCADE;
Hinweise zu diesem Schema:
SingerId
: Dies ist der erste Teil des Primärschlüssels der untergeordneten Tabelle.Albums
ist auch der Primärschlüssel der übergeordneten TabelleSingers
.- Die
ON DELETE CASCADE
-Anmerkung bedeutet, dass beim Löschen einer Zeile aus der übergeordneten Tabelle die werden untergeordnete Zeilen ebenfalls automatisch gelöscht. Wenn eine untergeordnete Tabelle diese Annotation nicht enthält oder die AnnotationON DELETE NO ACTION
lautet, müssen Sie die untergeordneten Zeilen löschen, bevor Sie die übergeordnete Zeile löschen können. - Verschränkte Zeilen werden zuerst nach Zeilen der übergeordneten Tabelle und dann nach zusammenhängenden Zeilen der untergeordneten Tabelle mit dem Primärschlüssel des übergeordneten Elements sortiert. Für Beispiel: "Singers(1)", dann "Albums(1, 1)" und dann "Albums(1, 2)".
- Die Datenlokalitätsbeziehung zwischen jedem Sänger und dessen Albumdaten bleibt erhalten, wenn diese Datenbank aufgeteilt wird, sofern die Größe einer
Singers
-Zeile und aller ihrerAlbums
-Zeilen unter dem Grenzwert für die Größe des Splits bleibt und es keinen Hotspot in einer dieserAlbums
-Zeilen gibt. - Nur wenn eine übergeordnete Zeile existiert, können Sie untergeordnete Zeilen einfügen. In der übergeordneten Zeile können entweder bereits in der Datenbank vorhanden sein oder vor dem Tag Einfügen der untergeordneten Zeilen in derselben Transaktion.
Hierarchie von verschränkten Tabellen erstellen
Die hierarchische Beziehung zwischen Singers
und Albums
kann auf weitere nachfolgende Tabellen erweitert werden. Beispielsweise können Sie eine verschränkte Tabelle namens Songs
als untergeordnetes Element von Albums
erstellen, um die Trackliste jedes Albums zu speichern:
Songs
muss einen Primärschlüssel haben, der alle Primärschlüssel der Tabellen enthält.
die sich auf einer höheren Hierarchieebene befinden, also SingerId
und AlbumId
.
-- Schema hierarchy: -- + Singers -- + Albums (interleaved table, child table of Singers) -- + Songs (interleaved table, child table of Albums)
GoogleSQL
CREATE TABLE Singers ( SingerId INT64 NOT NULL, FirstName STRING(1024), LastName STRING(1024), SingerInfo BYTES(MAX), ) PRIMARY KEY (SingerId); CREATE TABLE Albums ( SingerId INT64 NOT NULL, AlbumId INT64 NOT NULL, AlbumTitle STRING(MAX), ) PRIMARY KEY (SingerId, AlbumId), INTERLEAVE IN PARENT Singers ON DELETE CASCADE; CREATE TABLE Songs ( SingerId INT64 NOT NULL, AlbumId INT64 NOT NULL, TrackId INT64 NOT NULL, SongName STRING(MAX), ) PRIMARY KEY (SingerId, AlbumId, TrackId), INTERLEAVE IN PARENT Albums ON DELETE CASCADE;
PostgreSQL
CREATE TABLE singers ( singer_id BIGINT PRIMARY KEY, first_name VARCHAR(1024), last_name VARCHAR(1024), singer_info BYTEA ); CREATE TABLE albums ( singer_id BIGINT, album_id BIGINT, album_title VARCHAR, PRIMARY KEY (singer_id, album_id) ) INTERLEAVE IN PARENT singers ON DELETE CASCADE; CREATE TABLE songs ( singer_id BIGINT, album_id BIGINT, track_id BIGINT, song_name VARCHAR, PRIMARY KEY (singer_id, album_id, track_id) ) INTERLEAVE IN PARENT albums ON DELETE CASCADE;
Das folgende Diagramm zeigt eine physische Ansicht der verschränkten Zeilen.
In diesem Beispiel fügt Spanner bei steigender Anzahl der Sänger zwischen Sängerinnen und Sängern, um die Datenlokalität zwischen Sängerinnen und Sängern zu wahren Album- und Songdaten. Wenn jedoch die Größe einer Sängerin-Zeile und ihrer untergeordneten Zeilen die Split-Größenbeschränkung überschreitet oder in den untergeordneten Zeilen ein Hotspot erkannt wird, Spanner versucht, Split-Grenzen hinzuzufügen, um diesen Hotspot zu isolieren Zeile mit allen untergeordneten Zeilen ein.
Zusammenfassung: Eine übergeordnete Tabelle bildet zusammen mit allen untergeordneten und nachfolgenden Tabellen im Schema eine Tabellenhierarchie. Obwohl jede Tabelle in der Hierarchie logisch unabhängig ist, können Sie durch diese physische Verschränkung die Leistung verbessern, da die Tabellen schon vorab verknüpft werden. Dadurch können Sie auf die Zeilen der relationalen Tabellen zusammen zugreifen und gleichzeitig die Zugriffe auf den Speicher minimieren.
Joins mit verschachtelten Tabellen
Verbinden Sie nach Möglichkeit Daten in verschränkten Tabellen mit dem Primärschlüssel. Da jede verschränkte Zeile normalerweise physisch in demselben Split wie die entsprechende übergeordnete Zeile gespeichert ist, kann Spanner lokale Zusammenführungen mit dem Primärschlüssel durchführen und so den Zugriff auf das Speichersystem und den Netzwerkverkehr minimieren. Im folgenden Beispiel werden Singers
und
Albums
werden über den Primärschlüssel SingerId
verknüpft.
GoogleSQL
SELECT s.FirstName, a.AlbumTitle FROM Singers AS s JOIN Albums AS a ON s.SingerId = a.SingerId;
PostgreSQL
SELECT s.first_name, a.album_title FROM singers AS s JOIN albums AS a ON s.singer_id = a.singer_id;
Schlüsselspalten
Dieser Abschnitt enthält einige Hinweise zu Schlüsselspalten.
Tabellenschlüssel ändern
An den Schlüsseln einer Tabelle sind keine Änderungen möglich: Sie können weder eine Schlüsselspalte zu einer vorhandenen Tabelle hinzufügen noch eine Schlüsselspalte aus einer vorhandenen Tabelle entfernen.
NULL-Werte in einem Primärschlüssel speichern
Wenn Sie in GoogleSQL NULL in einer Primärschlüsselspalte speichern möchten,
NOT NULL
-Klausel für diese Spalte im Schema weglassen. (Datenbanken mit PostgreSQL-Dialekt)
NULL-Werte in einer Primärschlüsselspalte unterstützen.)
Das folgende Beispiel zeigt das Weglassen der NOT NULL
-Klausel in der Primärschlüsselspalte SingerId
. Da SingerId
der Primärschlüssel ist, kann
eine Zeile, in der NULL
in dieser Spalte gespeichert ist.
CREATE TABLE Singers ( SingerId INT64, FirstName STRING(1024), LastName STRING(1024), ) PRIMARY KEY (SingerId);
Die Eigenschaft der Primärschlüsselspalte, für die Nullwerte zulässig sind, muss zwischen der übergeordneten und der untergeordneten Tabellendeklaration übereinstimmen. In diesem Beispiel ist NOT NULL
für die Spalte Albums.SingerId
nicht zulässig, da sie in Singers.SingerId
weggelassen wird.
CREATE TABLE Singers ( SingerId INT64, FirstName STRING(1024), LastName STRING(1024), ) PRIMARY KEY (SingerId); CREATE TABLE Albums ( SingerId INT64 NOT NULL, AlbumId INT64 NOT NULL, AlbumTitle STRING(MAX), ) PRIMARY KEY (SingerId, AlbumId), INTERLEAVE IN PARENT Singers ON DELETE CASCADE;
Unzulässige Typen
Die folgenden Spalten können nicht vom Typ ARRAY
sein:
- Die Schlüsselspalten einer Tabelle
- Die Schlüsselspalten eines Index
Mehrinstanzenfähigkeit berücksichtigen
Falls Sie Daten speichern, die verschiedenen Kunden gehören, möchten Sie eventuell für Mehrinstanzenfähigkeit sorgen. Ein Musikdienst könnte beispielsweise die Inhalte der einzelnen Plattenlabel separat anzeigen.
Klassische Mehrinstanzenfähigkeit
Der gängige Ansatz, für Mehrinstanzenfähigkeit zu sorgen, besteht darin, für jeden Kunden eine eigene Datenbank zu erstellen. In diesem Beispiel hat jede Datenbank ihre eigene Tabelle Singers
:
SingerId | FirstName | LastName |
---|---|---|
1 | Marc | Richards |
2 | Catalina | Smith |
SingerId | FirstName | LastName |
---|---|---|
1 | Alice | Trentor |
2 | Gabriel | Wright |
SingerId | FirstName | LastName |
---|---|---|
1 | Benjamin | Martinez |
2 | Hanna | Harris |
Schemaverwaltete Mehrinstanzenfähigkeit
Eine weitere Möglichkeit für die
Mehrmandantenfähigkeit in Spanner besteht darin,
in einer einzigen Tabelle in einer Datenbank
beliefern und eine andere primäre
Schlüssel/Wert-Paar-Targeting für jeden Kunden. Sie können beispielsweise eine Spalte mit dem Schlüssel CustomerId
in Ihre Tabellen aufnehmen. Wenn Sie CustomerId
zur ersten Schlüsselspalte erklären, ist die Lokalität der Daten für jeden Kunden passend. Spanner kann dann effektiv Datenbank-Splits verwenden, um die Leistung anhand von Datengröße und Lademustern zu maximieren. Im folgenden Beispiel gibt es eine einzige Singers
-Tabelle für alle Kunden:
CustomerId | SingerId | FirstName | LastName |
---|---|---|---|
1 | 1 | Marc | Richards |
1 | 2 | Catalina | Smith |
2 | 1 | Alice | Trentor |
2 | 2 | Gabriel | Wright |
3 | 1 | Benjamin | Martinez |
3 | 2 | Hanna | Harris |
Wenn Sie für jeden Mandanten eine eigene Datenbank benötigen, wissen Sie über Folgendes:
- Es gelten Beschränkungen für die Anzahl der Datenbanken pro Instanz und für die Anzahl der Tabellen und Indexe pro Datenbank. Je nach Anzahl der sind möglicherweise keine separaten Datenbanken oder Tabellen möglich.
- Das Hinzufügen neuer Tabellen und nicht verschränkter Indexe kann lange dauern. Wenn Ihre Schemas so gestaltet sind, dass das Hinzufügen neuer Tabellen und Indexe erforderlich ist, können Sie möglicherweise nicht die gewünschte Leistung erzielen.
Das Erstellen separater Datenbanken funktioniert eventuell besser, wenn Sie Ihre Tabellen so auf die Datenbanken verteilen, dass jede Datenbank eine geringe Anzahl von Schemaänderungen pro Woche aufweist.
Wenn Sie bei Ihrer Anwendung für jeden Kunden separate Tabellen und Indexe erstellen, sollten Sie nicht alle Tabellen und Indexe in derselben Datenbank ablegen. Teilen Sie stattdessen in vielen Datenbanken ausführen, um die Leistung Probleme beim Erstellen einer großen Anzahl von Indexen.
Um mehr über andere Datenverwaltungsmuster und das Anwendungsdesign für Mehrmandantenfähigkeit finden Sie unter Implementierung von Mehrmandantenfähigkeit in Cloud Spanner