Alura > Cursos de Data Science > Cursos de NoSQL > Conteúdos de NoSQL > Primeiras aulas do curso Datomic: um banco cronológico

Datomic: um banco cronológico

Schema e transações - Introdução

Olá, pessoal, meu nome é Guilherme Silveira e serei o instrutor no curso de Introdução ao Datomic: Um banco cronológico

Nesse curso vamos estudar um banco de dados diferente chamado Datomic. O Datomic não armazena os dados da maneira tradicional que comumente aprendemos, os bancos de dados de entidade relacional que formam grandes tabelas com vários campos e várias linhas. Essas não são as únicas maneiras de fazer banco de dados. Existem diversas outras como chave-valor, documento, grafo, entre outras.

O Datomic tem uma abordagem diferente. Há dois grandes pontos que vamos ver a partir deste primeiro curso. Um delas é que tudo que se faz neste banco se acumula, ou seja, fica armazenado num histórico. Ele não vai apagar o passado, então quando apagarmos um produto do sistema, ele não apaga de verdade. Essas informações ficam escondidas, mas ninguém acessa, ninguém percebe que está ali, todo mundo vê o banco na sua última versão.

As informações ficam armazenadas para haver a possibilidade de voltar no tempo e fazer uma auditoria se quisermos, e verificar por quem, quando e por que um dado foi apagado. Tudo isso estará armazenado no banco.

Conseguimos até fazer simulações do futuro, de como estaria o banco se fizéssemos certas transações devido ao armazenamento desse log.

Também por não trabalhar com várias tabelas, temos uma grande mudança na maneira de pensar em que conseguimos aplicar ferramentas genéricas a uma única tabela.

Poderemos criar comportamentos para diversos tipos de entidades de uma vez só de uma maneira mais simples com o Datomic Cloud pois isso será natural para ele.

Passaremos por seis aulas em que vamos acessar o banco, criar dados, esquemas, incluir dados, entender como eles estarão armazenados, fazer queries cada vez mais complexas, isolar nosso código das queries e fazer diversos acessos a medida que desenvolvemos essas queries de maneira mais complexa, conforme entendemos como funciona o Datomic.

Vamos começar nossos estudos.

Schema e transações - Instalação e configuração

Nosso primeiro passo, então, será baixar e instalar o Datomic. Para isso, vamos em datomic.com/get-datomic.html. Baixaremos a versão Starter, que é equivalente a versão Pro, mas gratuita.

Existem duas verões gratuitas do Datomic, a Starter e a Free, que tem outros tipos de restrições. Como a Starter é equivalente a Pro, que talvez você queira adquirir quando for utilizar o Datomic em maior escala, faremos o download dessa.

Quando clicarmos em Download Starter teremos que criar a conta. Após criar a conta, será enviada uma licença no e-mail válida por um período determinado por um ano atualmente. Quando ela expirar, basta pedirmos outra.

Voltando ao site, na barra superior, vamos em Downloads, que é a segunda opção. Baixaremos a versão mais recente, a "0.9.5951", e faremos a instalação em algum diretório. Como é um arquivo zipado, precisaremos descompactar.

Tal qual qualquer servidor de banco de dados, ele é um programa que você roda, então na versão padrão vamos simplesmente rodá-lo. Descompactamos e movemos para o diretório.

Pelo terminal vamos entrar nesse diretório. O que precisamos fazer agora é colocar nossa licença. Para isso, primeiro precisamos pegar o texto que nos enviaram por e-mail. Em seguida, copiamos o texto e colamos em um arquivo que o Datomic vai ler.

Em Local Dev Setup encontraremos o caminho para o processo de instalação. Após baixar e descompactar o arquivo, o que já fizemos, a documentação indica que devemos inserir a licença em um arquivo do tipo dev-transactor-templates-properties. Então o Datomic vai rodar um primeiro program, capaz de escrever dados no banco, que precisa da nossa licença.

Vamos entrar em config > samples> dev-transactor-template.properties. Esse arquivo é que vamos editar, então abriremos o sublime no editor de texto - pode ser qualquer um - e vamos abrir este arquivo. Nele aparecerá um espaço com license-key= onde colaremos a licença, salvaremos e na sequência vamos fechar.

Vamos copiar esse arquivo e jogar no diretório do nosso Datomic, fora de samples e dentro de config.

Será avisado para colocarmos bin/transactor e o caminho do nosso arquivo, ou seja, config/dev-transactor-template.properties > =Enter. Assim que a transação terminar, será alertado que o servidor inicializou como datomic:dev://localhost:4334/ o nome do banco <DB-NAME>. Vamos guardar os dados em data.

System started datomic:dev://localhost:4334/<DB-NAME>, storing data in: data

Então, ele pretende utilizar o diretório data para guardar os dados do banco que criarmos, a assim rodaremos o Datomic.

Nesse momento queremos nos conectar com ele, para isso abriremos o IntelliJ e criaremos um projeto novo. Vamos escolher um projeto de Clojure utilizando o Leiningen. Em seguida, escolheremos um diretório do projeto de acordo com o que for melhor para cada um e nomearemos o projeto como "ecommerce", já que trabalharemos com um sistema de ecommerce.

Tendo criado o projeto, teremos que instalar a biblioteca. Criaremos um banco usando a datomic api, que precisaremos antes baixar. Na página do Dev Setup vamos em Overview e selecionaremos o modo *Peer Library.

Para instalar esse modo, teremos que utilizar a dependência [com.datomic/datomic-EDITION"VERSION"] que copíaremos e colaremos em project.clj. A versão que estamos utilizando, a mais atual, é a 0.9.5951, entretanto será apresentado um erro se for colado esse número

Podemos ir em mvcentral e buscar o artefato do Datomic Pro. Colocamos a versão, vamos no Leiningen e atualizaremos. Mesmo assim não conseguiremos baixar a dependência porque a versão do Datomic Pro peer não fica em um repositório aberto, fica em uma espaço controlado pelo Datomic. Como o download depende da licença, é possível para a empresa controlar quem baixou a biblioteca.

Por isso, voltaremos para nossa conta logada e em My Account descemos a página até or via leiningen onde é explicado como baixamos a bibliotecas via Leiningen. Em nosso arquivo ~/lein/credentials.clj.gpg teremos que colocar alguma informação. Para isso, vamos no terminal, abrimos uma nova aba, vamos no diretório e criamos um novo diretório chamado .lein.

No arquivo credentials.clj.gpg adicionaremos o via copiando as linhas de código encontradas na página.

{#'my\.datomic\.com" {:username "guilherme.silveira@caelum.com.br"
    password "781e9538-97e0-43fd-ba36-840c06080743'}} 

Salvamos o arquivo de credenciais. É avisado também para alterar o project.clj, então também copiamos e colamos as duas linhas de código.

: repositores {"my.datomic.com" {:url "https://my.datomic.com/repo"
    :cred :gpg}}
:dependencies [[com.datomic/datomic-pro $VERSION]]

Em projects vamos adicionar uma nova opção. Agora colocaremos a versão 0.9.5951, salvaremos e tentaremos atualizar.

Vamos fechar o IntelliJ e abrir de novo para garantir que o lein começou do zero. Assim que terminar de abrir, reciclaremos novamente.

Há diversas maneiras de baixar esse jar, a página inicial da nossa conta descreve algumas formas para isso. Quando já tivermos baixado um zip, encontraremos um datomic-pro-0.9.5951.jar.

Vamos nos conectar com esse banco de dados a partir do nosso código, então precisaremos da biblioteca, dojar do Datomic e da dependência. Também vamos baixá-la no site.

Na documentação veremos que peer library e "Installing from Datomic distribution" bastará usarmos o comando bin/maven-intall no Linux ou no Mac ou, ainda a opção para Windows. Entrando nesse diretório, executaremos esse bin. Vamos baixar o Maven aqui. Escolhemos a primeira opção. Copiaremos a pasta apache-maven-3.6.2 para nosso diretorio apps.

Não acharemos o mvn, porque ele tem que estar em nosso paf. Então se voltarmos no diretório e entrarmos no apache maven teremos o diretório do Maven. Podemos dar um pwd para vê-lo e então exportar a nossa path com variável de path mas o diretoria/bin.

export PATH=$PATH:/Users/aluralaranja/Documents/Guilherme/datomic1-introducao/apps/apache-maven-3.6.2/bin. 

Serão procurados os programas nos locais em que já eram buscados anteriormente e no diretório bin desse projeto. Se rodar um mvn, vai carregar. Vamos entrar de novo no diretório do Datomic e rodar aquele bin/maeve-intall. Agora o Datomic será instalado

Logo são dois Datomics: um é o servidor do banco de dados e outro é a biblioteca para se conectar com o servidor.

Como já instalamos, vamos em nossas dependências. Além do Clojure, queremos instalar a dependência com o Datomic Pro e a versão 0.9.5961.

[[org.clojure/clojure "1.10.0"]
    [com.datomic/datomic-pro "0.9.6961"]]

Salvamos esse arquivo e vamos recarregá-lo, conforme a recomendação.

O sistema procurará o jar do Datomic Pro para que possamos conectar e fazer um primeiro teste.

Vamos rodar nosso project.clj, que o RELP padrão que vai carregar. Vamos rodar esse código que é um código simples que vai requerer a biblioteca deles e vai manifestar querer no localhost na porta 4334 em um banco de dados chamado hello.

Em seguida chamamos um d/create-database para criar esse banco de dados. Quando rodamos o nosso banco de dados ele estava falando que é na porta 4334, o que vamos comparar para ter certeza que está certo.

(require '[datomic.api :as d])
(def db-url "datomic:dev://localhost:4334/hello")
(d/create-database db-url)

Será devolvido true, temos um banco de dados criado. Se tentarmos de novo criar esse banco, devolve false porque ele já existe.

Então esse é o processo de instalação tanto do Datomic, quanto da biblioteca que ele é cliente, mas vamos chamar de peer nessa situação. No próximo vídeo, faremos a criação do banco de dados.

Schema e transações - Schema e transacionando dados

Temos nosso servidor e nossa biblioteca. Agora já conseguimos escrever códigos.

Dentro da CRC Commerce, temos o arquivo core.clj. Vamos apagá-lo, pois não utilizaremos o código que ele tem por padrão. Criaremos um novo arquivo Clojure Namescape para gerar um novo Namespace que será o core. É obrigatório que ele exista porque o Leiningen. vai carregá-lo para nós.

Vimos na documentação como fazíamos para criar um banco de dados. Demos um require, um def e um create. Copiaremos esse código que foi o executado.

Será necessário um cuidado: nós executamos esse códigos aqui no RELP, que requer o scape, já que estamos evocando a função require. Nós o usamos como um chave dentro do Namespace, então não temos aquele scape.

(ns ecommerce.core
    (:require [datomic.api :as d]))

Então, em seguida definiremos URI e criaremos o banco.

(def db-uri "datomic:dev://localhost:4334/hello")
(d/create-database db-uri) 

Criado o banco, nos conectaremos a ele. Para isso, vamos chamar um d/conect. Isso devolverá uma conexão que chamaremos de conn

(def conn (d/connect db-uri))

Se quisermos, podemos apagar esse banco com d/delete depois de fazer a conexão.

(d/delete-database db-ui)

Para ver isso tudo funcionando, podemos usar o pprint

(ns ecommerce.core
    (:use clojure.pprint)
    (:require [datomic.api :as d]))

(def db-uri "datomic:dev://localhost:4334/hello")
    (pprint (d/create-database db-uri))

(def conn (d/connect db-uri))
    (pprint conn)
    (pprint (d/delete-database db-uri))

Salvamos e já podemos rodar. Tudo estará no core então será carregado assim que rodarmos. Como o banco já existe, ele dará false para o create, mas os demais funcionarão da maneira esperada.

Isolaremos esse tipo de tarefa ligada ao banco em um arquivo. Se o projeto for muito pequeno, talvez terá um New Namespace que possamos chamar de db. Se quisermos um projeto maior, podemos criar mais arquivos dentro de, apenas um já será o suficiente.

Vamos pegar esse código de infraestrutura do banco e colocá-lo dentro do Namespace. Claro, vamos precisar do require e do use. Deixaremos o db-uri no mesmo local. Agora o banco será de ecommerce não mais hello.

Definiremos uma função agora, e poderíamos determinar que ela abre uma conexão. depois que conectamos e fizemos seja o que for, Poderíamos criar uma função abre-conexao que não receberá nada e vai criar o banco e conectar. Não é preciso definir a variável do connect porque só queremos retornar a conexão, então criamos o banco e conectamos. Então abrimos a conexão. Se o banco já existe, não faça nada, apenas conecte.

Além disso, vamos criar uma outra função apaga-banco que também não recebe nada e faz um delete.

(ns ecommerce.db
    (:use clojure.pprint)
    (:require [datomic.api :as d]))

(def db-uri "datomic:dev://localhost:4334/ecommerce")

(defn abre-conexao []
    (d/create-database db-uri)
    (d/connect db-uri))

(defn apaga-banco []
    (d/delete-database db-uri))

Podemos pensar que o create-database deveria estar em outro lugar, mas isso poderá ser definido de acordo com o que parecer melhor.

Voltando ao core, precisaremos comportar o db com ecommerce.db :as db. Em seguida, chamamos um db/abre-conexao. Isso deveria definir a conn então vamos dar um pprint nela.

(ns ecommerce.core
    (:use clojure.pprint)
    (:require [datomic.api :as d]
        [eecommerce.db :as db]))

(def conn (db/abre-conexao))
(pprint conn)

Então vamos recarregar esse arquivo. Ele recarrega e imprime a Connection.

Agora que já conseguimos estruturar alguns itens de banco, o que precisaremos fazer será colocar dados dentro do banco. Como vamos trabalhar em um sistema de ecommerce, é natural que queiramos simular um exemplo que armazena vários produtos.

O nome de um produto será um String, também uma RI que vamos chamar de slug, que será um caminho para acessá-lo. Enquanto o nome de um produto pode ser Computador Novo o slug - que também será uma String - pode ser /computador_novo.

Além disso, teremos o preço, um ponto flutuante, e pode ser 3500.10, por exemplo. Essa, então, é nossa estrutura, o esquema que temos para nossos produtos.

; Produtos
; nome String 1 ==> Computador Novo
; slug String 1 ==> /computador_novo
; preço ponto flutuante 1 ==> 3500.10

Essa seria a ideia de um banco de dados fracional. Em um banco de dados relacional baseado em SQL é muito comum que criemos uma tabela de produtos com três colunas, nome, slug e preço e, possivelmente uma coluna identificadora, de ID. Vamos jogar isso dentro do ecommerce.db porque são estruturas do banco de dados.

Se no SQL temos um creat-table para criar essa tabela, como fazemos para criar isso no Datomic? No Datomic, não vamos pensar em várias tabelas, mas em uma grande tabela. Nela, por exemplo, para o produto cujo ID é 15, o nome será Computador Novo, o slug será /computador_novo, e preco de 31500.10.

Assim estaremos atribuindo ao ID da entidade id_entidade, e teremos o atributo e o valor.

; id_entidade atributo valor
; 15 :nome Computador Novo
; 15 :slug /computador_novo
; 15 :preço 3500.10

Para outro produto, por exemplo, 17 fazemos o mesmo procedimento. O nome pode ser Telefone Caro, slug /telefone e preco 8888.88.

; 17 :nome Telefone Caro
; 17 :slug /telefone
; 17 :preço 8888.88

Teremos uma única tabela, mas com as linhas ligadas através do ID da entidade. Aprenderemos outras informações a respeito delas com o passar do tempo.

Alcançaremos uma forma de descrever essa estrutura para nosso banco. Para isso definiremos uma função, por exemplo, model/novo-produto de nome Computador Novo cujo slug é /computador_ novo e o preço é 2500.10.

(model/novo-produto "Computador Novo", "/computador_novo", 2500.10)

Então essa será uma função de modelo que vamos ter de criar. A criação será simples e a adicionarmos ao require

(:require [datomic.api :as d]
        [ecommerce.db :as db]
        [ecommerce.model :as model])

Dentro desse modelo, selecionamos Ctrl + N para criar o Namespace novo, de nome model. Com a função de def novo-produto que receberá o nome do produto, o slug e o preço e devolverá o mapa.

(defn novo-produto [nome slug preco] 
    {:nome nome
        : slug slug 
        : preco preco})

Voltando ao core, poderíamos apenas rodar isso e imprimir o resultado.

(pprint (model/novo-produto "Computador Novo", "/computador_novo", 2500.10))

Perfeito, imprime o computador. Mas o que queremos é colocar esse mapa dentro do banco. Para isso, chamamos a função d/transact, ou seja, transacionamos, colocamos dentro disso várias informações. Lembre-se, em um banco de dados tradicional, a transação pode ser um ou vários insert em uma tabela. Aqui também a transação será de vários itens.

Então no d/transact vamos dar a conexão conn e o que queremos colocar lá dentro, que é o novo-produto. Então na verdade em vez de darmos print vamos dar um let e chamaremos de computador. Na sequência tentaremos transacioná-lo.

(let [computador (model/novo-produto "Computador Novo", "/computador_novo", 2500.10)]
    (d/transact conn computador)) 

Só um cuidado, o computador é um mapa, o transact recebe a conexão e uma sequência - nesse caso, um vetor - com um único item que queremos transacionar.

(let [computador (model/novo-produto "Computador Novo", "/computador_novo", 2500.10)]
    (d/transact conn [computador])

Então podemos recarregar esse arquivo, ele imprime a conexão para nós e aparecerá como Loaded. Se rodarmos esse d/transact de novo, ele funcionará.

Vamos então tentar carregar o arquivo e vamos tentar executar esse código com Shift + L. Carregou, mas ele não executou o d/transact? Não tem problema, com o cursor selecionaremos d/transact e pressionaremos Shift + P para forçar a execução. Apesar de ter sido executado, aparecerá um erro. Vamos analisá-lo.

Não será mais necessário imprimir, então podemos apagar pprint conn.

O erro será :db.error/not-an-entity Unable to resolve entity: :nome. Será apontado que nome não é um entidade. novo-produto será um produto que tem nome slug e preço, três chaves. Essas chaves serão as indicadoras dos atributos, então de algum modo será preciso indicar isso a eles. Assim como no SQL indicamos "crie uma tabela que tem três campos", aqui, teremos que falar o que vamos chamar de atributos.

Também chamaremos esses atributos e vamos criá-los. indicaremos que esse atributo nome é uma String e único - no sentido de só ter um dele. Um produto tem uma slug e é uma String. O preco tem ponto flutuante e é único também. Nos faltará indicar essas características, por isso ele não achou nome.

O nome do produto pode ser um, mas o nome do usuário poderá ter outra regra e assim por diante. Por essa razão, o mais adequado será usarmos :produto/nome, usar keywords que são identificadores com o namespace, já que se tiver um outronome` com outras características não haverá conflito.

; id_entidade atributo valor
; 15 :produto/nome Computador Novo
; 15 :produto/slug /computador_novo
; 15 :produto/preço 3500.10
; 17 :produto/nome Telefone Caro
; 17 :produto/slug /telefone
; 17 :produto/preço 8888.88

Então o que queremos fazer agora é definir esse esquema. Um schema é um lista de definições. Queremos definir primeiro que temos um identificador identque se chama produto/nome e ele terá um tipo de valor (valueType) db.type/string. Foi dito que um produto tem um nome, então a cardinality é um db.cardinality/one.

Podemos colocar também a documentação, nesse caso pode ser "O nome de um produto", por exemplo.

(def schema [{:db/ident :produto/nome
    :db/valueType :db.type/string
    :db/cardinality :db.cardinality/one
    :db/doc "O nome de um produto"}]) 

Do mesmo jeito que fizemos esse mapa, podemos colocar outros, outro db/ident que pode ser o produto/slug. Ele tem tipo de valor de string, cardinalidade one e doc que pode ser "Caminho para acessar esse produto via http".

Por fim, vamos ter também o preço. ident é produto/preco. E o valuType? Vamos na documentação ver os tipo, encontramos float e double mas eles tem o problema do arredondamento, ou seja, não tem precisão. Vamos escolher então o BigDecimal, assim :db.type/bigdec. Cardinalidade também será one e doc "Preço de um produto".

{:db/ident :produto/slug
    :db/valueType :db.type/string
    :db/cardinality :db.cardinality/one
    :db/doc "O caminho para acessar esse produto via http"}
{db/ident :produto/preco
    :db/valueType :db.type/bigdec
    db/cardinality :db.cardinality/one
    db/doc "O preco de um produto com precisão monetária"} 

Nosso esquema serão dados sequências de mapas, como tudo que trabalhamos em clojure. Agora queremos transacionar esse esquema. Assim como o nosso produto é um dado, o esquema e estrutura são mapas e utilizaremos esses flashmaps.

Voltando a ecommerce.core, antes de tentar transacionar o computador vamos transacionar na conexão conn o db/schema. Mas antes precisamos recarregar as mudanças que fizemos em ecommerce.db.

(db/transact conn db/schema)

Executamos e teremos um resultado bem grande. Os resultados do Datomic são, em geral, enormes. Conseguimos interpretar o que acontecerá transaction-data com o passar do tempo. No instante 2019-09-18T14:34:22.896-00:00" terá ocorrido a transação 13194139534312. Essa transação aparecerá várias vezes porque só fizemos uma. O quarto valor do banco é o ID da transação ID_TX.

clojure 
#datom [72 10 :produto/nome 13194139534312 true]
#datom [72 40 23 13194139534312 true]
#datom [72 41 35 13194139534312 true]
#datom [72 62 "O nome de um produto" 13194139534312 true]
#datom [73 10 :produto/slug 13194139534312 true]
#datom [73 40 23 13194139534312 true]
#datom [73 41 35 13194139534312 true] 
#datom [73 62 "O caminho para acessar esse produto via http 13194139534312 true] 

Aqui vemos que para a entidade 72 temos o atributo 62, o valor "O nome de um produto". Para a entidade 72 o 41 tem valor 35, para a entidade 72, 10 tem o valor :produto/nome. Provavelmente, db.type/string: é o 23, o cardinality/one é o 35, o valueType é o 40 E pode ver que quando chegamos no slug 73, são esses números que ele repete. Assim como vamos supor que 72 é o produto/nome, 73 produto/slug e 74 o produto/preco.

Então em vez dele ficar sempre referenciando, usa um atalho e tem um identificador para os identificadores que utilizamos.

Todos esses b@datoms serão colocados no banco, porque true que dizer que foram incluídos, false é de retirada. O quinto valor se referirá a operação realizada, de colocada ou de retirada.

Serão devolvidos alguns identificadores para os nossos produtos. Então se quiséssemos, no retorno de uma transação, conseguimos pegar os IDs que foram gerados e saber exatamente o que foi colocado dentro do banco, o resultado do d/transact.

Não queremos deixar isso ser feito assim toda vez, porque se executarmos novamente o Datomic perceberá que esses datoms já estarão lá e não deverão ser adicionados novamente, definindo o produto/nome, produto/slug e o produto/preco. Então podemos executar o transact do mesmo esquema diversas vezes, desde que não tenha alterações.

Extrairemos uma função db/cria-schema que recebe a conn para isolar isso dentro do nossos ecommerce.db.

(defn cria-schema [conn]
    (d/transact conn schema))

E agora se tentarmos adicionar a pessoa no banco, será que vai funcionar? Repare, agora já existe o produto/nome, produto/slug e produto/preco.

(def conn (db/abre-conexao))

(db/cria-schema conn) 

(let [computador (model/novo-produto "Computador Novo", "/computador_novo", 2500.10)]
    (d/transact conn [computador])) 

Dará erro e o programa dirá que a entidade nome não existe. Isso ocorreu porque em ecommerce.model o novo-produto está usando nome, slug e preco, quando deveria estar usando produto/nome, produto/slug e produto/preco.

(defn novo-produto [nome slug preco]
    {:produto/nome nome
      :produto/slug slug
      :produto/preco preco})

Assim conseguimos fazer direto a transferência do modelo pro banco.

Teremos problemas porque usamos 2500.10 com o valueType bigDec, mas esse é um valor double. Adicionando M transformamos ele em um valor bigDecimal.

(def conn (db/abre-conexao))

(db/cria-schema conn) 

(let [computador (model/novo-produto "Computador Novo", "/computador_novo", 2500.10M)]
    (d/transact conn [computador])) 

Agora dará certo. Será colocado no banco um "Computador Novo" cujo slug é /computador_novo e o valor 2500.10M. De fato, 72 era produto/nome 73 produto/slug e 74 produto/preco. Mas não precisaremos decorar esses IDs, pois essa transformação ocorrerá sozinha. O Datomic ainda anota quando isso ocorreu.

#inst"2019-09-18t14:40:22.669-00:00"

Dessa criamos um esquema e transacionamos dados que estarão dentro do Datomic.

Nos próximos vídeos continuaremos editando dados no banco.

Sobre o curso Datomic: um banco cronológico

O curso Datomic: um banco cronológico possui 144 minutos de vídeos, em um total de 35 atividades. Gostou? Conheça nossos outros cursos de NoSQL em Data Science, ou leia nossos artigos de Data Science.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda NoSQL acessando integralmente esse e outros cursos, comece hoje!

Plus

De
R$ 1.800
12X
R$109
à vista R$1.308
  • Acesso a TODOS os cursos da Alura

    Mais de 1500 cursos completamente atualizados, com novos lançamentos todas as semanas, emProgramação, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.

  • Alura Challenges

    Desafios temáticos para você turbinar seu portfólio. Você aprende na prática, com exercícios e projetos que simulam o dia a dia profissional.

  • Alura Cases

    Webséries exclusivas com discussões avançadas sobre arquitetura de sistemas com profissionais de grandes corporações e startups.

  • Certificado

    Emitimos certificados para atestar que você finalizou nossos cursos e formações.

Matricule-se

Pro

De
R$ 2.400
12X
R$149
à vista R$1.788
  • Acesso a TODOS os cursos da Alura

    Mais de 1500 cursos completamente atualizados, com novos lançamentos todas as semanas, emProgramação, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.

  • Alura Challenges

    Desafios temáticos para você turbinar seu portfólio. Você aprende na prática, com exercícios e projetos que simulam o dia a dia profissional.

  • Alura Cases

    Webséries exclusivas com discussões avançadas sobre arquitetura de sistemas com profissionais de grandes corporações e startups.

  • Certificado

    Emitimos certificados para atestar que você finalizou nossos cursos e formações.

  • Luri, a inteligência artificial da Alura

    Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com Luri até 100 mensagens por semana.

  • Alura Língua (incluindo curso Inglês para Devs)

    Estude a língua inglesa com um curso 100% focado em tecnologia e expanda seus horizontes profissionais.

Matricule-se
Conheça os Planos para Empresas

Acesso completo
durante 1 ano

Estude 24h/dia
onde e quando quiser

Novos cursos
todas as semanas