Projetando uma Tabela no Oracle NoSQL Database Cloud Service

Saiba como projetar e configurar tabelas no Oracle NoSQL Database Cloud Service.

Este artigo tem os seguintes tópicos:

Campos de 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 principais 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ê cria chaves primárias e de partição somente quando cria uma tabela. Eles permanecem em vigor durante o tempo de vida da tabela e não podem ser alterados ou eliminados.

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 experiência, você sabe que o nome do produto é importante, bem como exclusivo, para cada linha. Portanto, defina productName como a chave primária. Então, 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 Shard

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 Partição tem implicações no escalonamento e na obtenção do rendimento 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. 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. Então, a localização de todas as linhas de ambos os campos requer a verificação de todo o armazenamento de dados, em vez de um shard.

As chaves de partição designam armazenamento no mesmo shard para facilitar consultas eficientes de valores de chave. No entanto, como você deseja que seus dados sejam distribuídos entre os shards para melhor desempenho, é necessário evitar chaves de partição que tenham poucos valores exclusivos.

Observação:

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 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, eles 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 ou productID 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 ACID que abrangem vários registros, escolha uma chave de partição que permita atender a essa necessidade.

Qual é a melhor prática a ser seguida?

  • 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 para saber como designar chaves primárias e de partição usando o objeto TableRequest.

Tempo de Vida

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 vencem 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. O 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 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 da tabela e ciclos de vida

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, e uma tabela no estado ACTIVE pode mudar 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.

A seguir, descrição da tabela-state.png
Descrição da tabela de ilustração-state.png

Estado da Tabela Descrição

CREATING

A tabela está em processo de criação. Não está pronta para ser usada.

UPDATING

A atualização da tabela está em andamento. Não é possível alterar mais a tabela nesse estado.

Uma tabela está no estado UPDATING quando:

  • Os limites da tabela estão sendo alterados
  • O esquema da tabela está evoluindo
  • Adicionando ou eliminando um índice de tabela

ACTIVE

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.

DROPPING

A tabela está sendo eliminada e não pode ser acessada para nenhuma finalidade.

DROPPED

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.

Hierarquias da Tabela

O Oracle NoSQL Database permite que tabelas existam em um relacionamento pai-filho. Isso é conhecido como hierarquias de tabelas.

A instrução create table permite que uma tabela seja criada como filha de outra tabela, que depois se torna mãe da nova tabela. Isso é feito usando um nome composto (name_path) para a tabela filho. Um nome composto consiste em um número N (N > 1) de identificadores separados por pontos. O último identificador é o nome local da tabela filho e os primeiros identificadores N-1 apontam para o nome do pai.

Características das tabelas pai-filho:
  • Uma tabela filho herda as colunas de chave primária de sua tabela pai.
  • Todas as tabelas na hierarquia têm as mesmas colunas de chave de partição, que são especificadas na instrução create table da tabela raiz.
  • Uma tabela pai não pode ser eliminada antes de seus filhos serem eliminados.
  • Uma constraint de integridade referencial não é imposta em uma tabela pai-filho.

Considere o uso de tabelas filho quando for necessária alguma forma de normalização de dados. As tabelas filho também podem ser uma boa escolha ao modelar relacionamentos de 1 a N e também fornecer semântica de transação ACID ao gravar vários registros em uma hierarquia pai-filho.