Servidor Couchbase

Comparação entre SQL e NoSQL: Aplicativo ASP.NET

Essa comparação entre SQL e NoSQL é a próxima etapa após a conversão do seu banco de dados do SQL Server para o Couchbase. Em a postagem anteriorEm um dos meus testes, copiei o AdventureWorks do SQL Server para o Couchbase.

Nesta postagem, mostrarei um aplicativo ASP.NET Core que usa o SQL Server e como esse mesmo aplicativo usaria o Couchbase. Se quiser acompanhar, você pode conferir o Projeto SqlServerToCouchbase no GitHub.

Ao contrário da postagem anterior, não estou tentando fazer uma conversão "automática" de um aplicativo. Em vez disso, pense nisso mais como uma comparação entre SQL e NoSQL no nível do aplicativo.

Aplicativos ASP.NET SQL Server

Criei um aplicativo muito simples no estilo da API REST do ASP.NET Core. Usei o Entity Framework, mas se você estiver usando Dapper, ADO.NET, NHibernate etc., ainda poderá acompanhar o processo.

Cada endpoint retorna JSON. Também adicionei o Swashbuckle ao projeto, para que você possa emitir solicitações diretamente do navegador via OpenAPI.

Aplicativo do servidor ASP.NET Couchbase

A versão Couchbase do aplicativo retorna os mesmos dados, porque está usando os mesmos dados do SQL Server AdventureWorks.

No aplicativo, estou usando o SDK do Couchbase .NET e Transações do Couchbase bibliotecas. (Você poderia usar Linq2Couchbase como um tipo de substituição do Entity Framework).

Caso contrário, o aplicativo é o mesmo, fornecendo uma comparação (e contraste) entre SQL e NoSQL. Os pontos de extremidade estão retornando JSON, e o Swashbuckle está instalado.

Há um controlador em cada amostra. Vamos examinar cada endpoint no controlador e realizar uma comparação SQL e NoSQL.

Comparação entre SQL e NoSQL: Obter por ID

Vamos começar com o GetPersonByIdAsync endpoint. Dado um ID de pessoa, esse ponto de extremidade retorna os dados da pessoa para o ID fornecido.

SQL Server

Aqui está o exemplo do SQL Server usando o Entity Framework:

Também escrevi outra versão desse método, chamada GetPersonByIdRawAsync que usa uma consulta SQL "bruta". Essa consulta é muito parecida com a que o Entity Framework (acima) gera, e é semelhante a uma abordagem Dapper.

Observe que, de qualquer forma, uma consulta SQL está sendo executada.

Com o N1QL, podemos consultar os dados no Couchbase de forma muito semelhante. Aqui está o GetPersonByIdRawAsync no projeto Couchbase:

(Há uma etapa extra que vai de "bucket" para "cluster". Ela poderia ser ignorada, mas como uso bucket em outras partes do controlador, deixei-a lá).

No entanto, o uso de uma consulta N1QL envolve alguma sobrecarga extra (indexação, análise de consulta etc.). Com o Couchbase, se já soubermos o ID da pessoa, podemos ignorar uma consulta N1QL e fazer uma pesquisa direta de chave/valor (K/V).

Obter por ID com K/V

A chave já é conhecida; ela é fornecida como um argumento. Em vez de usar SQL, vamos fazer uma pesquisa de chave/valor. Fiz isso em um método de endpoint chamado GetPersonByIdAsync:

Ao contrário do SQL Server, o Couchbase oferece suporte a uma variedade de APIs para interagir com os dados. Nesse caso, a pesquisa de chave/valor estará extraindo o documento Person diretamente da memória. Não há necessidade de analisar uma consulta SQL ou usar qualquer indexação. As pesquisas de chave/valor no Couchbase geralmente são medidas em microssegundos.

Minha recomendação: use a pesquisa de chave/valor sempre que possível.

Obter uma entidade expandida por ID

Os dados podem ser complexos e abranger várias tabelas (ou vários documentos, no caso do Couchbase). Dependendo das ferramentas que estiver usando, você pode ter alguma funcionalidade que possa carregar entidades relacionadas.

Por exemplo, com o Entity Framework, você pode usar um Incluir para atrair entidades relacionadas, como mostrado neste GetPersonByIdExpandedAsync exemplo:

Nos bastidores, o Entity Framework pode gerar uma consulta JOIN e/ou várias consultas SELECT para que isso aconteça.

É nesse ponto que qualquer O/RM (não apenas o Entity Framework) pode ser perigoso. Certifique-se de usar uma ferramenta como o SQL Profiler para ver quais consultas estão realmente sendo executadas.

Observação
Os O/RMs podem ajudar, mas em um SQL para NoSQL Em comparação, é importante lembrar que a incompatibilidade de impedância é um problema muito menor no mundo NoSQL.

Para o exemplo do Couchbase, não estou usando o Entity Framework, mas, em vez disso, posso usar o Sintaxe NEST que faz parte das extensões N1QL do padrão SQL. Veja como a versão do Couchbase do GetPersonByIdExpandedAsync aparência:

NEST é um tipo de JOIN que coloca os dados JOINed em um objeto JSON aninhado. Em vez de usar um O/RM para mapear os dados, esses dados podem ser serializados diretamente em objetos C#.

Consulta de paginação

Vamos dar uma olhada em um exemplo em que NÃO temos uma única chave para procurar um dado. Vejamos um método que retorna uma "página" de resultados (talvez para preencher uma grade ou lista da interface do usuário).

Paginação no SQL Server

Aqui está a versão do SQL Server de GetPersonsPageAsync:

Com o Entity Framework, Ordem, Pulare Pegue são normalmente usados para paginação. Se abrirmos o SQL Server Profiler, o SQL gerado terá a seguinte aparência:

OFFSET ... ROWS FETCH NEXT ... é a sintaxe que está sendo usada para paginação aqui.

Paginação no Couchbase

A sintaxe de paginação sempre varia entre as implementações de SQL. O Couchbase se inclina mais para a sintaxe do Oracle/MySQL nesse aspecto. Aqui está a versão do Couchbase de GetPersonsPageAsync:

Nesse caso, LIMITE ... DESLOCAMENTO ... está sendo usado.

Também quero destacar o WHERE p.LastName IS NOT MISSING. Como o Couchbase é um banco de dados NoSQL, o mecanismo de consulta não pode presumir que Sobrenome estará em todos os documentos, mesmo com ORDER BY p.LastName. Ao adicionar este ONDE a consulta agora sabe qual índice usar. Sem isso, a consulta levará muito mais tempo para ser executada.

Atualizar com uma transação ACID

Com o modelo de estilo relacional que estamos usando no SQL Server e no Couchbase para este exemplo, as transações ACID serão importantes para ambos os aplicativos.

Nesses exemplos, há um PersonUpdateApi que permitirá que o usuário atualize ambos o nome de uma pessoa e seu endereço de e-mail. Como esses dados estão em duas tabelas/linhas separadas (SQL Server) ou dois documentos separados (Couchbase), queremos que essa seja uma operação atômica do tipo tudo ou nada.

Observação
Um ID é especificado para ambos (para simplificar a API), pois é possível (mas raro nesse conjunto de dados) que uma pessoa tenha vários endereços de e-mail.

ACID com o Entity Framework

Aqui está um exemplo de uma transação ACID usando o Entity Framework para atualizar uma linha de dados na tabela Person e uma linha de dados na tabela EmailAddress.

Observe as quatro partes principais de uma transação:

  1. Iniciar transação (_context.Database.BeginTransactionAsync();)
  2. tentar/captura
  3. Transação de confirmação (await transaction.CommitAsync();)
  4. Transação de reversão no captura (transaction.RollbackAsync();)

Esse é um recurso importante em que a comparação entre SQL e NoSQL mudou nos últimos anos. Com o Couchbase, as transações ACID agora são possíveis.

ACID com uma transação do Couchbase

Com o Couchbase, a API é um pouco diferente, mas as mesmas etapas estão todas lá:

As etapas principais são as mesmas:

  1. Iniciar transação (transaction.RunAsync( ... ))
  2. tentar/captura
  3. Transação de compromisso (implícita, mas contexto.CommitAsync() poderia ser usado)
  4. Transação de reversão (novamente, implícita, mas contexto.RollbackAsync() poderia ser usado).

Em ambos os casos, temos uma transação ACID. Diferente de SQL Server, no entanto, podemos mais tarde otimizar e consolidar os dados no Couchbase para reduzir a quantidade de transações ACID de que precisamos e aumentar o desempenho.

Procedimentos armazenados: uma comparação entre SQL e NoSQL

Os procedimentos armazenados são um tópico às vezes controverso. De modo geral, eles podem conter muita funcionalidade e lógica.

Procedimento armazenado no SQL Server

Criei um procedimento armazenado chamado "ListSubcomponents" (você pode ver o arquivo Detalhes completos no GitHub). Com o Entity Framework, você pode usar FromSqlRaw para executá-lo e mapear os resultados para objetos C#. Criei um objeto C# de pseudo-entidade chamado ListSubcomponents que é usado apenas para esse sproc:

O procedimento armazenado tem dois parâmetros.

Função definida pelo usuário do Couchbase

O Couchbase não tem nada chamado de "procedimento armazenado" (ainda), mas tem algo chamado de função definida pelo usuário (UDF) que também pode conter lógica complexa quando necessário.

Criei um UDF chamado ListSubcomponents (que você também pode visualização no GitHub) que corresponde à funcionalidade do sproc do SQL Server.

Veja a seguir como executar esse UDF no ASP.NET:

Invocá-lo no Couchbase com dois parâmetros é muito semelhante a usar o FromSqlRaw com o Entity Framework.

Desempenho - Comparação entre SQL e NoSQL

Agora que converti o aplicativo para usar o Couchbase, a nova versão é executada pelo menos tão rapidamente quanto a versão antiga do SQL Server?

É uma pergunta complicada de responder porque:

  • Não fiz NENHUMA otimização no modelo de dados. Ainda estou usando a conversão literal de dados de a postagem anterior.
  • O acesso aos dados pode variar muito de caso de uso para caso de uso.
  • Os ambientes podem variar muito de pessoa para pessoa e de empresa para empresa.

No entanto, eu queria fazer alguns testes de carga "por trás do envelope" como uma verificação de sanidade.

Executei os dois aplicativos em minha máquina local e usei ngrok para expô-los à Internet. Em seguida, usei carregador.io (uma excelente ferramenta para testes de carga com concorrência). Em seguida, executei alguns testes rápidos de desempenho somente com o endpoint de "paginação". Esse é o endpoint com o qual estou mais preocupado em termos de desempenho, e também acho que é a comparação SQL e NoSQL mais "igualitária" entre os endpoints.

Comparação entre SQL e NoSQL para teste de carga

Aqui estão os resultados do aplicativo do SQL Server:

SQL and NoSQL comparison - SQL Server load testing

E aqui estão os resultados do aplicativo Couchbase Server:

SQL and NoSQL comparison - Couchbase Server load testing

Interpretação dos resultados do teste de carga de comparação entre SQL e NoSQL

Não se trata de um benchmark ou de um ponto de dados que diga que "o Couchbase é mais rápido que o SQL Server".

O objetivo é apenas uma verificação de sanidade.

Se eu não estiver obtendo um desempenho pelo menos tão bom sob carga quanto antes, talvez eu esteja fazendo algo errado. Esse é um benefício crucial para o prova de conceito processo. Embora o Couchbase, especialmente o Couchbase 7, seja muito compatível com o sistema relacional, ainda existem diferenças e nuances entre todos e esse processo o ajudará a identificar as diferenças que mais importam para você e seu projeto.

Se estiver procurando benchmarks mais robustos, aqui estão alguns recursos que você pode consultar:

Conclusão

A comparação e a conversão de SQL e NoSQL do código do aplicativo, combinadas com alguns testes de carga muito básicos, mostram que eu posso:

  • Hospedar um modelo de dados relacional como está, sem alterações de modelagem
  • Converter os pontos de extremidade do ASP.NET para usar o SDK do Couchbase
  • Espere um desempenho pelo menos tão bom no início, com muito espaço para escalar e melhorar, com baixo risco.

Seu caso de uso pode variar, mas lembre-se também de que, durante essa conversão, o Couchbase nos forneceu:

Apêndice

Aqui está um guia sucinto da comparação entre SQL e NoSQL que fiz no aplicativo.

Operação do SQL Server Operação do Couchbase

Ler/gravar uma linha/entidade

Pesquisa de chave/valor

Ler/gravar várias linhas/páginas

Consulta N1QL

SELECIONAR uma entidade com entidades relacionadas

Consulta N1QL com NEST

BeginTransaction

Transação.Create

Procedimento armazenado

UDF (Eventos também pode ser útil aqui)

Lembretes:

  1. Mude para a API de chave/valor quando puder
  2. Use a indexação, a visualização do plano de indexação e o consultor de índices ao escrever N1QL
  3. Use uma transação ACID (somente) quando precisar
  4. Pense nas metas de desempenho e estabeleça uma maneira de testá-las

Próximas etapas

Confira Couchbase Server 7, atualmente em versão betahoje. É um download gratuito. Tente carregar seus dados relacionais nele, convertendo alguns pontos de extremidade, e veja se o processo funciona para você.

Compartilhe este artigo
Receba atualizações do blog do Couchbase em sua caixa de entrada
Esse campo é obrigatório.

Autor

Postado por Matthew Groves

Matthew D. Groves é um cara que adora programar. Não importa se é C#, jQuery ou PHP: ele enviará solicitações de pull para qualquer coisa. Ele tem programado profissionalmente desde que escreveu um aplicativo de ponto de venda QuickBASIC para a pizzaria de seus pais nos anos 90. Atualmente, ele trabalha como gerente sênior de marketing de produtos da Couchbase. Seu tempo livre é passado com a família, assistindo aos Reds e participando da comunidade de desenvolvedores. Ele é autor de AOP in .NET, Pro Microservices in .NET, autor da Pluralsight e Microsoft MVP.

Deixe um comentário

Pronto para começar a usar o Couchbase Capella?

Iniciar a construção

Confira nosso portal do desenvolvedor para explorar o NoSQL, procurar recursos e começar a usar os tutoriais.

Use o Capella gratuitamente

Comece a trabalhar com o Couchbase em apenas alguns cliques. O Capella DBaaS é a maneira mais fácil e rápida de começar.

Entre em contato

Deseja saber mais sobre as ofertas do Couchbase? Deixe-nos ajudar.