Schemas – Übersicht

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. 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 in verschiedenen 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 den 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:

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 Schlüssels 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 Last, wodurch sich die Anzahl der Splits in in der Datenbank.

Lastbasierte Aufteilung

Ein Beispiel dafür, wie Spanner eine lastbasierte Aufteilung Angenommen, 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 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, Zeilen mit Sängerdaten:

Tabelle mit fünf Zeilen und vier Spalten

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 Sie NULL-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 oder BYTES 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.

Beispielzeilen einer Tabelle, die in Primärschlüsselreihenfolge gespeichert sind

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.

Tabelle "Albums" mit fünf Zeilen und drei Spalten

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:

Physisches Layout von Zeilen

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 der Datei 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, kann 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 Tabelle Singers.
  • 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 Annotation ON 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örigen Albums Zeilen unter der Grenze für die geteilte Größe bleiben Kein Hotspot in keiner dieser Albums 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.

"Albums"-Zeilen sind zwischen "Albums"-Zeilen verschränkt

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:

Tabelle „Songs“ mit sechs Zeilen und vier Spalten

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.

Songs sind in "Albums" verschränkt, die zwischen "Albums" verschränkt sind.

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 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 sind logisch unabhängig und können auf diese Weise 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, für verschiedene Kunden. 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:

Datenbank 1: Ackworth Records
SingerId FirstName LastName
1MarcRichards
2CatalinaSmith
Datenbank 2: Cama Records
SingerId FirstName LastName
1AliceTrentor
2GabrielWright
Datenbank 3: Eagan Records
SingerId FirstName LastName
1BenjaminMartinez
2HannaHarris

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:

Spanner-Datenbank für Mehrmandantenfähigkeit
CustomerId SingerId FirstName LastName
11MarcRichards
12CatalinaSmith
21AliceTrentor
22GabrielWright
31BenjaminMartinez
32HannaHarris

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