Progettazione di una tabella in Oracle NoSQL Database Cloud Service

Scopri come progettare e configurare le tabelle in Oracle NoSQL Database Cloud Service.

Questo articolo contiene i seguenti argomenti:

Campi della tabella

Scopri come progettare e configurare i dati utilizzando i campi tabella.

Un'applicazione può scegliere di utilizzare tabelle senza schema, in cui una riga è costituita da campi chiave e un singolo campo dati JSON. Una tabella senza schema offre flessibilità in ciò che può essere memorizzato in una riga.

In alternativa, l'applicazione può scegliere di utilizzare tabelle a schema fisso, in cui tutti i campi della tabella sono definiti come tipi specifici.

Le tabelle di schema fisso con dati digitati sono più sicure da usare dal punto di vista dell'applicazione e dell'efficienza dello storage. Anche se è possibile modificare lo schema delle tabelle di schema fisso, non è possibile modificarne facilmente la struttura. Una tabella senza schema è flessibile e la struttura della tabella può essere facilmente modificata.

Infine, un'applicazione può anche utilizzare un approccio al modello dati ibrido in cui una tabella può avere tipizzato dati e campi dati JSON.

Gli esempi riportati di seguito illustrano come progettare e configurare i dati per tutti e tre gli approcci.

Esempio 1: progettazione di una tabella senza schema

Sono disponibili più opzioni per memorizzare informazioni sui pattern di navigazione nella tabella. Un'opzione consiste nel definire una tabella che utilizza un ID cookie come chiave e conserva i dati di segmentazione del pubblico come un singolo campo JSON.

// schema less, data is stored in a JSON field
CREATE TABLE audience_info (
       cookie_id LONG,
       audience_data JSON,
       PRIMARY KEY(cookie_id))

In questo caso, la tabella audience_info può contenere un oggetto JSON, ad esempio:

{
  "cookie_id": "",
  "audience_data": {
    "ipaddr" : "10.0.00.xxx",
    "audience_segment: {
       "sports_lover" : "2018-11-30",
       "book_reader" :  "2018-12-01"
    }
  }
}

L'applicazione avrà un campo chiave e un campo dati per questa tabella. Hai la flessibilità di ciò che hai scelto di memorizzare come informazioni nel tuo campo audience_data. Pertanto, è possibile modificare facilmente i tipi di informazioni disponibili.

Esempio 2: progettazione di una tabella schema fisso

È possibile memorizzare informazioni sui pattern di navigazione creando la tabella con campi dichiarati in modo più esplicito:

// fixed schema, data is stored in typed fields.
CREATE TABLE audience_info(
       cookie_id LONG,
       ipaddr STRING,
       audience_segment RECORD(sports_lover TIMESTAMP(9),
                               book_reader TIMESTAMP(9)),
       PRIMARY KEY(cookie_id))

In questo esempio, la tabella contiene un campo chiave e due campi dati. I dati sono più compatti e puoi assicurarti che tutti i campi dati siano accurati.

Esempio 3: progettazione di una tabella ibrida

È possibile memorizzare informazioni sui pattern di navigazione utilizzando i campi dati digitati e JSON nella tabella.

// mixed, data is stored in both typed and JSON fields.
CREATE TABLE audience_info (
       cookie_id LONG,
       ipaddr STRING,
       audience_segment JSON,
       PRIMARY KEY(cookie_id))

Chiavi principali e chiavi di partizione

Durante la progettazione dell'applicazione, apprendere lo scopo delle chiavi primarie e delle chiavi di partizione.

Le chiavi primarie e le chiavi di partizione sono elementi importanti nello schema e consentono di accedere e distribuire i dati in modo efficiente. Le chiavi primarie e le chiavi di partizione vengono create solo quando si crea una tabella. Rimangono in vigore per la vita del tavolo e non possono essere cambiati o eliminati.

Chiavi primarie

Quando si crea la tabella, è necessario designare una o più colonne chiave primaria. Una chiave primaria identifica in modo univoco ogni riga della tabella. Per operazioni CRUD semplici, Oracle NoSQL Database Cloud Service utilizza la chiave primaria per recuperare una riga specifica da leggere o modificare. Considerare ad esempio che una tabella contiene i campi seguenti:

  • productName

  • productType

  • productLine

L'esperienza dimostra che il nome del prodotto è importante e univoco per ogni riga, pertanto si imposta productName come chiave primaria. Quindi, si recuperano le righe di interesse in base al productName. In questo caso, utilizzare un'istruzione come questa per definire la tabella.

/* Create a new table called users. */
CREATE TABLE if not exists myProducts 
(
  productName STRING,
  productType STRING,
  productLine INTEGER,
  PRIMARY KEY (productName)
)"

Chiavi partizione

Lo scopo principale delle chiavi di partizionamento orizzontale è distribuire i dati nel cluster Oracle NoSQL Database Cloud Service per aumentare l'efficienza e posizionare i record che condividono la chiave di partizionamento in locale in modo da facilitarne il riferimento e l'accesso. I record che condividono la chiave partizione vengono memorizzati nella stessa posizione fisica ed è possibile accedervi in modo atomico ed efficiente.

La progettazione delle chiavi Primary e shard ha implicazioni sul ridimensionamento e sul raggiungimento del throughput di cui è stato eseguito il provisioning. Ad esempio, quando i record condividono le chiavi di partizione, è possibile eliminare più righe di tabella in un'operazione atomica o recuperare un subset di righe nella tabella in una singola operazione atomica. Oltre a consentire la scalabilità, chiavi di partizione ben progettate possono migliorare le prestazioni richiedendo meno cicli per inserire o ottenere dati da una singola partizione.

Si supponga, ad esempio, di designare tre campi chiave primaria:

PRIMARY KEY (productName, productType, productLine)

Poiché l'applicazione esegue spesso query utilizzando le colonne productName e productType, è opportuno specificare tali campi come chiavi di partizione. La designazione della chiave di partizione garantisce che tutte le righe per queste due colonne siano memorizzate nella stessa partizione. Se questi due campi non sono chiavi di partizione, le colonne con query più frequente potrebbero essere memorizzate su qualsiasi partizione. Quindi, l'individuazione di tutte le righe per entrambi i campi richiede la scansione di tutta la memorizzazione dei dati, anziché di una partizione.

Le chiavi di partizione designano lo storage sulla stessa partizione per facilitare query efficienti per i valori delle chiavi. Tuttavia, poiché si desidera distribuire i dati tra le partizioni per ottenere prestazioni ottimali, è necessario evitare le chiavi delle partizioni con pochi valori univoci.

Nota

Se non si designano chiavi di partizione durante la creazione di una tabella, Oracle NoSQL Database Cloud Service utilizza le chiavi primarie per l'organizzazione delle partizioni.

Fattori importanti da considerare quando si sceglie una chiave di partizione

  • Cardinalità: i campi cardinalità bassa, ad esempio il paese di origine di un utente, raggruppano i record in alcune partizioni. A loro volta, tali partizioni richiedono un frequente ribilanciamento dei dati, aumentando la probabilità di problemi di hot shard. Ogni chiave di partizione dovrebbe invece avere una cardinalità elevata, in cui la chiave di partizione può esprimere una porzione pari di record nel data set. Ad esempio, i numeri di identità come customerID, userID o productID sono validi candidati per una chiave di partizione.

  • Atomicità: solo gli oggetti che condividono la chiave partizione possono partecipare a una transazione. Se sono necessarie transazioni ACID che si estendono su più record, scegliere una chiave partizione che consenta di soddisfare tale requisito.

Quali sono le best practice da seguire?

  • Distribuzione uniforme delle chiavi di partizione: quando le chiavi di partizione vengono distribuite in modo uniforme, nessuna singola partizione limita la capacità del sistema.

  • Isolamento delle query: le query devono essere indirizzate a una partizione specifica per ottimizzare l'efficienza e le prestazioni. Se le query non sono isolate in una singola partizione, la query viene applicata a tutte le partizioni che risultano meno efficienti e aumentano la latenza delle query.

Vedere Creazione di tabelle per informazioni sull'assegnazione delle chiavi primarie e delle partizioni mediante l'oggetto TableRequest.

Tempo TTL

Scopri come specificare i tempi di scadenza per tabelle e righe utilizzando la funzione TTL (Time-to-Live).

Molte applicazioni gestiscono dati che hanno una durata utile limitata. Time-to-Live (TTL) è un meccanismo che consente di impostare un intervallo di tempo sulle righe della tabella, dopo il quale le righe scadono automaticamente e non sono più disponibili. È il periodo di tempo durante il quale i dati possono rimanere in Oracle NoSQL Database Cloud Service. I dati che raggiungono la scadenza non possono più essere recuperati e non vengono visualizzati in alcuna statistica di archiviazione.

Per impostazione predefinita, ogni tabella creata ha un valore TTL pari a zero, che indica l'assenza di scadenza. Quando si crea una tabella, è possibile dichiarare un valore TTL specificando il TTL con un numero, seguito da HOURS o DAYS. Le righe di tabella ereditano il valore TTL della tabella in cui risiedono, a meno che non si imposti esplicitamente un valore TTL per le righe di tabella. L'impostazione del valore TTL di una riga sostituisce il valore TTL della tabella. Se si modifica il valore TTL della tabella dopo che la riga ha un valore TTL, il valore TTL della riga persiste.

È possibile aggiornare il valore TTL per una riga di tabella in qualsiasi momento prima che la riga raggiunga l'ora di scadenza. Non è più possibile accedere ai dati scaduti. Pertanto, l'utilizzo dei valori TTL è più efficiente rispetto all'eliminazione manuale delle righe, poiché viene evitato il sovraccarico derivante dalla scrittura di una voce di log del database per l'eliminazione dei dati. I dati scaduti vengono rimossi dal disco dopo la data di scadenza.

Stati tabella e cicli di vita

Scopri i diversi stati della tabella e il loro significato (processo del ciclo di vita della tabella).

Ogni tabella passa attraverso una serie di stati diversi, dalla creazione della tabella all'eliminazione (drop). Ad esempio, una tabella con stato DROPPING non può passare allo stato ACTIVE, mentre una tabella con stato ACTIVE può passare allo stato UPDATING. È possibile tenere traccia dei diversi stati delle tabelle monitorando il ciclo di vita delle tabelle. In questa sezione vengono descritti i vari stati della tabella.

Descrizione della tabella state.png:
Descrizione della tabella di figura: state.png

Stato tabella: Descrizione

CREATING

La tabella è in fase di creazione. Non è pronto per l'utilizzo.

UPDATING

L'aggiornamento della tabella è in corso. Non è possibile apportare ulteriori modifiche alla tabella con questo stato.

Una tabella si trova nello stato UPDATING quando:

  • I limiti della tabella vengono modificati
  • Lo schema della tabella si sta evolvendo
  • Aggiunta o eliminazione di un indice di tabella

ACTIVE

La tabella può essere utilizzata nello stato corrente. È possibile che la tabella sia stata creata o modificata di recente, ma lo stato della tabella è ora stabile.

DROPPING

La tabella è in fase di eliminazione e non è possibile accedervi per alcuno scopo.

DROPPED

La tabella è stata eliminata e non esiste più per le attività di lettura, scrittura o query.

Nota

Una volta eliminata, è possibile creare di nuovo una tabella con lo stesso nome.

Gerarchie di tabelle

Oracle NoSQL Database consente alle tabelle di esistere in una relazione padre-figlio. Questa operazione è nota come gerarchie di tabelle.

L'istruzione Crea tabella consente di creare una tabella come figlio di un'altra tabella, che diventa quindi padre della nuova tabella. Questa operazione viene eseguita utilizzando un nome composto (name_path) per la tabella figlio. Un nome composto è costituito da un numero N (N > 1) di identificatori separati da punti. L'ultimo identificativo è il nome locale della tabella figlio e i primi identificativi N-1 puntano al nome del padre.

Caratteristiche delle tabelle padre-figlio:
  • Una tabella figlio eredita le colonne chiave primaria della relativa tabella padre.
  • Tutte le tabelle nella gerarchia hanno le stesse colonne chiave partizione, specificate nell'istruzione Crea tabella della tabella radice.
  • Impossibile eliminare una tabella padre prima di eliminare i relativi figli.
  • Un vincolo di integrità referenziale non viene applicato in una tabella padre-figlio.

È consigliabile utilizzare le tabelle figlio quando è richiesta una qualche forma di normalizzazione dei dati. Le tabelle figlio possono anche essere una buona scelta quando si modellano relazioni da 1 a N e forniscono anche la semantica delle transazioni ACID quando si scrivono più record in una gerarchia padre-figlio.