{"id":2708,"date":"2017-03-07T09:51:19","date_gmt":"2017-03-07T17:51:19","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=2708"},"modified":"2024-09-12T02:19:18","modified_gmt":"2024-09-12T09:19:18","slug":"moving-sql-server-couchbase-app-migration","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pt\/moving-sql-server-couchbase-app-migration\/","title":{"rendered":"Mudan\u00e7a do SQL Server para o Couchbase Parte 3: Migra\u00e7\u00e3o de aplicativos"},"content":{"rendered":"<div id=\"header\">\n<h2>Mudan\u00e7a do SQL Server para o Couchbase Parte 3: Migra\u00e7\u00e3o de aplicativos<\/h2>\n<\/div>\n<div id=\"preamble\">\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Nesta s\u00e9rie de postagens do blog, apresentarei as considera\u00e7\u00f5es sobre a mudan\u00e7a para um banco de dados de documentos quando voc\u00ea tem um hist\u00f3rico relacional. Especificamente, o Microsoft SQL Server em compara\u00e7\u00e3o com o <a href=\"https:\/\/developer.couchbase.com\/?utm_source=blogs&amp;utm_medium=link&amp;utm_campaign=blogs\">Servidor Couchbase<\/a>.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Em tr\u00eas partes, abordarei o assunto:<\/p>\n<\/div>\n<div class=\"ulist\">\n<ul>\n<li><a href=\"https:\/\/www.couchbase.com\/blog\/pt\/moving-from-sql-server-to-couchbase-part-1-data-modeling\/\">Modelagem de dados<\/a><\/li>\n<li><a href=\"https:\/\/www.couchbase.com\/blog\/pt\/sql-server-couchbase-data-migration\/\">Migra\u00e7\u00e3o de dados<\/a><\/li>\n<li>Aplicativos que usam os dados (esta postagem do blog)<\/li>\n<\/ul>\n<\/div>\n<div class=\"paragraph\">\n<p>O objetivo \u00e9 estabelecer algumas diretrizes gerais que podem ser aplicadas ao planejamento e ao design do seu aplicativo.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Se voc\u00ea quiser acompanhar, criei um aplicativo que demonstra o Couchbase e o SQL Server lado a lado. <a href=\"https:\/\/github.com\/couchbaselabs\/blog-source-code\/tree\/master\/Groves\/045MigrateFromSQLServer\/src\/SQLServerToCouchbase\">Obtenha o c\u00f3digo-fonte no GitHub<\/a>e certifique-se de <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/downloads\/?utm_source=blogs&amp;utm_medium=link&amp;utm_campaign=blogs\">Fa\u00e7a o download de uma pr\u00e9via para desenvolvedores do Couchbase Server<\/a>.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_migrate_vs_rewrite\">Migrar vs. Reescrever<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Se voc\u00ea estiver criando um novo aplicativo da Web, o Couchbase Server \u00e9 uma boa op\u00e7\u00e3o para usar como seu <strong>sistema de registro<\/strong>. A modelagem de dados flex\u00edvel, o acesso r\u00e1pido aos dados e a facilidade de dimensionamento fazem dele uma boa op\u00e7\u00e3o.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>O Couchbase Server pode complementar o SQL Server em seu aplicativo da Web existente. Ele pode ser um armazenamento de sess\u00e3o ou um armazenamento de cache. Voc\u00ea n\u00e3o precisa substituir seu RDMBS para se beneficiar do Couchbase Server. Voc\u00ea pode us\u00e1-lo como seu <strong>sistema de engajamento<\/strong>.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>No entanto, se voc\u00ea estiver pensando em fazer de um banco de dados de documentos o seu \"sistema de registro\" para um aplicativo existente, precisar\u00e1 planejar o que fazer com esse aplicativo (supondo que voc\u00ea j\u00e1 tenha elaborado um plano de modelagem e migra\u00e7\u00e3o de dados, conforme abordado nas partes anteriores desta s\u00e9rie do blog). Na verdade, h\u00e1 duas op\u00e7\u00f5es:<\/p>\n<\/div>\n<div class=\"ulist\">\n<ul>\n<li><strong>Substitua sua camada de dados\/servi\u00e7o<\/strong>. Se voc\u00ea criou seu aplicativo de forma a desacopl\u00e1-lo da persist\u00eancia subjacente, isso o beneficiar\u00e1 enormemente ao mudar do SQL Server para o Couchbase. Se voc\u00ea estiver usando um SOA, por exemplo, talvez n\u00e3o precise fazer muitas altera\u00e7\u00f5es no aplicativo Web.<\/li>\n<li><strong>Reconstrua seu aplicativo<\/strong>. Se voc\u00ea n\u00e3o tiver uma arquitetura desacoplada, provavelmente ter\u00e1 que se preocupar e reescrever\/refatorar grandes partes do seu aplicativo. Esse pode ser um custo significativo que voc\u00ea ter\u00e1 de levar em conta ao decidir se deve ou n\u00e3o mudar para um banco de dados de documentos. Eu gostaria de poder dizer que seria mais f\u00e1cil, que haveria uma po\u00e7\u00e3o m\u00e1gica que voc\u00ea poderia usar. Mas lembre-se, mesmo que o custo de uma reconstru\u00e7\u00e3o seja muito alto, voc\u00ea ainda pode usar o Couchbase Server em<br \/>\nem conjunto com o SQL Server.<\/li>\n<\/ul>\n<\/div>\n<div class=\"paragraph\">\n<p>As pe\u00e7as da pilha que podem precisar ser reconstru\u00eddas ou substitu\u00eddas incluem:<\/p>\n<\/div>\n<div class=\"ulist\">\n<ul>\n<li><strong>ADO.NET<\/strong> - Se estiver usando o ADO.NET simples ou um micro-OR\/M como o Dapper, eles podem ser substitu\u00eddos pelo SDK do Couchbase .NET.<\/li>\n<li><strong>OR\/M<\/strong> - Estrutura de entidades, NHibernate, Linq2SQL, etc. Eles podem ser substitu\u00eddos pelo Linq2Couchbase<\/li>\n<li><strong>Qualquer c\u00f3digo que os utilize diretamente<\/strong> - Qualquer c\u00f3digo que toque em ADO.NET, OR\/Ms ou outro c\u00f3digo do SQL Server precisar\u00e1 ser substitu\u00eddo para usar o Couchbase (e\/ou reescrito para introduzir outra camada de abstra\u00e7\u00e3o).<\/li>\n<\/ul>\n<\/div>\n<div class=\"paragraph\">\n<p>O restante desta postagem do blog ser\u00e1 composto de dicas e diretrizes que se aplicam \u00e0 reescrita, \u00e0 refatora\u00e7\u00e3o ou ao in\u00edcio de um novo projeto.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_what_s_going_to_be_covered\">O que ser\u00e1 coberto<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Os bancos de dados de documentos for\u00e7am a l\u00f3gica comercial para fora do banco de dados em uma extens\u00e3o maior do que os bancos de dados relacionais. Por melhor que fosse se o Couchbase Server tivesse todos os recursos dispon\u00edveis, sempre h\u00e1 compensa\u00e7\u00f5es.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Nesta postagem do blog, abordaremos as altera\u00e7\u00f5es na codifica\u00e7\u00e3o de aplicativos que v\u00eam com o uso do Couchbase. Em um alto n\u00edvel, veja o que ser\u00e1 abordado nesta postagem do blog. \u00c0 esquerda, um recurso do SQL Server; \u00e0 direita, o equivalente mais pr\u00f3ximo ao usar o Couchbase Server.<\/p>\n<\/div>\n<table class=\"tableblock frame-all grid-all spread\">\n<colgroup>\n<col style=\"width: 50%\" \/>\n<col style=\"width: 50%\" \/> <\/colgroup>\n<thead>\n<tr>\n<th class=\"tableblock halign-left valign-top\">SQL Server<\/th>\n<th class=\"tableblock halign-left valign-top\">Servidor Couchbase<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">tSQL<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">N1QL<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">Procedimentos armazenados<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">N\u00edvel de servi\u00e7o<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">Gatilhos<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">N\u00edvel de servi\u00e7o<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">Visualiza\u00e7\u00f5es<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">Visualiza\u00e7\u00f5es Map\/Reduce<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">N\u00famero autom\u00e1tico<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">Balc\u00e3o<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">OR\/M (mapeador de objeto\/relacional)<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">ODM (Modelo de dados de objeto)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">\u00c1CIDO<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">ACID de documento \u00fanico<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"paragraph\">\n<p>Al\u00e9m disso, tamb\u00e9m abordaremos estes t\u00f3picos importantes:<\/p>\n<\/div>\n<div class=\"ulist\">\n<ul>\n<li>Serializa\u00e7\u00e3o<\/li>\n<li>Seguran\u00e7a<\/li>\n<li>Concorr\u00eancia<\/li>\n<li>SSIS, SSRS, SSAS<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_using_n1ql\">Usando o N1QL<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>O <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/n1ql\/\">N1QL (pronuncia-se \"nickel\")<\/a> A linguagem de consulta SQL \u00e9 um dos meus recursos favoritos do Couchbase Server. Voc\u00ea j\u00e1 est\u00e1 familiarizado com a linguagem de consulta SQL. Com o N1QL, voc\u00ea pode aplicar seus conhecimentos a um banco de dados de documentos.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Aqui est\u00e3o alguns exemplos para mostrar o <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/current\/n1ql\/n1ql-intro\/n1ql-sql-differences.html?utm_source=blogs&amp;utm_medium=link&amp;utm_campaign=blogs\">semelhan\u00e7as entre o N1QL e o tSQL<\/a>:<\/p>\n<\/div>\n<table class=\"tableblock frame-all grid-all spread\">\n<colgroup>\n<col style=\"width: 50%\" \/>\n<col style=\"width: 50%\" \/> <\/colgroup>\n<thead>\n<tr>\n<th class=\"tableblock halign-left valign-top\">tSQL<\/th>\n<th class=\"tableblock halign-left valign-top\">N1QL<\/th>\n<\/tr>\n<\/thead>\n<tfoot>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">DELETE FROM [tabela] WHERE val1 = 'foo'<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">DELETE FROM `bucket` WHERE val1 = &#8216;foo&#8217;<\/p>\n<\/td>\n<\/tr>\n<\/tfoot>\n<tbody>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">SELECT * FROM [tabela]<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">SELECT * from `bucket`<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">SELECT t1.* , t2.* FROM [table1] t1 JOIN [table2] t2 ON t1.id = t2.id<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">SELECT b1.* , b2.* FROM `bucket` b1 JOIN `bucket` b2 ON KEYS b1.mykeys<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">INSERT INTO [table] (key, col1, col2) VALUES (1, 'val1\u2032,'val2')<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">INSERT INTO `bucket` (KEY, VALUE) VALUES (&#8216;1&#8217;, {&#8220;col1&#8243;:&#8221;val1&#8221;, &#8220;col2&#8243;:&#8221;val2&#8221;})<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">UPDATE [tabela] SET val1 = 'newvalue' WHERE val1 = 'foo'<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">UPDATE `bucket` SET val1 =&#8217;newvalue&#8217; WHERE val1 = &#8216;foo&#8217;<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"paragraph\">\n<p>Agradecimentos a <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/n1ql\/\">N1QL<\/a>Se voc\u00ea n\u00e3o tiver um banco de dados de documentos, migrar suas consultas SQL deve ser menos dif\u00edcil do que em outros bancos de dados de documentos. Seu modelo de dados ser\u00e1 diferente, e nem todas as fun\u00e7\u00f5es do tSQL est\u00e3o (ainda) dispon\u00edveis no N1QL. Mas, na maior parte do tempo, seu conhecimento atual de escrita em tSQL pode ser aplicado.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Voltando ao carrinho de compras, aqui est\u00e1 um exemplo de uma consulta tSQL simples que obteria informa\u00e7\u00f5es sobre o carrinho de compras de um determinado usu\u00e1rio:<\/p>\n<\/div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight decode:true\"><code class=\"language-SQL\">SELECT c.Id, c.DateCreated, c.[User], i.Price, i.Quantity\r\nFROM ShoppingCart c\r\nINNER JOIN ShoppingCartItems i ON i.ShoppingCartID = c.Id\r\nWHERE c.[User] = 'mschuster'<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"paragraph\">\n<p>No Couchbase, um carrinho de compras poderia ser modelado como um \u00fanico documento, portanto, uma consulta aproximadamente equivalente seria:<\/p>\n<\/div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight decode:true\"><code class=\"language-SQL\">SELECT META(c).id, c.dateCreated, c.items, c.`user`\r\nFROM `sqltocb` c\r\nWHERE c.type = 'ShoppingCart'\r\nAND c.`user` = 'mschuster';<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"paragraph\">\n<p>Observe que, embora o N1QL tenha <code>JUNTAR<\/code> funcionalidade, n\u00e3o <code>JUNTAR<\/code> \u00e9 necess\u00e1rio nessa consulta de carrinho de compras. Todos os dados do carrinho de compras est\u00e3o em um \u00fanico documento, em vez de estarem espalhados em v\u00e1rias tabelas e linhas.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Os resultados n\u00e3o s\u00e3o <em>exatamente<\/em> o mesmo: a consulta N1QL retorna um resultado mais hier\u00e1rquico. Mas a consulta <em>poderia<\/em> ser modificado com um <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/current\/n1ql\/n1ql-language-reference\/from.html#concept_rnt_zfk_np__unnest\"><code>IN\u00daTIL<\/code><\/a> para achatar os resultados, se necess\u00e1rio. <code>IN\u00daTIL<\/code> \u00e9 um <em>uni\u00e3o intra-documento<\/em>que \u00e9 um recurso necess\u00e1rio ao escrever SQL para JSON.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Em muitos bancos de dados de documentos que n\u00e3o sejam o Couchbase, voc\u00ea provavelmente teria que aprender uma API para criar consultas e n\u00e3o poderia aplicar sua experi\u00eancia com o tSQL para ajudar a aumentar a produtividade. N\u00e3o estou dizendo que a tradu\u00e7\u00e3o ser\u00e1 sempre um passeio no parque, mas ser\u00e1 relativamente f\u00e1cil em compara\u00e7\u00e3o com as alternativas. Se voc\u00ea estiver iniciando um <strong>novo<\/strong> ent\u00e3o voc\u00ea ficar\u00e1 feliz em saber que suas habilidades de escrita em SQL continuar\u00e3o a ser bem utilizadas!<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Ao escrever o C# para interagir com o N1QL, \u00e9 importante conhecer alguns conceitos-chave.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p><strong>Consist\u00eancia de varredura<\/strong>. Ao executar uma consulta N1QL, h\u00e1 v\u00e1rias op\u00e7\u00f5es de consist\u00eancia de varredura. A consist\u00eancia da varredura define como a consulta N1QL deve se comportar em rela\u00e7\u00e3o \u00e0 indexa\u00e7\u00e3o. O comportamento padr\u00e3o \u00e9 \"Not Bounded\", que oferece o melhor desempenho. No outro extremo do espectro est\u00e1 \"RequestPlus\", que oferece a melhor consist\u00eancia. H\u00e1 tamb\u00e9m o \"AtPlus\", que \u00e9 um bom meio-termo, mas exige um pouco mais de trabalho. I <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/new-to-couchbase-4.5-atplus\/\">escreveu no blog sobre consist\u00eancia de varredura<\/a> em junho, e vale a pena revis\u00e1-lo antes de come\u00e7ar a escrever N1QL em .NET.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p><strong>Parametriza\u00e7\u00e3o<\/strong>. Se voc\u00ea estiver criando consultas N1QL, \u00e9 importante <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/4.5\/sdk\/dotnet\/n1ql-queries-with-sdk.html?utm_source=blogs&amp;utm_medium=link&amp;utm_campaign=blogs\">usar parametriza\u00e7\u00e3o<\/a> para evitar inje\u00e7\u00e3o de SQL. H\u00e1 duas op\u00e7\u00f5es no N1QL: par\u00e2metros posicionais (numerados) e par\u00e2metros nomeados.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Aqui est\u00e1 um exemplo de consist\u00eancia de varredura e parametriza\u00e7\u00e3o usadas no C#:<\/p>\n<\/div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight decode:true\"><code class=\"language-C#\">var query = QueryRequest.Create(n1ql);\r\nconsulta.ScanConsistency(ScanConsistency.RequestPlus);\r\nquery.AddNamedParameter(\"userId\", id);\r\nvar result = _bucket.Query(query);<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"paragraph\">\n<p>N\u00e3o vou me aprofundar no <a href=\"https:\/\/docs.couchbase.com\/server\/6.0\/n1ql\/n1ql-language-reference\/index.html\">Linguagem de consulta N1QL<\/a> mais do que isso, porque esse \u00e9 um t\u00f3pico muito profundo. Mas voc\u00ea pode <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/products\/n1ql\/\">confira os conceitos b\u00e1sicos do N1QL<\/a> e <a href=\"https:\/\/query.pub.couchbase.com\/tutorial\/#1\">Comece a usar o tutorial interativo do N1QL<\/a>.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_sql_stored_procedures\">Procedimentos armazenados em SQL<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>N\u00e3o h\u00e1 equivalente aos procedimentos armazenados (sprocs) no Couchbase. Se voc\u00ea ainda n\u00e3o tiver uma camada de servi\u00e7o e estiver usando sprocs para compartilhar alguma l\u00f3gica entre dom\u00ednios, recomendo que crie uma camada de servi\u00e7o e mova a l\u00f3gica para l\u00e1.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Na verdade, eu n\u00e3o tinha certeza se os sprocs pertenciam \u00e0 parte 2 ou \u00e0 parte 3 desta s\u00e9rie do blog. Camadas t\u00edpicas em um aplicativo corporativo:<\/p>\n<\/div>\n<div class=\"ulist\">\n<ul>\n<li>Camada da Web (UI - Angular\/React\/Tradicional ASP.NET MVC)<\/li>\n<li>Camada de servi\u00e7o (ASP.NET WebApi)<\/li>\n<li>Banco de dados<\/li>\n<\/ul>\n<\/div>\n<div class=\"paragraph\">\n<p>Os sprocs vivem no banco de dados, mas cont\u00eam l\u00f3gica. A camada de servi\u00e7o tamb\u00e9m cont\u00e9m l\u00f3gica comercial. Ent\u00e3o, eles contam como dados ou funcionalidade?<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Fiz uma pesquisa de opini\u00e3o no Twitter para decidir.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p><span class=\"image\"><img decoding=\"async\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/02\/047_01_twitter_sproc_poll.png\" alt=\"Twitter straw poll on Stored Procedures\" \/><\/span><\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Mas minha recomenda\u00e7\u00e3o \u00e9 que, se voc\u00ea j\u00e1 tiver uma camada de servi\u00e7o, mova a l\u00f3gica do sproc para ela. Se voc\u00ea n\u00e3o tiver uma camada de servi\u00e7o, crie uma. Isso ficar\u00e1 entre o banco de dados e a interface do usu\u00e1rio.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>No c\u00f3digo-fonte desta s\u00e9rie, criei um \u00fanico procedimento armazenado.<\/p>\n<\/div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight decode:true\"><code class=\"language-SQL\">CREATE PROCEDURE SP_SEARCH_SHOPPING_CART_BY_NAME\r\n\t@searchString NVARCHAR(50)\r\nAS\r\nBEGIN\r\n\tSELECT c.Id, c.[User], c.DateCreated\r\n\tFROM ShoppingCart c\r\n\tWHERE c.[User] LIKE '%' + @searchString + '%'\r\nEND\r\nIR<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"paragraph\">\n<p>Esse sproc pode ser executado a partir do Entity Framework da seguinte forma:<\/p>\n<\/div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight decode:true\"><code class=\"language-C#\">public List SearchForCartsByUserName(string searchString)\r\n{\r\n    var cmd = _context.Database.Connection.CreateCommand();\r\n    cmd.CommandText = \"SP_SEARCH_SHOPPING_CART_BY_NAME @searchString\";\r\n    cmd.Parameters.Add(new SqlParameter(\"@searchString\", searchString));\r\n    _context.Database.Connection.Open();\r\n    var reader = cmd.ExecuteReader();\r\n\r\n    var carts = ((IObjectContextAdapter) _context)\r\n        .ObjectContext\r\n        .Translate(reader, \"ShoppingCarts\", MergeOption.AppendOnly);\r\n\r\n    var result = carts.ToList();\r\n    _context.Database.Connection.Close();\r\n    return result;\r\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"paragraph\">\n<p><em>A prop\u00f3sito, esse c\u00f3digo sproc do Entity Framework \u00e9 feio. Talvez eu tenha feito isso errado? N\u00e3o estou tentando difamar o EF, mas, em geral, n\u00e3o usei muito OR\/Ms e sprocs juntos em minha carreira. Certamente, um trecho de c\u00f3digo ADO.NET ou Dapper seria mais curto e mais limpo.<\/em><\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Esse \u00e9 um sproc muito simples, mas introduz uma funcionalidade b\u00e1sica de pesquisa. Os benef\u00edcios desse sproc:<\/p>\n<\/div>\n<div class=\"ulist\">\n<ul>\n<li><strong>Reutiliza\u00e7\u00e3o:<\/strong> O mesmo sproc pode ser reutilizado entre diferentes aplicativos<\/li>\n<li><strong>Abstra\u00e7\u00e3o:<\/strong> A implementa\u00e7\u00e3o do sproc pode ser alterada ou aprimorada. Nesse caso, um <code>GOSTO<\/code> poderia ser trocado por uma pesquisa de texto completo mais robusta.<\/li>\n<\/ul>\n<\/div>\n<div class=\"paragraph\">\n<p>Qualquer abordagem adotada com a introdu\u00e7\u00e3o de uma camada de servi\u00e7o deve proporcionar os mesmos benef\u00edcios. Criei um endpoint ASP.NET WebApi para substituir o sproc.<\/p>\n<\/div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight decode:true\"><code class=\"language-C#\">[HttpGet]\r\n[Route(\"api\/searchByName\/{searchString}\")]\r\npublic IHttpActionResult SearchByName(string searchString)\r\n{\r\n    var n1ql = @\"SELECT META(c).id, c.`user`\r\n        FROM `sqltocb` c\r\n        WHERE c.type = 'ShoppingCart'\r\n        AND c.`user` LIKE $searchString\";\r\n    var query = QueryRequest.Create(n1ql);\r\n    query.AddNamedParameter(\"searchString\", \"%\" + searchString + \"%\");\r\n    consulta.ScanConsistency(ScanConsistency.RequestPlus);\r\n    var results = _bucket.Query(query).Rows;\r\n\r\n    return Json(results);\r\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"paragraph\">\n<p><em>Observa\u00e7\u00e3o: por uma quest\u00e3o de simplicidade no c\u00f3digo de exemplo, esse endpoint realmente reside no mesmo projeto da Web, mas, na produ\u00e7\u00e3o, ele deve ser movido para seu pr\u00f3prio projeto e implantado separadamente.<\/em><\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Esse endpoint cont\u00e9m uma consulta N1QL de natureza semelhante ao sproc acima. Vamos ver se ela tem os mesmos benef\u00edcios:<\/p>\n<\/div>\n<div class=\"ulist\">\n<ul>\n<li><strong>Reutilizar?<\/strong> Sim. Esse endpoint pode ser implementado em seu pr\u00f3prio servidor e ser reutilizado de outros aplicativos.<\/li>\n<li><strong>Abstra\u00e7\u00e3o?<\/strong> Mais uma vez, sim. A implementa\u00e7\u00e3o usa o ing\u00eanuo <code>GOSTO<\/code> que poder\u00edamos melhorar mudando-a para usar <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/current\/sdk\/dotnet\/full-text-searching-with-sdk.html\">Recursos de pesquisa de texto completo do Couchbase<\/a> sem alterar a API.<\/li>\n<\/ul>\n<\/div>\n<div class=\"paragraph\">\n<p>Em vez de chamar um sproc por meio do Entity Framework, esse ponto de extremidade seria chamado via HTTP. Aqui est\u00e1 um exemplo que usa a biblioteca RestSharp:<\/p>\n<\/div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight decode:true\"><code class=\"language-C#\">public List SearchForCartsByUserName(string searchString)\r\n{\r\n    \/\/ normalmente haveria autentica\u00e7\u00e3o\/autoriza\u00e7\u00e3o com uma chamada REST como esta\r\n    var client = new RestClient(_baseUrl);\r\n    var request = new RestRequest(\"\/api\/searchByName\/\" + searchString);\r\n    request.AddHeader(\"Accept\", \"application\/json\");\r\n    var response = client.Execute&lt;List&gt;(request);\r\n    return response.Data;\r\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"paragraph\">\n<p>Se estiver criando um novo projeto, recomendo que crie uma camada de servi\u00e7o com a expectativa de que ela seja usada em toda a empresa. Isso permite que voc\u00ea tenha o mesmo \"c\u00f3digo compartilhado\" que os sprocs normalmente forneceriam sem colocar esse c\u00f3digo no banco de dados.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Isso tamb\u00e9m se aplica ao SQL Server <strong>fun\u00e7\u00f5es, tipos definidos pelo usu\u00e1rio, regras, objetos CLR definidos pelo usu\u00e1rio<\/strong>.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p><em>Observa\u00e7\u00e3o: o exemplo de sproc acima \u00e9 um <code>SELECIONAR<\/code> apenas para manter o exemplo simples. Nesse caso, voc\u00ea poderia criar uma visualiza\u00e7\u00e3o do MapReduce (que ser\u00e1 discutida abaixo). No entanto, uma visualiza\u00e7\u00e3o do MapReduce n\u00e3o pode alterar documentos, portanto, uma abordagem de camada de servi\u00e7o \u00e9 uma solu\u00e7\u00e3o geral melhor para substituir os sprocs.<\/em><\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_sql_triggers\">Acionadores SQL<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Se os sprocs ainda n\u00e3o foram controversos o suficiente, basta mencionar os acionadores em uma conversa. Assim como acontece com os procedimentos armazenados, geralmente recomendo que voc\u00ea mova a l\u00f3gica do acionador para a camada de servi\u00e7o, longe do banco de dados. Se o seu projeto de software depende de muitos acionadores, ou de acionadores complexos, ou de muitos acionadores complexos, talvez seja melhor esperar por outro projeto para tentar usar o Couchbase Server.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Dito isso, h\u00e1 algumas coisas de ponta que est\u00e3o sendo trabalhadas e que podem ser mais ou menos equivalentes aos acionadores. Se estiver interessado nisso, entre em contato comigo e tamb\u00e9m fique atento a <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/\">Blog do Couchbase<\/a> para obter as informa\u00e7\u00f5es mais recentes.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_views\">Visualiza\u00e7\u00f5es<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>No SQL Server, as visualiza\u00e7\u00f5es s\u00e3o uma forma de armazenar consultas complexas no servidor, al\u00e9m de proporcionar alguns benef\u00edcios de desempenho. No Couchbase, as visualiza\u00e7\u00f5es de mapa\/reprodu\u00e7\u00e3o t\u00eam fornecido funcionalidade semelhante h\u00e1 algum tempo. Na maioria das vezes, a funcionalidade fornecida pelas visualiza\u00e7\u00f5es pode ser fornecida de forma mais expressiva com o N1QL. No entanto, as visualiza\u00e7\u00f5es n\u00e3o est\u00e3o desaparecendo e, \u00e0s vezes, h\u00e1 benef\u00edcios em us\u00e1-las.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>As exibi\u00e7\u00f5es de mapa\/redu\u00e7\u00e3o podem ser definidas e armazenadas no cluster do Couchbase. Para cri\u00e1-las, voc\u00ea define uma fun\u00e7\u00e3o \"map\" (com JavaScript) e, opcionalmente, uma fun\u00e7\u00e3o \"reduce\" (tamb\u00e9m em JavaScript).<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Na interface do usu\u00e1rio do Console do Couchbase, v\u00e1 para \u00cdndices \u2192 Visualiza\u00e7\u00f5es \u2192 Criar visualiza\u00e7\u00e3o. Crie um documento de design e crie uma visualiza\u00e7\u00e3o dentro desse documento de design.<\/p>\n<\/div>\n<div class=\"imageblock\">\n<div class=\"content\"><img decoding=\"async\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/02\/047_01_Couchbase_View_editor.png\" alt=\"Editing a Map\/Reduce view in Couchbase\" \/><\/div>\n<div class=\"title\">Figura 1. Captura de tela do editor de visualiza\u00e7\u00e3o Map\/Reduce no Console do Couchbase mais recente<\/div>\n<\/div>\n<div class=\"paragraph\">\n<p>No centro est\u00e1 o c\u00f3digo Map\/Reduce no qual voc\u00ea est\u00e1 trabalhando. Um documento de amostra e seus metadados tamb\u00e9m s\u00e3o mostrados para ajud\u00e1-lo visualmente e, na parte inferior, voc\u00ea tem algumas op\u00e7\u00f5es para executar sua visualiza\u00e7\u00e3o.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Para obter detalhes completos sobre como as visualiza\u00e7\u00f5es funcionam, consulte o <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/current\/sdk\/dotnet\/view-queries-with-sdk.html\">Documenta\u00e7\u00e3o das visualiza\u00e7\u00f5es do MapReduce<\/a>.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Como um exemplo r\u00e1pido, quero criar uma exibi\u00e7\u00e3o que liste apenas as pessoas com idade superior a 21 anos.<\/p>\n<\/div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight decode:true\"><code class=\"language-JavaScript\">function (doc, meta) {\r\n  if(doc.age &gt; 21) {\r\n  \temit(meta.id, doc.name);\r\n  }\r\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"paragraph\">\n<p>Essa exibi\u00e7\u00e3o emitiria a chave do documento e o valor do campo \"name\". Se meu compartimento contivesse os seguintes documentos:<\/p>\n<\/div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight decode:true\"><code class=\"language-JavaScript\">foo1 {\"age\":17, \"name\": \"Carmella Albert\"}\r\nfoo2 {\"age\":25, \"name\": \"Lara Salinas\"}\r\nfoo3 {\"age\":35, \"name\": \"Teresa Johns\"}<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"paragraph\">\n<p>Em seguida, os resultados da exibi\u00e7\u00e3o seriam semelhantes:<\/p>\n<\/div>\n<table class=\"tableblock frame-all grid-all spread\">\n<colgroup>\n<col style=\"width: 50%\" \/>\n<col style=\"width: 50%\" \/> <\/colgroup>\n<thead>\n<tr>\n<th class=\"tableblock halign-left valign-top\">Chave<\/th>\n<th class=\"tableblock halign-left valign-top\">Valor<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">\"foo2\"<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">\"Lara Salinas\"<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">\"foo3\"<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">\"Teresa Johns\"<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"paragraph\">\n<p>Os resultados dessas exibi\u00e7\u00f5es s\u00e3o atualizados automaticamente em um intervalo e tamb\u00e9m s\u00e3o atualizados de forma incremental \u00e0 medida que os documentos sofrem muta\u00e7\u00e3o. Isso significa que, por padr\u00e3o, os resultados das exibi\u00e7\u00f5es s\u00e3o <strong>eventualmente<\/strong> consistente com os documentos reais. Como desenvolvedor, voc\u00ea pode <a href=\"https:\/\/docs.couchbase.com\/server\/current\/learn\/architecture-overview.html\">especificar o n\u00edvel de consist\u00eancia<\/a> (ou estanqueidade) que voc\u00ea deseja. Isso ter\u00e1 um impacto no desempenho.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>As visualiza\u00e7\u00f5es de mapa\/reprodu\u00e7\u00e3o podem ser muito \u00fateis quando voc\u00ea tem uma l\u00f3gica muito complexa que \u00e9 mais f\u00e1cil de escrever em JavaScript do que em N1QL. Tamb\u00e9m pode haver benef\u00edcios de desempenho quando se est\u00e1 trabalhando com um sistema que exige muita grava\u00e7\u00e3o.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>As visualiza\u00e7\u00f5es podem ser acessadas a partir do .NET usando <code>Consulta<\/code>.<\/p>\n<\/div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight decode:true\"><code class=\"language-C#\">var query = new ViewQuery().From(\"viewdesigndocument\", \"viewwname\").Limit(10);\r\nvar people = bucket.Query(query);\r\nforeach (var person in people.Rows)\r\n    Console.WriteLine(landmark.Key);<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"paragraph\">\n<p>Como alternativa, voc\u00ea pode criar consultas N1QL em vez de usar visualiza\u00e7\u00f5es. Em muitos casos, o N1QL ser\u00e1 mais f\u00e1cil de escrever, e a diferen\u00e7a de desempenho ser\u00e1 insignificante. Ao contr\u00e1rio das visualiza\u00e7\u00f5es, as consultas N1QL residiriam na camada de servi\u00e7o. Atualmente, n\u00e3o h\u00e1 como armazenar uma \"visualiza\u00e7\u00e3o N1QL\" no cluster do Couchbase Server.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_serialization_deserialization\">Serializa\u00e7\u00e3o\/desserializa\u00e7\u00e3o<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Se voc\u00ea estiver usando N1QL, visualiza\u00e7\u00f5es ou opera\u00e7\u00f5es de chave\/valor, \u00e9 importante considerar como o JSON \u00e9 serializado e desserializado.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>O SDK do .NET usa <a href=\"https:\/\/www.newtonsoft.com\/json\">Newtonson JSON.NET<\/a>. Se voc\u00ea estiver familiarizado com essa ferramenta (e quem entre os desenvolvedores de .NET n\u00e3o est\u00e1), lembre-se de que voc\u00ea pode usar os mesmos atributos (como <a href=\"https:\/\/www.newtonsoft.com\/json\/help\/html\/SerializationAttributes.htm\">JsonProperty, JsonConverter<\/a>etc.). Em alguns casos extremos, pode ser \u00fatil criar seu pr\u00f3prio serializador personalizado, o que \u00e9 poss\u00edvel com o Couchbase .NET SDK. D\u00ea uma olhada no <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/current\/sdk\/nonjson.html?utm_source=blogs&amp;utm_medium=link&amp;utm_campaign=blogs\">documenta\u00e7\u00e3o sobre serializa\u00e7\u00e3o e documentos n\u00e3o JSON<\/a> para obter mais informa\u00e7\u00f5es.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_security\">Seguran\u00e7a<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>O Couchbase tem <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/current\/security\/concepts-rba.html?utm_source=blogs&amp;utm_medium=link&amp;utm_campaign=blogs\">controle de acesso baseado em fun\u00e7\u00e3o (RBAC)<\/a> para administradores.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>O Couchbase pode se integrar ao LDAP para gerenciar os administradores do Couchbase e atribuir fun\u00e7\u00f5es aos usu\u00e1rios. O Couchbase tamb\u00e9m pode criar internamente usu\u00e1rios somente leitura.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>H\u00e1 algumas mudan\u00e7as e melhorias mais robustas chegando ao sistema RBAC do Couchbase, portanto, fique atento. Na verdade, eu recomendaria que voc\u00ea come\u00e7asse a <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/introducing-developer-builds\/\">verificando as compila\u00e7\u00f5es mensais para desenvolvedores<\/a>Espero ver alguns aprimoramentos e recursos interessantes nessa \u00e1rea em breve!<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_concurrency\">Concorr\u00eancia<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>A simultaneidade \u00e9 algo com que voc\u00ea precisa lidar com frequ\u00eancia, especialmente em um aplicativo da Web. V\u00e1rios usu\u00e1rios podem estar realizando a\u00e7\u00f5es que resultam na altera\u00e7\u00e3o do mesmo documento ao mesmo tempo.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>O SQL Server usa <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/optimistic-or-pessimistic-locking-which-one-should-you-pick\/\">bloqueio pessimista<\/a> por padr\u00e3o. Isso significa que o SQL Server espera que as linhas estejam em conten\u00e7\u00e3o e, portanto, age de forma defensiva. Esse \u00e9 um padr\u00e3o sensato para bancos de dados relacionais porque os dados desnormalizados est\u00e3o espalhados por v\u00e1rias tabelas e v\u00e1rias linhas. O SQL Server tem a capacidade de usar <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/optimistic-or-pessimistic-locking-which-one-should-you-pick\/\">bloqueio otimista<\/a> tamb\u00e9m, por meio de uma variedade de <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/ms173763.aspx\">n\u00edveis de transa\u00e7\u00e3o<\/a>.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>O Couchbase tamb\u00e9m oferece duas op\u00e7\u00f5es para lidar com a concorr\u00eancia: otimista e pessimista.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p><strong>Otimista<\/strong>. Isso \u00e9 chamado de \"otimista\" porque funciona melhor quando \u00e9 improv\u00e1vel que um documento esteja em conten\u00e7\u00e3o com muita frequ\u00eancia. Voc\u00ea est\u00e1 fazendo uma suposi\u00e7\u00e3o otimista. No Couchbase, isso \u00e9 feito com <a href=\"https:\/\/docs.couchbase.com\/dotnet-sdk\/current\/howtos\/concurrent-document-mutations.html\">CAS (Compare and Swap)<\/a>. Quando voc\u00ea recupera um documento, ele vem com metadados, incluindo um valor CAS (que \u00e9 apenas um n\u00famero). Quando voc\u00ea for atualizar esse documento, poder\u00e1 fornecer o valor CAS. Se os valores corresponderem, ent\u00e3o seu otimismo valeu a pena e as altera\u00e7\u00f5es ser\u00e3o salvas. Se n\u00e3o corresponderem, a opera\u00e7\u00e3o falhar\u00e1 e voc\u00ea ter\u00e1 de lidar com isso (uma mesclagem, uma mensagem de erro etc.). <em>Se voc\u00ea n\u00e3o fornecer um valor CAS, as altera\u00e7\u00f5es ser\u00e3o salvas de qualquer maneira.<\/em><\/p>\n<\/div>\n<div class=\"paragraph\">\n<p><strong>Pessimista<\/strong>. Isso \u00e9 chamado de \"pessimista\" porque funciona melhor quando voc\u00ea sabe que um documento sofrer\u00e1 muitas muta\u00e7\u00f5es. Voc\u00ea est\u00e1 fazendo uma suposi\u00e7\u00e3o pessimista e est\u00e1 bloqueando o documento \u00e0 for\u00e7a. Se voc\u00ea usar <code>GetAndLock<\/code> no .NET SDK, o documento ser\u00e1 bloqueado, o que significa que n\u00e3o poder\u00e1 ser modificado. Os documentos s\u00e3o bloqueados por um per\u00edodo m\u00e1ximo de 15 segundos. Voc\u00ea pode definir um valor menor. Tamb\u00e9m \u00e9 poss\u00edvel desbloquear explicitamente um documento, mas \u00e9 preciso controlar o valor CAS para fazer isso.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Para obter mais detalhes, consulte a documenta\u00e7\u00e3o sobre <a href=\"https:\/\/docs.couchbase.com\/dotnet-sdk\/current\/concurrent-mutations-cluster.html\">Muta\u00e7\u00f5es simult\u00e2neas de documentos<\/a>.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_autonumber\">N\u00famero autom\u00e1tico<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Atualmente, o Couchbase Server n\u00e3o oferece nenhum tipo de gera\u00e7\u00e3o autom\u00e1tica de chaves ou numera\u00e7\u00e3o sequencial de chaves.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>No entanto, voc\u00ea pode <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/current\/sdk\/core-operations.html\">usar o <strong>Balc\u00e3o<\/strong> recurso<\/a> para fazer algo semelhante. A ideia \u00e9 que um documento seja reservado como um documento contador especial. Esse documento pode ser incrementado como uma opera\u00e7\u00e3o at\u00f4mica, e o n\u00famero pode ser usado como uma chave parcial ou total do novo documento que est\u00e1 sendo criado.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Ratnopam Chakrabarti, um desenvolvedor da Ericsson, escreveu recentemente um <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/using-autonumber-in-couchbase\/\">postagem de blog de convidado sobre como criar chaves numeradas sequencialmente com o Couchbase Server<\/a>. Seu exemplo est\u00e1 em Java, mas \u00e9 f\u00e1cil de seguir, portanto, n\u00e3o repetirei seu exemplo aqui.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_or_ms_and_odms\">OR\/Ms e ODMs<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Se estiver usando o SQL Server, talvez esteja familiarizado com os mapeadores objeto-relacionais (OR\/Ms). Entity Framework, NHibernate, Linq2SQL e muitos outros s\u00e3o OR\/Ms. Os OR\/Ms tentam preencher a lacuna entre os dados estruturados em C# e os dados normalizados em bancos de dados relacionais. Normalmente, eles tamb\u00e9m oferecem outros recursos, como provedores Linq, unidade de trabalho etc. Acredito que os OR\/Ms seguem a regra 80\/20. Eles podem ser muito \u00fateis 80% do tempo, e uma dor de cabe\u00e7a nos outros 20%.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Para bancos de dados de documentos, h\u00e1 uma incompatibilidade de imped\u00e2ncia muito menor, pois os objetos C# podem ser serializados\/desserializados para JSON e n\u00e3o precisam ser divididos em um conjunto normalizado de tabelas.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>No entanto, as outras funcionalidades que os OR\/Ms oferecem ainda podem ser \u00fateis em bancos de dados de documentos. A ferramenta equivalente \u00e9 chamada de ODM (Object Document Model). Essas ferramentas ajudam voc\u00ea a definir um conjunto de classes para mapear para documentos. Ottoman e Linq2Couchbase s\u00e3o ODMs populares para o Couchbase, para Node e .NET, respectivamente.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p><a href=\"https:\/\/github.com\/couchbaselabs\/Linq2Couchbase\">Linq2Couchbase<\/a> tem um provedor Linq. N\u00e3o \u00e9 um projeto oficialmente suportado (ainda), mas \u00e9 um dos provedores Linq mais completos que j\u00e1 usei e \u00e9 usado em produ\u00e7\u00e3o pelos clientes do Couchbase.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Abaixo est\u00e1 um exemplo da documenta\u00e7\u00e3o do Linq2Couchbase que deve parecer familiar para os usu\u00e1rios do Entity Framework e do NHibernate.Linq:<\/p>\n<\/div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight decode:true\"><code class=\"language-C#\">var context = new BucketContext(ClusterHelper.GetBucket(\"travel-sample\"));\r\nvar query = (from a in context.Query()\r\n             where a.Country == \"United Kingdom\"\r\n             select a).\r\n             Take(10);<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"paragraph\">\n<p>Tamb\u00e9m usei o Linq2Couchbase no c\u00f3digo de amostra para esta s\u00e9rie do blog. Aqui est\u00e1 um exemplo para carrinhos de compras:<\/p>\n<\/div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight decode:true\"><code class=\"language-C#\">var query = from c in _context.Query()\r\n    where c.Type == \"ShoppingCart\" \/\/ poderia usar o atributo DocumentFilter em vez desse Where\r\n    orderby c.DateCreated descendente\r\n    select new {Cart = c, Id = N1QlFunctions.Meta(c).Id};\r\nvar results = query.ScanConsistency(ScanConsistency.RequestPlus)\r\n    .Take(10)\r\n    .ToList();<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"paragraph\">\n<p>Al\u00e9m de ser um excelente provedor de Linq, o Linq2Couchbase tamb\u00e9m tem um recurso experimental de controle de altera\u00e7\u00f5es. Vale a pena dar uma olhada. Brant Burnett \u00e9 um dos principais colaboradores do projeto e tamb\u00e9m \u00e9 um <a href=\"https:\/\/developer.couchbase.com\/experts-and-champions?utm_source=blogs&amp;utm_medium=link&amp;utm_campaign=blogs\">Especialista em Couchbase<\/a>. Ele apresentou uma sess\u00e3o no Couchbase Connect 2016 chamada <a href=\"https:\/\/www.youtube.com\/watch?v=X__mC2FArp4\">LINQing para dados: Facilitando a transi\u00e7\u00e3o do SQL<\/a>.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>[youtube https:\/\/www.youtube.com\/watch?v=X__mC2FArp4&amp;w=560&amp;h=315]<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_transactions\">Transa\u00e7\u00f5es<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>J\u00e1 abordei o bloqueio pessimista e otimista para transa\u00e7\u00f5es em um \u00fanico documento. Por causa disso, podemos dizer que o Couchbase suporta transa\u00e7\u00f5es ACID em um n\u00edvel por documento. No momento, o Couchbase n\u00e3o oferece suporte a transa\u00e7\u00f5es ACID entre v\u00e1rios documentos.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Pensando no <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/moving-from-sql-server-to-couchbase-part-1-data-modeling\/\">Primeira postagem no blog sobre modelagem de dados<\/a>Em compara\u00e7\u00e3o com um modelo relacional, a necessidade de transa\u00e7\u00f5es com v\u00e1rios documentos \u00e9 geralmente reduzida ou eliminada. Um conceito (como carrinho de compras) pode exigir linhas em v\u00e1rias tabelas em um modelo relacional, mas um \u00fanico modelo de documento no Couchbase.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Se voc\u00ea estiver seguindo um modelo referencial, como no exemplo de m\u00eddia social do <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/moving-from-sql-server-to-couchbase-part-1-data-modeling\/\">primeira postagem no blog<\/a>Se voc\u00ea n\u00e3o tiver um modelo de dados de dados, poder\u00e1 se preocupar com a falta de transa\u00e7\u00f5es. Isso destaca a import\u00e2ncia de pensar em seus casos de uso ao criar o modelo de dados. Se as transa\u00e7\u00f5es forem vitais para o seu caso de uso, o modelo de dados poder\u00e1 ser estruturado para acomod\u00e1-las. <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/forums\/\">Teremos prazer em ajud\u00e1-lo com isso, basta perguntar!<\/a><\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>O suporte a transa\u00e7\u00f5es de v\u00e1rios documentos poder\u00e1 ser oferecido no futuro se um n\u00famero suficiente de desenvolvedores e clientes do Couchbase solicitar ou precisar dele. Portanto, se voc\u00ea fizer o exerc\u00edcio de projetar um modelo de dados de banco de dados de documentos e as transa\u00e7\u00f5es forem <em>ainda<\/em> uma parte vital do seu projeto, ent\u00e3o o Couchbase pode n\u00e3o ser o melhor \"sistema de registro\" para pelo menos parte do seu projeto. O Couchbase ainda pode ser o melhor \"sistema de engajamento\", capaz de ajudar com dimensionamento, armazenamento em cache, desempenho e flexibilidade quando necess\u00e1rio.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p><em>Como observa\u00e7\u00e3o adicional, talvez valha a pena dar uma olhada no <a href=\"https:\/\/ndescribe.atlassian.net\/wiki\/display\/DOC\/Transactional+Documents\">NDescreva o projeto<\/a>pois inclui um SDK que funciona sobre o SDK do Couchbase e fornece um sistema de transa\u00e7\u00f5es. (Observe que essa n\u00e3o \u00e9 uma ferramenta com suporte oficial).<\/em><\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_ssis_ssas_ssrs\">SSIS, SSAS, SSRS<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Nem todo mundo usa o SQL Server Integration Services (SSIS), o SQL Server Analysis Services (SSAS) e o SQL Server Reporting Services (SSRS), mas esses s\u00e3o recursos poderosos que o SQL Server tem para integra\u00e7\u00e3o, gera\u00e7\u00e3o de relat\u00f3rios e an\u00e1lise.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>N\u00e3o posso lhe dar uma resposta gen\u00e9rica \"use X em vez de Y\" para esses casos, pois isso depende muito do seu caso de uso. Posso indicar algumas das ferramentas dispon\u00edveis para o Couchbase que giram em torno de processamento de dados, transforma\u00e7\u00e3o de dados, gera\u00e7\u00e3o de relat\u00f3rios e an\u00e1lise.<\/p>\n<\/div>\n<div class=\"ulist\">\n<ul>\n<li><strong>Kafka<\/strong> \u00e9 uma ferramenta de streaming de dados de c\u00f3digo aberto. Algumas das <a href=\"https:\/\/kafka.apache.org\/uses\">Casos de uso populares para o Kafka<\/a> incluem mensagens, rastreamento de atividades do site, m\u00e9tricas e muito mais.<\/li>\n<li><strong>Fa\u00edsca<\/strong> \u00e9 um mecanismo de processamento de dados, destinado ao processamento de dados em grande escala e ETL.<\/li>\n<li><strong>Hadoop<\/strong> \u00e9 uma estrutura de big data para armazenamento e processamento distribu\u00eddos.<\/li>\n<\/ul>\n<\/div>\n<div class=\"paragraph\">\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/pt\/bigdata\/\">O Couchbase tem conectores<\/a> que suportam cada uma dessas tr\u00eas ferramentas populares.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Finalmente, <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/4.5\/analytics\/introduction.html\"><strong>An\u00e1lise do Couchbase<\/strong> est\u00e1 atualmente em visualiza\u00e7\u00e3o para desenvolvedores<\/a>. Ele foi concebido como um mecanismo de gerenciamento de dados que \u00e9 executado paralelamente ao Couchbase Server. \u00c9 uma pr\u00e9via para desenvolvedores e ainda n\u00e3o \u00e9 recomendado para uso em produ\u00e7\u00e3o, mas voc\u00ea pode <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/downloads\/\">Fa\u00e7a o download do Couchbase Analytics e das extens\u00f5es do Kafka, Spark e Hadoop (clique na guia Extens\u00f5es) e experimente-os<\/a>.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_summary\">Resumo<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Abordamos a modelagem de dados, a migra\u00e7\u00e3o de dados e a migra\u00e7\u00e3o de aplicativos pelas lentes do SQL Server. Esse \u00e9 um bom ponto de partida para seu pr\u00f3ximo projeto e lhe dar\u00e1 algo em que pensar se estiver pensando em migrar.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>O <a href=\"https:\/\/developer.couchbase.com\/?utm_source=blogs&amp;utm_medium=link&amp;utm_campaign=blogs\">Portal do desenvolvedor do Couchbase<\/a> cont\u00e9m mais detalhes e informa\u00e7\u00f5es sobre todos os aspectos do Couchbase Server.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Gostaria de saber o que o Couchbase pode fazer para facilitar a sua transi\u00e7\u00e3o, quer voc\u00ea esteja migrando ou come\u00e7ando do zero. Perdi alguma coisa? Voc\u00ea tem alguma ferramenta ou sistema que recomenda? Tem alguma d\u00favida? D\u00ea uma olhada na se\u00e7\u00e3o <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/forums\/\">F\u00f3runs do Couchbase<\/a>Envie-me um e-mail para <a href=\"mailto:matthew.groves@couchbase.com\">matthew.groves@couchbase.com<\/a> ou me encontre em <a href=\"https:\/\/twitter.com\/mgroves\">Twitter @mgroves<\/a>.<\/p>\n<\/div>\n<\/div>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>Moving from SQL Server to Couchbase Part 3: App Migration In this series of blog posts, I\u2019m going to lay out the considerations when moving to a document database when you have a relational background. Specifically, Microsoft SQL Server as [&hellip;]<\/p>","protected":false},"author":71,"featured_media":2574,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1811,1814,1816,1819,1812],"tags":[1806,1556],"ppma_author":[8937],"class_list":["post-2708","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet","category-application-design","category-couchbase-server","category-data-modeling","category-n1ql-query","tag-entity-framework","tag-sql-server"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.9 (Yoast SEO v25.9) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Moving from SQL Server to Couchbase Part 3: App Migration<\/title>\n<meta name=\"description\" content=\"In this blog post series, I&#039;m laying out the considerations when moving from Microsoft SQL Server to Couchbase Server. This post is about app migration.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/pt\/moving-sql-server-couchbase-app-migration\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Moving from SQL Server to Couchbase Part 3: App Migration\" \/>\n<meta property=\"og:description\" content=\"In this blog post series, I&#039;m laying out the considerations when moving from Microsoft SQL Server to Couchbase Server. This post is about app migration.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pt\/moving-sql-server-couchbase-app-migration\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2017-03-07T17:51:19+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-09-12T09:19:18+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/geese-migration.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2048\" \/>\n\t<meta property=\"og:image:height\" content=\"949\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Matthew Groves\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@mgroves\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Matthew Groves\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"17 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/moving-sql-server-couchbase-app-migration\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/moving-sql-server-couchbase-app-migration\/\"},\"author\":{\"name\":\"Matthew Groves\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/3929663e372020321b0152dc4fa65a58\"},\"headline\":\"Moving from SQL Server to Couchbase Part 3: App Migration\",\"datePublished\":\"2017-03-07T17:51:19+00:00\",\"dateModified\":\"2024-09-12T09:19:18+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/moving-sql-server-couchbase-app-migration\/\"},\"wordCount\":3837,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/moving-sql-server-couchbase-app-migration\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/geese-migration.jpg\",\"keywords\":[\"Entity Framework\",\"SQL Server\"],\"articleSection\":[\".NET\",\"Application Design\",\"Couchbase Server\",\"Data Modeling\",\"SQL++ \/ N1QL Query\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/moving-sql-server-couchbase-app-migration\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/moving-sql-server-couchbase-app-migration\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/moving-sql-server-couchbase-app-migration\/\",\"name\":\"Moving from SQL Server to Couchbase Part 3: App Migration\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/moving-sql-server-couchbase-app-migration\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/moving-sql-server-couchbase-app-migration\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/geese-migration.jpg\",\"datePublished\":\"2017-03-07T17:51:19+00:00\",\"dateModified\":\"2024-09-12T09:19:18+00:00\",\"description\":\"In this blog post series, I'm laying out the considerations when moving from Microsoft SQL Server to Couchbase Server. This post is about app migration.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/moving-sql-server-couchbase-app-migration\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/moving-sql-server-couchbase-app-migration\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/moving-sql-server-couchbase-app-migration\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/geese-migration.jpg\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/geese-migration.jpg\",\"width\":2048,\"height\":949,\"caption\":\"Geese migration licensed through Creative Commons https:\/\/commons.wikimedia.org\/wiki\/File:BrantaLeucopsisMigration.jpg\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/moving-sql-server-couchbase-app-migration\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Moving from SQL Server to Couchbase Part 3: App Migration\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/3929663e372020321b0152dc4fa65a58\",\"name\":\"Matthew Groves\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/ba51e6aacc53995c323a634e4502ef54\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/70feb1b28a099ad0112b8d21fe1e81e1a4524beed3e20b7f107d5370e85a07ab?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/70feb1b28a099ad0112b8d21fe1e81e1a4524beed3e20b7f107d5370e85a07ab?s=96&d=mm&r=g\",\"caption\":\"Matthew Groves\"},\"description\":\"Matthew D. Groves is a guy who loves to code. It doesn't matter if it's C#, jQuery, or PHP: he'll submit pull requests for anything. He has been coding professionally ever since he wrote a QuickBASIC point-of-sale app for his parent's pizza shop back in the 90s. He currently works as a Senior Product Marketing Manager for Couchbase. His free time is spent with his family, watching the Reds, and getting involved in the developer community. He is the author of AOP in .NET, Pro Microservices in .NET, a Pluralsight author, and a Microsoft MVP.\",\"sameAs\":[\"https:\/\/crosscuttingconcerns.com\",\"https:\/\/x.com\/mgroves\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/pt\/author\/matthew-groves\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Mudan\u00e7a do SQL Server para o Couchbase Parte 3: Migra\u00e7\u00e3o de aplicativos","description":"In this blog post series, I'm laying out the considerations when moving from Microsoft SQL Server to Couchbase Server. This post is about app migration.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/pt\/moving-sql-server-couchbase-app-migration\/","og_locale":"pt_BR","og_type":"article","og_title":"Moving from SQL Server to Couchbase Part 3: App Migration","og_description":"In this blog post series, I'm laying out the considerations when moving from Microsoft SQL Server to Couchbase Server. This post is about app migration.","og_url":"https:\/\/www.couchbase.com\/blog\/pt\/moving-sql-server-couchbase-app-migration\/","og_site_name":"The Couchbase Blog","article_published_time":"2017-03-07T17:51:19+00:00","article_modified_time":"2024-09-12T09:19:18+00:00","og_image":[{"width":2048,"height":949,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/geese-migration.jpg","type":"image\/jpeg"}],"author":"Matthew Groves","twitter_card":"summary_large_image","twitter_creator":"@mgroves","twitter_misc":{"Written by":"Matthew Groves","Est. reading time":"17 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/moving-sql-server-couchbase-app-migration\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/moving-sql-server-couchbase-app-migration\/"},"author":{"name":"Matthew Groves","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/3929663e372020321b0152dc4fa65a58"},"headline":"Moving from SQL Server to Couchbase Part 3: App Migration","datePublished":"2017-03-07T17:51:19+00:00","dateModified":"2024-09-12T09:19:18+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/moving-sql-server-couchbase-app-migration\/"},"wordCount":3837,"commentCount":2,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/moving-sql-server-couchbase-app-migration\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/geese-migration.jpg","keywords":["Entity Framework","SQL Server"],"articleSection":[".NET","Application Design","Couchbase Server","Data Modeling","SQL++ \/ N1QL Query"],"inLanguage":"pt-BR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/moving-sql-server-couchbase-app-migration\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/moving-sql-server-couchbase-app-migration\/","url":"https:\/\/www.couchbase.com\/blog\/moving-sql-server-couchbase-app-migration\/","name":"Mudan\u00e7a do SQL Server para o Couchbase Parte 3: Migra\u00e7\u00e3o de aplicativos","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/moving-sql-server-couchbase-app-migration\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/moving-sql-server-couchbase-app-migration\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/geese-migration.jpg","datePublished":"2017-03-07T17:51:19+00:00","dateModified":"2024-09-12T09:19:18+00:00","description":"In this blog post series, I'm laying out the considerations when moving from Microsoft SQL Server to Couchbase Server. This post is about app migration.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/moving-sql-server-couchbase-app-migration\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/moving-sql-server-couchbase-app-migration\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/moving-sql-server-couchbase-app-migration\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/geese-migration.jpg","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/geese-migration.jpg","width":2048,"height":949,"caption":"Geese migration licensed through Creative Commons https:\/\/commons.wikimedia.org\/wiki\/File:BrantaLeucopsisMigration.jpg"},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/moving-sql-server-couchbase-app-migration\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Moving from SQL Server to Couchbase Part 3: App Migration"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"Blog do Couchbase","description":"Couchbase, o banco de dados NoSQL","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"pt-BR"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"Blog do Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/3929663e372020321b0152dc4fa65a58","name":"Matthew Groves","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/ba51e6aacc53995c323a634e4502ef54","url":"https:\/\/secure.gravatar.com\/avatar\/70feb1b28a099ad0112b8d21fe1e81e1a4524beed3e20b7f107d5370e85a07ab?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/70feb1b28a099ad0112b8d21fe1e81e1a4524beed3e20b7f107d5370e85a07ab?s=96&d=mm&r=g","caption":"Matthew Groves"},"description":"Matthew D. Groves \u00e9 um cara que adora programar. N\u00e3o importa se \u00e9 C#, jQuery ou PHP: ele enviar\u00e1 solicita\u00e7\u00f5es 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\u00eanior de marketing de produtos da Couchbase. Seu tempo livre \u00e9 passado com a fam\u00edlia, assistindo aos Reds e participando da comunidade de desenvolvedores. Ele \u00e9 autor de AOP in .NET, Pro Microservices in .NET, autor da Pluralsight e Microsoft MVP.","sameAs":["https:\/\/crosscuttingconcerns.com","https:\/\/x.com\/mgroves"],"url":"https:\/\/www.couchbase.com\/blog\/pt\/author\/matthew-groves\/"}]}},"authors":[{"term_id":8937,"user_id":71,"is_guest":0,"slug":"matthew-groves","display_name":"Matthew Groves","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/70feb1b28a099ad0112b8d21fe1e81e1a4524beed3e20b7f107d5370e85a07ab?s=96&d=mm&r=g","author_category":"","last_name":"Groves","first_name":"Matthew","job_title":"","user_url":"https:\/\/crosscuttingconcerns.com","description":"Matthew D. Groves \u00e9 um cara que adora programar.  N\u00e3o importa se \u00e9 C#, jQuery ou PHP: ele enviar\u00e1 solicita\u00e7\u00f5es 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\u00eanior de marketing de produtos da Couchbase. Seu tempo livre \u00e9 passado com a fam\u00edlia, assistindo aos Reds e participando da comunidade de desenvolvedores.  Ele \u00e9 autor de AOP in .NET, Pro Microservices in .NET, autor da Pluralsight e Microsoft MVP."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/2708","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/users\/71"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=2708"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/2708\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media\/2574"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=2708"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=2708"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=2708"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=2708"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}