Auf dieser Seite werden die Anforderungen für das Spanner-Schema, die Verwendung des Schemas 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. Sie verwenden Schemas, um Objekte zu organisieren, eine detaillierte Zugriffssteuerung anzuwenden Berechtigungen und vermeiden Namenskonflikte. Sie müssen für jede Datenbank in Spanner.
Sie können Zeilen in Ihrer Datenbanktabelle auch unterschiedlichen geografischen Regionen. Weitere Informationen finden Sie in der Geo-Partitionierung – Übersicht
Stark typisierte Daten
Daten in Spanner sind stark typisiert. Zu den Datentypen gehören skalare und komplexe , die unter Datentypen in GoogleSQL beschrieben werden. und PostgreSQL-Datentypen.
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 eine schnelle Zeilensuche indexiert. Wenn Sie vorhandene Zeilen in einer Tabelle 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. Für die Tabelle Customers
könnte beispielsweise ein
von der Anwendung bereitgestelltes CustomerId
, das 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). zusammen) als Primärschlüssel verwenden.
- 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 (z. B. Version 1 der UUID), bei der 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. Durch Verschränkung kann Spanner physisch
ordnet im Speicher untergeordnete Zeilen mit übergeordneten Zeilen an. Eine Colocations-Einrichtung kann erheblich
die Leistung zu 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
Dazu deklarieren Sie eine Datenlokalitätsbeziehung zwischen
zwei unabhängige Tabellen. Sie geben Spanner an,
zum Speichern einer oder mehrerer Zeilen von Invoices
mit einer Customers
-Zeile.
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üssel und ihr Vergleich mit verschränkten Tabellen finden Sie unter Fremdschlüssel Übersicht.
Primärschlüssel in verschränkten Tabellen
Zum Verschachteln 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 Elements enthält, in in derselben Reihenfolge und normalerweise einer oder mehreren zusätzlichen untergeordneten Tabellenspalten.
Spanner speichert Zeilen in sortierter Reihenfolge nach Primärschlüsselwerten, wobei untergeordnete Zeilen zwischen übergeordneten Zeilen eingefügt. Abbildung von verschränkten Zeilen ansehen im Abschnitt Verschränkte Tabellen erstellen weiter unten auf dieser Seite.
Zusammenfassend lässt sich sagen, dass Spanner Zeilen zusammengehöriger Tabellen physisch zusammenfassen kann. 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 Daten in Ihren Tabellen klein sind, Ihre Datenbank verarbeiten kann. Aber was passiert, wenn Ihre verwandten Tabellen wachsen und die Ressourcenlimits eines einzelnen Servers erreichen? Spanner ist eine verteilte Datenbank. Das bedeutet, dass Sie wächst, teilt Spanner Ihre Daten in Blöcke namens „Splits“. Aufteilungen können sich unabhängig voneinander bewegen und verschiedenen Servern zugewiesen werden, die sich an verschiedenen physischen Standorten befinden können. A Split enthält einen Bereich zusammenhängender Zeilen. Die Start- und Endschlüssel dieses Bereichs sind als „Split-Grenzen“ bezeichnet. Spanner fügt automatisch ein und entfernt basierend auf Größe und Auslastung, wodurch sich die Anzahl der Splits in in der Datenbank.
Lastbasierte Aufteilung
Ein Beispiel dafür, wie Spanner eine lastbasierte Aufteilung Nehmen wir an, Ihre Datenbank enthält eine Tabelle mit 10 Zeilen, häufiger gelesen als alle anderen Zeilen in der Tabelle. Spanner kann Split-Grenzen zwischen jeder dieser 10 Zeilen hinzufügen, Sie werden jeweils von einem anderen Server verarbeitet, anstatt alle liest diese Zeilen, um die Ressourcen eines einzelnen Servers zu verbrauchen.
Grundsätzlich gilt: Wenn Sie die Best Practices für das Schemadesign befolgen, Spanner kann Hotspots abschwächen, sodass der Lesedurchsatz sollte sich alle paar Minuten verbessern, bis die Ressourcen gesättigt sind. oder es kommt zu Fällen, in denen keine neuen Split-Grenzen hinzugefügt werden können (da Sie haben einen Split, der nur eine einzelne Zeile ohne verschränkte untergeordnete Elemente abdeckt.
Benannte Schemas
Mit benannten Schemas können Sie ähnliche Daten organisieren. So können Sie schnell Objekte in der Google Cloud Console suchen, Berechtigungen anwenden und keine Kollisionen.
Benannte Schemas werden wie andere Datenbankobjekte mit DDL verwaltet.
Mit benannten Spanner-Schemas können Sie voll qualifizierte Namen verwenden
(FQNs) verwendet, um Daten abzufragen. Mit FQNs können Sie den Schemanamen und die
Objektname zur Identifizierung von Datenbankobjekten. Sie könnten z. B. ein Schema erstellen,
warehouse
für die Geschäftseinheit „Warehouse“. 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 lautet die FQN warehouse.product
.
zweiten Beispiels lautet die FQN fulfillment.product
. So werden Unklarheiten in
Situationen, in denen 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 Schemas auf.
Detaillierte Zugriffssteuerung mit benannten Schemas verwenden
Mit benannten Schemas können Sie jedem Objekt im Schema Zugriff auf Schemaebene gewähren. Dies gilt für Schemaobjekte, die vorhanden sind, wenn Sie Zugriff gewähren. Sie müssen Zugriff auf Objekte gewähren, die später hinzugefügt werden.
Eine differenzierte Zugriffssteuerung beschränkt den Zugriff auf ganze Gruppen von Datenbankobjekten, z. B. Tabellen, Spalten und Zeilen 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, Zeilen mit Sängerdaten:
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 auf der Stammebene der Datenbankhierarchie (da es sich nicht als verschränktes untergeordnetes Element einer anderen Tabelle definiert).- Bei GoogleSQL-Dialekt-Datenbanken werden Primärschlüsselspalten normalerweise mit
NOT NULL
annotiert (Sie können diese Annotation auslassen, wenn SieNULL
-Werte in Schlüsselspalten. Weitere Informationen finden Sie unter Schlüssel/Wert-Paare Spalten). - 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ängenangabe ist optional für die PostgreSQL-varchar
und -character varying
Typen. Weitere Informationen finden Sie unter Skalare Datentypen. für GoogleSQL-Dialekt-Datenbanken und PostgreSQL-Daten Typen für PostgreSQL-Dialekt-Datenbanken.
Wie sieht das physische Layout der Zeilen in der Tabelle Singers
aus? Die
Das folgende Diagramm zeigt Zeilen der Tabelle Singers
, die nach Primärschlüssel gespeichert sind.
("singer(1)" und dann "singer(2)", wobei die Zahl in Klammern für
den Primärschlüsselwert.
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. Wenn diese Tabelle größer wird, ist es möglich,
Singers
-Daten, die an verschiedenen Orten gespeichert werden.
Übergeordnete und untergeordnete Tabellen erstellen
Angenommen, Sie möchten nun einige grundlegende Daten zu den Alben der einzelnen Sänger hinzufügen, um in der Musik-App.
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 folgende Beispielschema
definiert sowohl die Tabelle Albums
als auch die Tabelle Singers
im Stammverzeichnis der Datenbank
Hierarchie, d. h., sie sind Tabellen 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 nach zusammenhängenden Primärschlüsseln 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
zwischen den Zeilen liegen müssen. 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 ausführlicher
Details.
Verschränkte Tabellen erstellen
Eine verschränkte Tabelle ist eine Tabelle, die Sie als verschränkte untergeordnete Tabelle deklarieren. eine andere Tabelle, da Sie möchten, dass die Zeilen der untergeordneten Tabelle physisch in der verknüpften übergeordneten Zeile gespeichert. Wie bereits erwähnt, ist die übergeordnete Tabelle Primärschlüssel muss der erste Teil des zusammengesetzten Primärschlüssels der untergeordneten Tabelle sein.
Nehmen wir an, Sie erkennen bei der Entwicklung Ihrer Musikanwendung, dass die App
muss häufig auf Zeilen aus der Tabelle Albums
zugreifen, wenn auf eine
Singers
Zeile. Wenn Sie beispielsweise auf die Zeile Singers(1)
zugreifen, müssen Sie außerdem
um auf die Zeilen Albums(1, 1)
und Albums(1, 2)
zuzugreifen. In diesem Fall Singers
und Albums
müssen eine starke Daten-Lokalität-Beziehung haben. Sie können Folgendes deklarieren:
Daten-Lokalitätsbeziehung durch Erstellen von Albums
als verschränktes untergeordnetes Element
Tabelle mit Singers
.
-- 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 keine diese AnnotationON DELETE NO ACTION
ist, müssen Sie die untergeordneten Zeilen löschen, bevor Sie die übergeordnete Zeile löschen können. - Verschränkte Zeilen werden zuerst nach den Zeilen der übergeordneten Tabelle geordnet, dann nach zusammenhängende Zeilen der untergeordneten Tabelle mit dem Primärschlüssel der übergeordneten Tabelle. Für Beispiel: "Singers(1)", dann "Albums(1, 1)" und dann "Albums(1, 2)".
- Die Datenlokalität zwischen den einzelnen Sängern und ihren Albumdaten
beibehalten, wenn diese Datenbank aufgeteilt wird, vorausgesetzt, die Größe einer
Singers
-Zeile und alle zugehörigenAlbums
Zeilen unter der Grenze für die geteilte Größe bleiben Kein Hotspot in keiner dieserAlbums
Zeilen. - 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 unterscheiden, um die Datenlokalität zwischen Sängern und Sängern 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 zusammen mit allen untergeordneten Zeilen an.
Zusammenfassung: Eine übergeordnete Tabelle bildet zusammen mit allen untergeordneten und nachfolgenden Tabellen im Schema eine Tabellenhierarchie. Obwohl jede Tabelle in der Hierarchie sind logisch unabhängig. Durch die physische Verschachtelung die Leistung, die effektive Vorabverknüpfung der Tabellen und die Möglichkeit, zusammengehörige Zeilen zugleich und gleichzeitig die Speicherzugriffe zu minimieren.
Joins mit verschränkten Tabellen
Verbinden Sie nach Möglichkeit Daten in verschränkten Tabellen mit dem Primärschlüssel. Da jedes einzelne
verschränkte Zeile wird normalerweise physisch im selben Split wie die übergeordnete Zeile gespeichert
Zeile kann Spanner lokal Joins anhand des Primärschlüssels ausführen. Dadurch wird
Speicherzugriff und Netzwerkverkehr. 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
ist nicht zulässig, da dies von 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 dürfen nicht vom Typ ARRAY
sein:
- Die Schlüsselspalten einer Tabelle
- Die Schlüsselspalten eines Index
Entwicklung für Mehrmandantenfähigkeit
Sie können die Mehrmandantenfähigkeit implementieren, wenn Sie Daten speichern, unterschiedlichen Kunden zu präsentieren. Ein Musikdienst könnte beispielsweise die Inhalte der einzelnen Plattenlabel separat anzeigen.
Klassische Mehrinstanzenfähigkeit
Der klassische Ansatz für Mehrmandantenfähigkeit besteht darin, eine separate Datenbank für
für jeden einzelnen Kunden. 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 |
Durch Schema verwaltete Mehrmandantenfähigkeit
Eine weitere Möglichkeit für Mehrmandantenfähigkeit in Spanner besteht darin, alle
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 einen CustomerId
-Schlüssel einfügen
Spalte in Ihren Tabellen. Wenn Sie CustomerId
als erste Schlüsselspalte festlegen,
die Daten für jeden Kunden
gut strukturiert sind. Spanner
können Datenbankaufteilungen effektiv nutzen, um die
basierend auf Datengröße und Lademustern. Im folgenden Beispiel
Es gibt 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 separate Datenbank benötigen, wissen Sie über Folgendes:
- Es gibt Limits für die Anzahl der Datenbanken pro Instanz sowie 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. Möglicherweise können Sie die gewünschte Leistung erzielen, neue Tabellen und Indexe hinzufügen.
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 für jeden Kunden Ihrer Anwendung separate Tabellen und Indexe erstellen, nicht alle Tabellen und Indexe in derselben Datenbank speichern. 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 Spanner