Questa pagina illustra i requisiti dello schema di Spanner e come utilizzare lo schema per creare relazioni gerarchiche e funzionalità dello schema. Inoltre, introduce con interleaving, che possono migliorare le prestazioni delle query quando si eseguono query sulle tabelle in una relazione genitore-figlio.
Uno schema è uno spazio dei nomi che contiene oggetti di database, come tabelle, visualizzazioni, indici e funzioni. Puoi usare gli schemi per organizzare gli oggetti, applicare un controllo dell'accesso granulare ed evitare collisioni di nomi. Devi definire uno schema per ogni database in Spanner.
Puoi anche segmentare ulteriormente e archiviare le righe nella tabella del database in diverse regioni geografiche. Per ulteriori informazioni, consulta Panoramica del partizionamento geografico.
Dati fortemente tipizzati
I dati in Spanner sono fortemente tipizzati. I tipi di dati includono scalari e complessi descritti in Tipi di dati in GoogleSQL e i tipi di dati di PostgreSQL.
Scegli una chiave principale
I database Spanner possono contenere una o più tabelle. Le tabelle sono strutturate come righe e colonne. Lo schema della tabella definisce una o più colonne della tabella come la chiave primaria della tabella che identifica in modo univoco ogni riga. Le chiavi principali sono sempre indicizzate per la ricerca rapida delle righe. Se vuoi aggiornare o eliminare righe esistenti in una tabella, la tabella deve avere una chiave primaria. Una tabella senza principale le colonne chiave possono avere una sola riga. Solo i database di dialetti GoogleSQL possono avere senza chiave primaria.
Spesso la tua applicazione ha già un campo che è adatto per l'utilizzo come chiave primaria. Ad esempio, per una tabella Customers
potrebbe essere presente un CustomerId
fornito dall'applicazione che funge da chiave primaria. In altri
casi, potrebbe essere necessario generare una chiave primaria durante l'inserimento della riga. In genere si tratta di un valore intero univoco senza significato commerciale (una chiave primaria surrogata).
In ogni caso, devi fare attenzione a non creare hot spot con la scelta della chiave primaria. Ad esempio, se inserisci record con un numero intero in aumento monotonico come chiave, lo inserirai sempre alla fine dello spazio della chiave. Questo comportamento è indesiderato perché Spanner divide i dati tra per intervalli di chiavi, il che significa che gli inserimenti saranno indirizzati a un singolo server, creando un hotspot. Esistono tecniche che possono distribuire il carico su più server ed evitare hotspot:
- Esegui l'hashing della chiave e archiviala in una colonna. Utilizzare la colonna hash (o la colonna hash e le colonne chiave univoche insieme) come chiave primaria.
- Scambia l'ordine della colonne nella chiave primaria.
- Utilizza un UUID (Universally Unique Identifier). Versione 4 L'opzione UUID è consigliata perché utilizza valori casuali nei bit di ordine più alto. Non utilizzare un algoritmo UUID (ad esempio version 1 UUID) che memorizza il timestamp nei bit di ordine superiore.
- Esegui l'inversione dei bit nei valori sequenziali.
Relazioni tabella padre-figlio
Esistono due modi per definire le relazioni padre-figlio in Spanner: interfoliazione delle tabelle e chiavi esterne.
L'interleaving delle tabelle di Spanner è una buona scelta per molte relazioni padre-figlio. Con l'interleaving, Spanner
colloca le righe figlio con righe padre nello spazio di archiviazione. La colocation può significativamente
a migliorare le prestazioni. Ad esempio, se hai una tabella Customers
e una
Invoices
e la tua applicazione recupera spesso tutte le fatture per un
puoi definire Invoices
come tabella secondaria con interleaving
Customers
. In questo modo dichiari una relazione di località dei dati tra
due tabelle indipendenti. Stai dicendo a Spanner di memorizzare una o più righe di Invoices
con una riga Customers
.
Per associare una tabella secondaria a una tabella padre, utilizza un DDL che dichiara tabella secondaria con interleaving in quella padre e includendo la tabella padre chiave primaria come prima parte della chiave primaria composita della tabella figlio. Per maggiori informazioni Informazioni sull'interfoliazione, consulta Creare tabelle con interleaving più avanti in questo .
Le chiavi esterne sono una soluzione padre-figlio più generica e sono adatte a ulteriori casi d'uso. Non si limitano alle colonne di chiave primaria e le tabelle possono avere più relazioni di chiave esterna, sia come genitore in alcune relazioni che come figlio altri. Tuttavia, una relazione di chiave esterna non implica la collocazione delle tabelle nel livello di archiviazione.
Google consiglia di scegliere di rappresentare le relazioni padre-figlio come tabelle con interleaving o come chiavi esterne, ma non entrambi. Per ulteriori informazioni sulle chiavi esterne e sul loro confronto con le tabelle con interleaving, consulta la Panoramica delle chiavi esterne.
Chiavi primarie nelle tabelle con interfoliazione
Per l'interlacciamento, ogni tabella deve avere una chiave primaria. Se dichiari una tabella essere un elemento figlio con interleaving di un'altra tabella, la tabella deve avere un chiave primaria che include tutti i componenti della chiave primaria dell'elemento padre, in nello stesso ordine e, in genere, in una o più colonne secondarie aggiuntive della tabella.
Spanner archivia le righe in ordine ordinato in base ai valori della chiave primaria, con righe secondarie inserite tra le righe principali. Guarda un'illustrazione di righe con interleaving in Crea tabelle con interleaving più avanti in questa pagina.
In sintesi, Spanner può collocare fisicamente le righe di tabelle correlate. Gli esempi di schema mostrano l'aspetto di questo layout fisico.
Suddivisione del database
Puoi definire gerarchie di relazioni padre-figlio con interleaving fino a sette livelli di profondità, il che significa che puoi collocare in modo colocalizzato le righe di sette tabelle indipendenti. Se la dimensione dei dati nelle tabelle è ridotta, un singolo Spanner in grado di gestire il database. Ma cosa succede quando le tabelle correlate crescono e iniziano a raggiungere i limiti di risorse di un singolo server? Spanner è un database distribuito, il che significa che, cresce, Spanner suddivide i dati in blocchi chiamati "divisioni". I singoli split possono spostarsi indipendentemente l'uno dall'altro e essere assegnati a server diversi, che possono trovarsi in località fisiche diverse. R che contiene un intervallo di righe contigue. Le chiavi iniziale e finale di questo intervallo sono chiamati "confini della suddivisione". Spanner aggiunge e rimuove automaticamente confini della suddivisione in base alle dimensioni e al carico, il che cambia il numero di suddivisioni in del database.
Suddivisione basata sul carico
Ecco un esempio di come Spanner esegue la suddivisione basata sul carico mitigazione degli hotspot di lettura, supponiamo che il database contenga una tabella con 10 righe vengono lette più spesso di tutte le altre righe della tabella. Spanner può aggiungere limiti di suddivisione tra ciascuna di queste 10 righe in modo che ciascuna venga gestita da un server diverso, anziché consentire a tutte le letture di queste righe di consumare le risorse di un singolo server.
Come regola generale, se segui le best practice per la progettazione dello schema, Spanner può mitigare gli hotspot in modo che la velocità effettiva di lettura dovrebbe migliorare a intervalli di pochi minuti fino a quando non saturare le risorse nel tuo o si verificano casi in cui non è possibile aggiungere nuovi confini della suddivisione (perché abbiamo una suddivisione che copre una sola riga senza elementi secondari con interleaving).
Schemi denominati
Gli schemi denominati consentono di organizzare insieme dati simili. In questo modo puoi trovare rapidamente gli oggetti nella console Google Cloud, applicare i privilegi ed evitare collisioni di nomi.
Gli schemi denominati, come altri oggetti del database, vengono gestiti utilizzando DDL.
Gli schemi denominati di Spanner ti consentono di utilizzare nomi completi
(FQN) per eseguire query sui dati. I nomi di dominio completi consentono di combinare il nome dello schema
per identificare gli oggetti del database. Ad esempio, puoi creare uno schema chiamato warehouse
per l'unità commerciale del magazzino. Le tabelle che utilizzano questo
lo schema potrebbe includere: product
, order
e customer information
. In alternativa, puoi creare uno schema denominato fulfillment
per l'unità commerciale di evasione degli ordini.
Questo schema può anche contenere tabelle chiamate product
, order
e customer
information
. Nel primo esempio, il nome di dominio completo è warehouse.product
e nel
secondo esempio è fulfillment.product
. In questo modo eviterai confusione
situazioni in cui più oggetti
hanno lo stesso nome.
Nel DDL CREATE SCHEMA
, agli oggetti della tabella viene assegnato sia un nome di dominio completo, ad esempio
sales.customers
e un nome breve, ad esempio sales
.
I seguenti oggetti database supportano gli schemi denominati:
TABLE
CREATE
INTERLEAVE IN [PARENT]
FOREIGN KEY
SYNONYM
VIEW
INDEX
FOREIGN KEY
SEQUENCE
Per ulteriori informazioni sull'utilizzo degli schemi denominati, consulta Gestire gli schemi denominati.
Utilizza un controllo dell'accesso granulare con schemi denominati
Gli schemi con nome ti consentono di concedere l'accesso a livello di schema a ogni oggetto dello schema. Questo vale per gli oggetti dello schema esistenti al momento in cui concedi l'accesso. Devi concedere l'accesso agli oggetti aggiunti in un secondo momento.
Il controllo dell'accesso granulare limita l'accesso a interi gruppi di oggetti di database, ad esempio tabelle, colonne e righe della tabella.
Per ulteriori informazioni, vedi Concedere i privilegi di controllo dell'accesso granulare agli schemi nominativi.
Esempi di schema
Gli esempi di schema in questa sezione mostrano come creare tabelle principali e secondarie con e senza interlacciamento e illustrano i layout fisici corrispondenti dei dati.
Crea una tabella padre
Supponiamo che tu stia creando un'applicazione musicale e che tu abbia bisogno di una tabella che memorizzi righe di dati sui cantanti:
Tieni presente che la tabella contiene una colonna della chiave primaria, SingerId
, che appare
a sinistra della riga in grassetto e che le tabelle sono organizzate in righe e
colonne.
Puoi definire la tabella con il seguente DDL:
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 );
Tieni presente quanto segue sullo schema di esempio:
Singers
è una tabella alla radice della gerarchia del database (in quanto non è definita come tabella secondaria con interfoliazione di un'altra tabella).- Per i database di dialetti GoogleSQL, in genere le colonne di chiave primaria sono annotate con
NOT NULL
Puoi omettere questa annotazione se vuoi consentire valoriNULL
in colonne chiave. Per ulteriori informazioni, consulta le sezioni Chiave colonne). - Le colonne non incluse nella chiave primaria sono chiamate colonne non chiave e possono avere un'annotazione facoltativa
NOT NULL
. - Le colonne che utilizzano il tipo
STRING
oBYTES
in GoogleSQL devono essere definito con una lunghezza, che rappresenta il numero massimo di di caratteri che possono essere memorizzati nel campo. La specifica della lunghezza è facoltativo per PostgreSQLvarchar
echaracter varying
di testo. Per ulteriori informazioni, consulta Tipi di dati Scalari per i database di dialetti GoogleSQL e i dati PostgreSQL tipi per database di dialetti PostgreSQL.
Qual è il layout fisico delle righe nella tabella Singers
? La
il seguente diagramma mostra le righe della tabella Singers
archiviate dalla chiave primaria
("Singers(1)", e poi "Singers(2)", dove il numero tra parentesi è
il valore della chiave primaria.
Il diagramma precedente mostra un esempio di confine di suddivisione tra le righe con chiave Singers(3)
e Singers(4)
, con i dati delle suddivisioni risultanti assegnati a server diversi. Man mano che questa tabella cresce, è possibile che le righe di dati Singers
vengano archiviate in posizioni diverse.
Creare tabelle principali e secondarie
Supponiamo di voler aggiungere alcuni dati di base sugli album di ogni cantante a l'applicazione musicale.
Tieni presente che la chiave primaria di Albums
è composta da due colonne: SingerId
e
AlbumId
, per associare ogni album al relativo cantante. Lo schema di esempio riportato di seguito
definisce le tabelle Albums
e Singers
nella radice della gerarchia del database, il che le rende tabelle sorelle.
-- 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) );
Il layout fisico delle righe Singers
e Albums
ha l'aspetto del
diagramma seguente, con le righe della tabella Albums
archiviate da istanze primarie contigue
quindi le righe di Singers
archiviate da una chiave primaria contigua:
Una nota importante sullo schema è che Spanner presuppone che non
relazioni di località dei dati tra le tabelle Singers
e Albums
, perché
si tratta di tabelle di primo livello. Man mano che il database cresce, Spanner può aggiungere confini di suddivisione tra le righe. Ciò significa che le righe della tabella Albums
potrebbero finire in una suddivisione diversa rispetto alle righe della tabella Singers
,
e le due suddivisioni potrebbero spostarsi indipendentemente l'una dall'altra.
A seconda delle esigenze della tua applicazione, potrebbe essere opportuno consentire i dati Albums
in segmenti diversi dei dati Singers
. Tuttavia, ciò potrebbe comportare un calo delle prestazioni a causa della necessità di coordinare letture e aggiornamenti tra risorse distinte. Se la tua applicazione deve recuperare spesso informazioni
su tutti gli album di un particolare cantante, devi creare Albums
come
una tabella secondaria con interleaving di Singers
, che distribuisce le righe dalle due
nelle tabelle di ricerca
lungo la dimensione di chiave primaria. L'esempio seguente lo spiega in maggiore dettaglio.
Creare tabelle con interleaving
Una tabella con interfoliazione è una tabella che dichiari come figlia con interfoliazione di un'altra tabella perché vuoi che le righe della tabella figlio vengano memorizzate fisicamente con la riga principale associata. Come accennato in precedenza, la chiave primaria della tabella padre deve essere la prima parte della chiave primaria composita della tabella figlio.
Durante la progettazione dell'applicazione musicale, supponi di capire che l'app deve accedere spesso alle righe della tabella Albums
quando accede a una riga Singers
. Ad esempio, quando accedi alla riga Singers(1)
, devi anche accedere alle righe Albums(1, 1)
e Albums(1, 2)
. In questo caso, Singers
e Albums
devono avere una relazione forte con la località dei dati. Puoi dichiarare
questa relazione con le località di dati creando Albums
come figlio con interleaving
tabella di Singers
.
-- Schema hierarchy: -- + Singers -- + Albums (interleaved table, child table of Singers)
La riga in grassetto nello schema seguente mostra come creare Albums
come
tabella con interleaving di 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;
Note su questo schema:
SingerId
, che è la prima parte della chiave primaria della tabella figlioAlbums
, è anche la chiave primaria della tabella padreSingers
.- La
ON DELETE CASCADE
l'annotazione indica che quando viene eliminata una riga della tabella padre, vengono eliminate automaticamente anche le righe secondarie. Se una tabella secondaria non ha questa annotazione o se l'annotazione èON DELETE NO ACTION
, devi eliminare le righe secondarie prima di poter eliminare la riga principale. - Le righe interlacciate vengono ordinate prima in base alle righe della tabella principale, poi in base alle righe contigue della tabella figlio che condividono la chiave primaria della tabella principale. Ad esempio, "Cantanti(1)", "Album(1, 1)" e "Album(1, 2)".
- La relazione di località dei dati di ogni cantante e dei relativi album viene conservata se questo database viene suddiviso, a condizione che le dimensioni di una riga
Singers
e di tutte le sue righeAlbums
rimangano al di sotto del limite di dimensione della suddivisione e che non esistano hotspot in nessuna di queste righeAlbums
. - La riga principale deve esistere prima di poter inserire le righe secondarie. La riga padre possono già esistere nel database o possono essere inseriti prima del delle righe figlio nella stessa transazione.
Crea una gerarchia di tabelle con interfoliazione
La relazione padre-figlio tra Singers
e Albums
può essere estesa a più tabelle discendenti. Ad esempio, potresti creare una tabella con interleaving
denominato Songs
come elemento secondario di Albums
per memorizzare l'elenco delle tracce di ogni album:
Songs
deve avere una chiave primaria che includa tutte le chiavi primarie delle tabelle situate a un livello superiore nella gerarchia, ovvero SingerId
e 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;
Il seguente diagramma rappresenta una vista fisica delle righe con interleaving.
In questo esempio, man mano che il numero di cantanti aumenta, Spanner aggiunge la suddivisione confini tra cantanti per preservare la località di dati tra un cantante e i suoi i dati di album e brani. Tuttavia, se le dimensioni di una riga del cantante e delle relative righe figlio superano il limite di dimensioni della suddivisione o se viene rilevato un hotspot nelle righe figlio, Spanner tenta di aggiungere confini di suddivisione per isolare la riga dell'hotspot insieme a tutte le righe figlio sottostanti.
In sintesi, una tabella principale, insieme a tutte le relative tabelle figlio e discendenti, forma una gerarchia di tabelle nello schema. Sebbene ogni tabella della gerarchia sia indipendente dal punto di vista logico, interleavingle fisicamente in questo modo può migliorare le prestazioni, pre-unire efficacemente le tabelle e consentire di accedere contemporaneamente alle righe correlate riducendo al minimo gli accessi allo spazio di archiviazione.
Join con tabelle con interleaving
Se possibile, unisci i dati in tabelle con interleaving in base alla chiave primaria. Poiché ogni
di solito la riga con interleaving viene archiviata fisicamente nella stessa suddivisione della riga padre
Spanner può eseguire i join mediante chiave primaria localmente, riducendo al minimo
accesso allo spazio di archiviazione e traffico di rete. Nell'esempio seguente, Singers
e
Albums
sono uniti nella chiave primaria SingerId
.
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;
Colonne chiave
Questa sezione include alcune note sulle colonne principali.
Modificare le chiavi delle tabelle
Le chiavi di una tabella non possono essere modificate. Non puoi aggiungere una colonna della chiave a una tabella esistente o rimuoverla da una tabella esistente.
Memorizzare valori NULL in una chiave primaria
In GoogleSQL, se vuoi memorizzare NULL in una colonna della chiave primaria,
ometti la clausola NOT NULL
per quella colonna nello schema. I database in dialetto PostgreSQL non supportano i valori NULL in una colonna della chiave primaria.
Ecco un esempio di omissione della clausola NOT NULL
nella colonna di chiave primaria
SingerId
. Tieni presente che, poiché SingerId
è la chiave primaria, non possono essere
una riga che archivia NULL
in quella colonna.
CREATE TABLE Singers ( SingerId INT64, FirstName STRING(1024), LastName STRING(1024), ) PRIMARY KEY (SingerId);
La proprietà nullable della colonna della chiave primaria deve corrispondere tra le dichiarazioni della tabella padre e della tabella figlio. In questo esempio, NOT NULL
per la colonna
Albums.SingerId
non è consentito perché Singers.SingerId
lo omette.
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;
Tipi non consentiti
Le seguenti colonne non possono essere di tipo ARRAY
:
- Le colonne chiave di una tabella.
- Le colonne chiave di un indice.
Progettazione per l'architettura multi-tenancy
Ti consigliamo di implementare il multitenancy se archivi dati appartenenti a diversi clienti. Ad esempio, un servizio di musica potrebbe voler archiviare separatamente i contenuti di ogni singola casa discografica.
Multitenancy classico
Il modo classico di progettare un'architettura multi-tenancy è creare un database separato
per ciascun cliente. In questo esempio, ogni database ha la propria tabella Singers
:
SingerId | Nome | Cognome |
---|---|---|
1 | Marc | Riccardo |
2 | Catalina | Smith |
SingerId | Nome | Cognome |
---|---|---|
1 | Alice | Trentor |
2 | Gabriele | Wright |
SingerId | Nome | Cognome |
---|---|---|
1 | Federico | Martinez |
2 | Anna | Harris |
Multitenancy gestito dallo schema
Un altro modo per progettare in funzione della multitenancy in Spanner è avere tutti i clienti in un'unica tabella in un unico database e utilizzare un valore della chiave primaria diverso per ogni cliente. Ad esempio, potresti includere una chiave CustomerId
nelle tabelle. Se imposti CustomerId
come prima colonna della chiave, i
dati per ogni cliente hanno una buona localizzazione. Spanner può quindi utilizzare in modo efficace le suddivisioni del database per massimizzare le prestazioni in base alle dimensioni dei dati e ai pattern di caricamento. Nell'esempio seguente,
è disponibile un'unica tabella Singers
per tutti i clienti:
CustomerId | SingerId | Nome | Cognome |
---|---|---|---|
1 | 1 | Marc | Riccardo |
1 | 2 | Catalina | Smith |
2 | 1 | Alice | Trentor |
2 | 2 | Gabriele | Wright |
3 | 1 | Federico | Martinez |
3 | 2 | Anna | Harris |
Se devi avere database separati per ogni tenant, tieni presente i seguenti vincoli:
- Esistono limiti al numero di database per istanza e il numero di tabelle e indici per database. In base al numero di potrebbe non essere possibile avere database o tabelle separati.
- L'aggiunta di nuove tabelle e indici senza interleaving può richiedere molto tempo volta. Potresti non essere in grado di ottenere il rendimento desiderato se la progettazione dello schema dipende dall'aggiunta di nuove tabelle e nuovi indici.
Se vuoi creare database separati, potresti ottenere risultati migliori se suddividi le tabelle nei database in modo che ogni database abbia un numero ridotto di modifiche dello schema a settimana.
Se crei tabelle e indici separati per ogni cliente della tua applicazione, non inserire tutte le tabelle e gli indici nello stesso database. Suddividi invece su molti database, per mitigare le prestazioni problemi con la creazione di un numero elevato di indici.
Per scoprire di più su altri pattern di gestione dei dati e sulla progettazione di applicazioni per multi-tenancy, consulta Implementazione della multitenancy in Chiave inglese