Design da Tabela
Saiba como projetar e configurar tabelas no Oracle NoSQL Database Cloud Service.
Tabela
Uma tabela é um conjunto de linhas, no qual cada linha mantém um registro de dados. Cada linha consiste em campos-chave e em campos de dados definidos quando uma tabela é criada. Além disso, uma tabela tem um armazenamento especificado, pode suportar um throughput máximo de leitura e gravação definido e tem um tamanho máximo.
Conheça os seguintes conceitos antes de projetar uma tabela no Oracle NoSQL Database Cloud Service:
-
Campos da Tabela: As tabelas são criadas com o uso de instruções DDL (Data Definition Language) que definem os tipos de dados e as chaves primárias usadas para a tabela. O Oracle NoSQL Database Cloud Service suporta diferentes tipos de dados, incluindo vários tipos numéricos, strings, binários, timestamps, mapas, arrays, registros e um tipo JSON especial, que pode conter dados JSON válidos. Um aplicativo pode escolher tipos de dados para os campos da tabela com base no modelo de dados. Consulte Tipos de Dados Suportados para obter uma lista completa de tipos de dados suportados no Oracle NoSQL Database Cloud Service.
Consulte Campos da Tabela para saber mais sobre campos da tabela.
-
Chaves Primárias e de Partição: Cada tabela deve ter um ou mais campos designados como a chave primária. Essa designação ocorre no momento da criação da tabela e não pode ser alterada após a criação da tabela. Uma chave primária identifica exclusivamente cada linha da tabela. No caso mais simples, uma chave primária é usada para recuperar uma linha específica a ser examinada ou modificada.
As chaves de partição identificam quais campos de chave primária são significativos em termos de armazenamento de shard. Ou seja, as linhas que contêm os mesmos valores para todas as chaves de partição são garantidas para serem armazenadas na mesma partição. Esse armazenamento de shards é importante para algumas operações que garantem a atomicidade dos resultados.
Consulte Chaves Primárias e Chaves de Partição para saber mais.
-
Índices: Índices representam uma maneira alternativa de recuperar linhas da tabela. Normalmente, você recupera as linhas da tabela usando a chave primária. Ao criar um índice, você pode recuperar linhas com eficiência com base em campos que não fazem parte da chave primária. Os índices fornecem mais capacidade de consulta, mas consomem recursos de armazenamento e de throughput.
Consulte Criando Tabelas e Índices para saber como criar um índice.
-
Capacidade: Ao criar uma tabela, você também especifica os recursos de throughput e armazenamento disponíveis para a tabela. As operações de leitura e gravação na tabela são limitadas pela capacidade de throughput de leitura e gravação que você define. A quantidade de espaço que a tabela pode usar é limitada pela capacidade de armazenamento.
Consulte Estimando a Capacidade para obter informações sobre como estimar a capacidade que você deve especificar para a sua tabela.
Consulte Tratando a Capacidade para saber como lidar com a capacidade da sua tabela.
-
Tempo de Vida (TTL): O tempo de vida permite que você expire automaticamente as linhas da tabela. O TTL é expresso como o tempo que os dados têm permissão para permanecer na tabela. Os dados que atingirem o valor de timeout de expiração não poderão mais ser recuperados e não aparecerão em operações de leitura.
Consulte Tempo de Vida para saber mais.
- Colunas de Identidade: As colunas de identidade são um tipo especial de colunas que obtêm seus valores automaticamente designados pelo Oracle NoSQL Database Cloud Service. Esses valores são gerados por um gerador de sequência. Não há suporte para colunas de identidade na console do NoSQL Database Cloud Service. Para obter mais detalhes sobre colunas de identidade, consulte Coluna de Identidade na Referência SQL do Oracle NoSQL Database. Para saber como acessar colunas de identidade de um aplicativo Oracle NoSQL Database Cloud Service, consulte Inserindo Valores de IDENTIDADE Programaticamente em Conceitos Básicos do Driver Java da Tabela do Banco de Dados NoSQL.
-
Ciclos de Vida da Tabela: Quando as tabelas são criadas, modificadas ou excluídas, elas passam por diferentes estados de ciclo de vida.
Consulte Estados e Ciclos de Vida da Tabela para saber sobre o ciclo de vida de uma tabela.
Tipos de Dados Suportados
O Oracle NoSQL Database Cloud Service suporta muitos tipos de dados comuns.
Tipo de Dados | Descrição |
---|---|
|
Uma sequência de zero ou mais bytes. |
FIXED_BINARY |
Um array de bytes de tamanho fixo. |
|
Um tipo de dados com um dos dois valores possíveis: |
|
Um número de ponto flutuante longo de 64 bits (8 bytes). |
|
Um número de ponto flutuante longo de 32 bits (4 bytes) |
|
Um número inteiro longo de 64 bits ( 8 bytes). |
|
Um número inteiro longo de 32 bits (4 bytes). |
|
Uma sequência de caracteres Unicode. |
|
Um número decimal assinado com precisão arbitrária. |
|
Um ponto no tempo com uma precisão. A precisão afeta o tamanho e o uso do armazenamento. O timestamp é armazenado e gerenciado no fuso horário UTC (Coordinated Universal Time). |
|
Uma enumeração, representada como um array de strings. Os valores |
|
Uma coleção ordenada de zero de itens mais tipados. Os arrays não definidos como JSON não podem conter valores Os arrays declarados como JSON podem conter qualquer JSON válida, incluindo o valor especial, nulo, que é relevante para JSON. |
|
Uma coleção não ordenada de zero ou mais pares de chave/item, na qual todas as chaves são strings e todos os itens são do mesmo tipo. Todas as chaves devem ser exclusivas. Os pares chave/item são chamados de campos, as chaves são nomes de campos e os itens associados são valores de campos. Os valores de campos podem ter diferentes tipos, mas os mapas não podem conter valores de campos NULL. |
|
Uma coleção fixa de um ou mais pares de item/chave, em que todas as chaves são strings. Todas as chaves de um registro devem ser exclusivas. |
|
Qualquer dado JSON válido. |
Campos da Tabela
Saiba como criar e configurar dados usando campos da tabela.
Um aplicativo pode optar por usar tabelas sem esquema, em que uma linha consiste em campos-chave e um único campo de dados JSON. Uma tabela sem esquema oferece flexibilidade no que pode ser armazenado em uma linha.
Como alternativa, o aplicativo pode optar por usar tabelas de esquema fixo, em que todos os campos da tabela são definidos como tipos específicos.
As tabelas de esquema fixo com dados tipados são mais seguras para uso com base em um ponto de vista de aplicação de regras e de eficiência do armazenamento. Embora o esquema de tabelas de esquema fixo possa ser modificado, não é possível modificar a estrutura da tabela facilmente. Uma tabela sem esquema é flexível e a estrutura da tabela pode ser modificada facilmente.
Por fim, um aplicativo também pode usar uma abordagem de modelo de dados híbridos em que uma tabela pode ter campos de dados tipados e JSON.
Os exemplos a seguir demonstram como projetar e configurar dados para todas as três abordagens.
Exemplo 1: Criando uma Tabela Sem Esquema
Você tem várias opções para armazenar informações sobre padrões de navegação na tabela. Uma opção é definir uma tabela que usa um ID de cookie como uma chave e mantém os dados de segmentação do público-alvo como um único 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))
Nesse caso, a tabela audience_info
pode conter um objeto JSON como:
{
"cookie_id": "",
"audience_data": {
"ipaddr" : "10.0.00.xxx",
"audience_segment: {
"sports_lover" : "2018-11-30",
"book_reader" : "2018-12-01"
}
}
}
Seu aplicativo terá um campo-chave e um campo de dados para essa tabela. Você tem flexibilidade no que optou por armazenar informações no campo audience_data
. Portanto, você pode alterar facilmente os tipos de informações disponíveis.
Exemplo 2: Criando uma Tabela de Esquema Fixo
Você pode armazenar informações sobre padrões de navegação criando sua tabela com campos mais declarados explicitamente:
// 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));
Neste exemplo, sua tabela tem um campo-chave e dois campos de dados. Seus dados são mais compactos e você pode garantir que todos os campos de dados sejam precisos.
Exemplo 3: Criando uma Tabela Híbrida
Você pode armazenar informações sobre padrões de navegação usando campos de dados tipados e JSON em sua tabela.
// 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));
Chaves Primárias e Chaves de Partição
Conheça a finalidade das chaves primárias e das chaves de partição durante o projeto do seu aplicativo.
As chaves primárias e as chaves de partição são elementos importantes no seu esquema e ajudam você a acessar e distribuir dados de forma eficiente. Você só cria chaves primárias e de partição quando cria uma tabela. Elas permanecem em vigor durante o tempo de vida da tabela e não podem ser alteradas ou eliminadas.
Chaves Primárias
Você deve designar uma ou mais colunas de chave primária ao criar a tabela. Uma chave primária identifica exclusivamente cada linha da tabela. Para operações CRUD simples, o Oracle NoSQL Database Cloud Service usa a chave primária para recuperar uma linha específica para ler ou modificar. Por exemplo, considere que uma tabela tenha os seguintes campos:
-
productName
-
productType
-
productLine
Com base na sua experiência, você sabe que o nome do produto é importante, bem como exclusivo, para cada linha. Portanto, defina productName
como a chave primária. Portanto, você recupera linhas de interesse com base no productName
. Nesse caso, use uma instrução como essa para definir a tabela.
/* Create a new table called users. */
CREATE TABLE if not exists myProducts
(
productName STRING,
productType STRING,
productLine INTEGER,
PRIMARY KEY (productName)
)";
Chaves de Partição
A principal finalidade das chaves de partição é distribuir dados no cluster do Oracle NoSQL Database Cloud Service para aumentar a eficiência e posicionar os registros que compartilham a chave de partição localmente para fácil referência e acesso. Os registros que compartilham a chave de partição são armazenados no mesmo local físico e podem ser acessados de forma atômica e eficiente.
O seu design de chave Primária e de chave de Partição tem implicações no escalonamento e na obtenção do throughput provisionado. Por exemplo, quando os registros compartilham as chaves de partição, você pode excluir várias linhas de tabela em uma operação atômica ou recuperar um subconjunto de linhas de sua tabela em uma única operação atômica. Além de permitir a escalabilidade, as chaves de partição bem projetadas podem melhorar o desempenho, exigindo menos ciclos para inserir dados ou obter dados de um único shard.
Por exemplo, suponha que você designe três campos de chave primária:
PRIMARY KEY (productName, productType, productLine)
Como você sabe que frequentemente o aplicativo faz consultas usando as colunas productName
e productType
, a especificação desses campos como chaves de partição é apropriada. A designação de chave de partição garante que todas as linhas dessas duas colunas sejam armazenadas no mesmo shard. Se esses dois campos não forem chaves de partição, as colunas consultadas com mais frequência poderão ser armazenadas em qualquer shard. Logo, a localização de todas as linhas de ambos os campos requer a varredura de todo o armazenamento de dados, em vez de um shard.
Se você não designar chaves de partição ao criar uma tabela, o Oracle NoSQL Database Cloud Service utilizará as chaves primárias para a organização de shards.
Fatores importantes a serem considerados ao se escolher uma chave de partição
-
Cardinalidade: campos de baixa cardinalidade, como país de origem do usuário, agrupam registros em alguns shards. Por sua vez, esses shards exigem rebalanceamento frequente de dados, aumentando a probabilidade de problemas de hot shard. Em vez disso, cada chave de partição deve ter uma cardinalidade alta, em que a chave de partição pode expressar uma fatia uniforme de registros no conjunto de dados. Por exemplo, os números de identidade como
customerID
,userID
ouproductID
são bons candidatos para uma chave de partição. -
Atomicidade: Somente objetos que compartilham a chave de partição podem participar de uma transação. Se você precisar de transações de ACID que abrangem vários registros, escolha uma chave de partição que permita atender a essa necessidade.
Quais são as melhores práticas a serem seguidas?
-
Distribuição uniforme de chaves de partição: Quando as chaves de partição são distribuídas uniformemente, nenhum shard único limita a capacidade do sistema.
-
Isolamento de Consulta: As consultas devem ser direcionadas a um shard específico para maximizar a eficiência e o desempenho. Se as consultas não estiverem isoladas em um único shard, a consulta será aplicada a todos os shards, o que é menos eficiente e aumenta a latência da consulta.
Consulte Criando Tabelas e Índices para saber como designar chaves primárias e de partição usando o objeto TableRequest
.
TTL (Time to Live)
Saiba como especificar tempos de expiração para tabelas e linhas usando o recurso TTL (Tempo de Vida).
Muitos aplicativos tratam dados que têm um tempo de vida útil limitado. O Tempo de Vida (TTL) é um mecanismo que permite definir um período nas linhas da tabela, após o qual as linhas expiram automaticamente e não ficam mais disponíveis. É a quantidade de tempo que os dados podem permanecer no Oracle NoSQL Database Cloud Service. Os dados que atingem o tempo de expiração não podem mais ser recuperados e não aparecem em estatísticas de armazenamento.
Por padrão, cada tabela que você criar tem um valor de TTL zero, indicando que não há tempo de expiração. Você pode declarar um valor de TTL quando criar uma tabela, especificando o TTL com um número, seguido por HOURS
ou DAYS
. As linhas da tabela herdam o valor de TTL da tabela em que elas residem, a menos que você defina explicitamente um valor de TTL para linhas da tabela. Um valor de TTL definido para a linha substitui o valor de TTL da tabela. Se você alterar o valor de TTL da tabela após a linha ter um valor de TTL, o valor de TTL da linha persistirá.
Você pode atualizar o valor de TTL de uma linha da tabela a qualquer momento antes que a linha atinja o tempo de expiração. Os dados expirados não podem mais ser acessados. Portanto, o uso de valores de TTL é mais eficiente do que excluir linhas manualmente, porque o overhead de gravar uma entrada de log do banco de dados para a exclusão de dados é evitado. Os dados expirados são expurgados do disco após a data de expiração.
Estados e Ciclos de Vida da Tabela
Saiba mais sobre os diferentes estados de tabela e seu significado (processo de ciclo de vida de tabela).
Cada tabela passa por uma série de diferentes estados, desde a criação da tabela até a exclusão (eliminação). Por exemplo, uma tabela no estado DROPPING
não pode prosseguir para o estado ACTIVE
, ao passo que uma tabela no estado ACTIVE
pode passar para o estado UPDATING
. Você pode rastrear os diferentes estados da tabela monitorando o ciclo de vida da tabela. Esta seção descreve os diversos estados da tabela.
Estado da Tabela | Descrição |
---|---|
|
A tabela está em processo de criação. Não está pronta para ser usada. |
|
A atualização da tabela está em andamento. Não é possível fazer mais modificações na tabela nesse estado. Uma tabela permanece no estado
|
|
A tabela pode ser usada no estado atual. A tabela pode ter sido criada ou modificada recentemente, mas o estado da tabela agora é estável. |
|
A tabela está sendo eliminada e não pode ser acessada para nenhuma finalidade. |
|
A tabela foi eliminada e não existe mais para atividades de leitura, gravação ou consulta.
Observação
Uma vez eliminada, uma tabela com o mesmo nome poderá ser criada novamente. |