Há um recurso que eu gostaria que existisse no RDBMS, que é o suporte interno para definir um valor de tempo de vida para os registros de dados. Nos bancos de dados NoSQL, o suporte de TTL é muito comum. Os bancos de dados NoSQL foram projetados para lidar com determinados tipos de dados que geralmente não são encontrados nos casos de uso tradicionais de RDBMS. Isso inclui o gerenciamento de logs e eventos, em que, não apenas devido à natureza não estruturada dos dados, mas também ao seu grande volume, o gerenciamento em RDBMS pode ser difícil e caro. É esse tipo de dados que faz com que o Time-to-Live (TTL), um recurso popular nos bancos de dados NoSQL.
Mas uma rápida pesquisa no Google sobre TTL com RDBMS tradicional retorna mais de 1 milhão de resultados, o que indica que há vários casos de uso em que os desenvolvedores gostariam de ter esse tipo de suporte em RDBMS. Estes são alguns dos casos de uso que eu vi:
- Aplicativos que geram um grande volume de dados temporários para fins de cálculo. Por exemplo, um sistema de remuneração de incentivo que permite ao administrador do plano projetar e executar análises hipotéticas para verificar a eficácia do plano. Então, quando os planos forem implementados, os dados temporários para cálculos também precisarão ser mantidos para fins de validação/consulta do usuário.
- Os sistemas de informações gerenciais geralmente precisam pré-gerar dados agregados de fontes multigeográficas, o que geralmente envolve regras complexas de conversão de moeda. O requisito para esses dados agregados geralmente é necessário apenas para o período de relatório contábil atual.
- Sistemas que incluem um processo de arquivamento automático para remover dados antigos depois que os dados forem movidos para uma mídia de armazenamento diferente.
Todos os casos de uso mencionados acima também incluiriam as etapas adicionais da exclusão real dos dados. Mas, em muitos casos, o sistema desejaria desacoplar o processo para evitar o processo potencialmente demorado de exclusão de dados em um RDBMS baseado em transações.
Aqui, o recurso Time-to-Live (TTL) permitiria que o aplicativo simplesmente definisse os registros de dados com o tempo de expiração e adiasse o DELETE real para um processo de banco de dados diferente.
Para o Couchbase, o suporte ao TTL sempre esteve disponível com Operações de valor-chave do Couchbase. Mas de Couchbase 6.5.1Agora, esse recurso está disponível com DMLs N1QL, o que permite que os usuários consultem e definam o valor de expiração diretamente nas instruções N1QL.
N1QL TTL com OPTIONS
Para dar suporte ao TTL, a sintaxe do N1QL foi ampliada com um parâmetro opcional OPTIONS.
|
1 2 |
INSERT INTO default (KEY, VALUE [, OPTIONS]) VALUES (kval, docval [, {"expiration":eval}]); |
Observe que o parâmetro OPTIONS é opcional para garantir a compatibilidade com versões anteriores.
INSERT/UPSERT e defina o documento para expirar em 10 minutos.
|
1 2 |
INSERT INTO default (KEY, VALUE) VALUES ("k01", {"id":"k01"}, {"expiration":10*60}); UPSERT INTO default (KEY, VALUE) VALUES ("k01", {"id":"k01"}, {"expiration":10*60}); |
INSERT/UPSERT em SELECT e defina o tempo de expiração do documento como 1 hora
|
1 2 3 4 |
INSERT INTO default (KEY key, VALUE doc, OPTIONS {"expiration": 60*60}) SELECT META(t).id AS key, t AS doc FROM `travel-sample` AS t; UPSERT INTO default (KEY key, VALUE doc, OPTIONS {"expiration": 60*60}) SELECT META(t).id AS key, t AS doc FROM `travel-sample` AS t; |
Para preservar o TTL durante a atualização/upsert
Antes do Couchbase 6.5.1, a instrução de atualização N1QL não preservará o valor existente no documento. Esse comportamento permanecerá inalterado e, se os usuários quiserem preservar o TTL, a instrução de atualização do N1QL deverá definir explicitamente a expiração com o mesmo valor.
|
1 |
UPDATE default AS d SET d.comment = "xyz" , META(d).expiration = META(d).expiration; |
INSERIR/UPSERT no SELECT e manter o tempo de expiração do documento
|
1 2 3 4 |
INSERT INTO default (KEY key, VALUE doc, OPTIONS {"expiration": exptime}) SELECT META(t).id AS key, t AS doc, META(t).expiration AS exptime FROM `travel-sample` AS t; UPSERT INTO default (KEY key, VALUE doc, OPTIONS {"expiration": exptime}) SELECT META(t).id AS key, t AS doc, META(t).expiration AS exptime FROM `travel-sample` AS t; |
MERGE documentos e preserva o tempo de expiração.
|
1 2 3 4 5 6 7 8 9 10 11 |
MERGE INTO `travel-sample` AS route USING `travel-sample` AS airport ON route.sourceairport = airport.faa WHEN MATCHED THEN UPDATE SET route.old_equipment = route.equipment, route.equipment = ""797"", route.updated = true, META(route).expiration = META(route).expiration WHERE airport.country = ""France"" AND route.airline = ""BA"" AND CONTAINS(route.equipment, ""319"");" |
Campo META().expiration
O campo META().expiration sempre esteve disponível com o N1QL. Mas com o N1QL TTL, os usuários podem alterar diretamente o valor do campo.
Para selecionar e usar a expiração em um predicado
|
1 |
SELECT META(d).id, META(d).expiration FROM default d WHERE META(d).expiration > 0; |
Para atualizar todos os documentos e definir o tempo de comentário e expiração para 10 minutos.
|
1 |
UPDATE default AS d SET d.comment = "xyz" , META(d).expiration = 10*60; |
Para limpar o tempo de expiração, para que o documento não seja excluído.
|
1 |
UPDATE default AS d SET META(d).expiration = 0; |
Para excluir todos os documentos que expirarão em mais de um dia
|
1 |
DELETE default d WHERE META(d).expiration > <span style="font-weight: 400">(NOW_MILLIS()/1000)+ (60*60*24);</span> |
Observe que o valor relativo é usado somente para INSERT/UPDATE/UPSERT. O valor de expiração absoluto deve ser usado em todos os outros casos.
Valor do tempo de expiração
O tempo de expiração que é inferior a 30 dias no futuro pode ser definido como o número de segundos. O valor de 60*60*24*14 marcará o documento para exclusão em 14 dias. Para 30 dias ou mais no futuro, deve ser usada a hora Unix. Para obter mais informações sobre o tempo de expiração do Couchbase, consulte a seção Documentação do Couchbase.
Criar um índice no campo de expiração
A capacidade de consultar e indexar o META().expiration sempre foi possível no Couchbase.
|
1 2 3 |
CREATE INDEX idx_expir ON `travel-sample` ( META().expiration ); SELECT META().id, META().expiration FROM `travel-sample` WHERE META().expiration = 0 ORDER BY META().id LIMIT 2; |
Observe que pode haver um atraso entre o momento em que o documento é excluído e quando a exclusão se propaga para o serviço de índice. Por esse motivo, as consultas que são totalmente cobertas pelo índice com a expiração podem retornar dados obsoletos. Mas esse comportamento é apenas temporário.
Consideração de desempenho
N1QL acessa as informações de TTL usando o API SUBDOC Essa API retornará o documento completo e também tem alguma sobrecarga no tamanho do pacote de solicitação. A sobrecarga adicional pode incorrer em latência de consulta adicional. No entanto, a API SUBDOC só será usada se o campo META().expiration for referenciado na consulta.
Recursos adicionais
- Suporte do Couchbase para TTL: https://docs.couchbase.com/server/current/learn/buckets-memory-and-storage/expiration.html
- Como definir o tempo de expiração: https://docs.couchbase.com/server/current/learn/buckets-memory-and-storage/expiration.html
- API SUBDOC do Couchbase: https://docs.couchbase.com/server/5.0/developer-guide/sub-doc-api.html
- Indexação do campo Expiração: https://docs.couchbase.com/server/current/n1ql/n1ql-language-reference/indexing-meta-info.html