{"id":10832,"date":"2021-03-02T00:27:36","date_gmt":"2021-03-02T08:27:36","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=10832"},"modified":"2025-06-13T16:46:30","modified_gmt":"2025-06-13T23:46:30","slug":"sql-to-nosql-automated-migration","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/sql-to-nosql-automated-migration\/","title":{"rendered":"SQL to NoSQL: Automated Migration"},"content":{"rendered":"<div class=\"paragraph\">\n<p>SQL to NoSQL migration seems like a contradiction, but thanks to advances and innovations in Couchbase Server\u2019s NoSQL database, it\u2019s becoming easier.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>In this post, I\u2019ll introduce you to a tool called <a href=\"https:\/\/github.com\/mgroves\/SqlServerToCouchbase\">SqlServerToCouchbase<\/a>, an open-source attempt at an automated tool to help you &#8220;convert&#8221; a Microsoft SQL Server database into a Couchbase Server database. Along the way, we\u2019ll look at data migration strategies, comparisons between SQL and NoSQL terms, and trade-offs between the two types of databases. <strong>Even if you aren\u2019t using SQL Server or Couchbase Server<\/strong>, this article can help you in your conversion efforts.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Before starting, keep in mind that moving between any two databases (SQL to NoSQL <em>or<\/em> SQL to SQL) is much like translating between two languages. There are automations like Babelfish, Google Translate, and so on. These are very helpful tools for getting started, but aren\u2019t substitutes for (eventually) immersing yourself in the language.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<blockquote class=\"twitter-tweet\" data-width=\"550\" data-dnt=\"true\">\n<p lang=\"qme\" dir=\"ltr\"><a href=\"https:\/\/twitter.com\/hashtag\/googletranslatefails?src=hash&amp;ref_src=twsrc%5Etfw\">#googletranslatefails<\/a> <a href=\"https:\/\/twitter.com\/hashtag\/overs%C3%A6ttelsesfejl?src=hash&amp;ref_src=twsrc%5Etfw\">#overs\u00e6ttelsesfejl<\/a> <a href=\"https:\/\/t.co\/SNNoGHBD1Q\">pic.twitter.com\/SNNoGHBD1Q<\/a><\/p>\n<p>&mdash; EgoLibris (@egolibris) <a href=\"https:\/\/twitter.com\/egolibris\/status\/864846974859849728?ref_src=twsrc%5Etfw\">May 17, 2017<\/a><\/p><\/blockquote>\n<p><script async src=\"https:\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script><\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Beyond the translation of syntax, there\u2019s also the idioms and culture that surrounds any technology. No automation tool can capture all of the nuance, but let\u2019s give it a try to see how far we can go.<\/p>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_strategies_to_migrate_data_from_sql_to_nosql\">Convert SQL to NoSQL: Data Migration Strategies<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>If you\u2019re considering migrating data from SQL Server to Couchbase (or any relational database to Couchbase), the first step is to come to agreement on your high-level goals and plans. There are multiple paths to take, and each trades-off risk, effort, and benefits. Here are a few examples for how to convert SQL to NoSQL:<\/p>\n<\/div>\n<div class=\"responsive-table\">\n<table class=\"tableblock frame-all grid-all spread\">\n<colgroup>\n<col style=\"width: 10%\" \/>\n<col style=\"width: 60%\" \/>\n<col style=\"width: 10%\" \/>\n<col style=\"width: 10%\" \/>\n<col style=\"width: 10%\" \/> <\/colgroup>\n<thead>\n<tr>\n<th class=\"tableblock halign-left valign-top\">Level<\/th>\n<th class=\"tableblock halign-left valign-top\">Description<\/th>\n<th class=\"tableblock halign-left valign-top\">Risk<\/th>\n<th class=\"tableblock halign-left valign-top\">Effort<\/th>\n<th class=\"tableblock halign-left valign-top\">Benefits<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">1<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\"><strong>Rewrite<\/strong>: No migration, write the whole thing over<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">5\/5<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">5\/5<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">\u2b50\u2b50\u2b50\u2b50\u2b50<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">2<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\"><strong>Redesign Schema<\/strong>: Keep your business logic, rewrite your data layer and schema, totally redesign your schema with a NoSQL-optimized model<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">4\/5<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">4\/5<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">\u2b50\u2b50\u2b50\u2b50<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">3<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\"><strong>Refactor First<\/strong>: Keep everything but refactor your data logic and RDBMS schema into a NoSQL-optimized model<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">4\/5<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">3\/5<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">\u2b50\u2b50\u2b50<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">4<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\"><strong>Optimize Later<\/strong>: Host your schema with as few changes as possible, get the application running on the new technology, refactor\/optimize the schema as necessary for performance<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">3\/5<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">4\/5<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">\u2b50\u2b50\u2b50<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">5<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\"><strong>Just Host It<\/strong>: Host your schema with as few changes as possible.<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">2\/5<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">2\/5<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">\u2b50\u2b50<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div class=\"paragraph\">\n<p>Historically, NoSQL databases have focused on &#8220;Level 1&#8221; rebuilding or greenfield projects. While that approach captures the most benefit from NoSQL from the beginning, rebuilds are always expensive and risky.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>However, Couchbase Server, along with new capabilities coming in Couchbase Server 7 (you can download <a href=\"https:\/\/www.couchbase.com\/downloads\/\">Couchbase 7 beta right now<\/a>), allows a level 5 (followed by level 4) approach that reduces the risk and cost of trying out NoSQL. You won\u2019t necessarily reap <strong>all<\/strong> the benefits of NoSQL right away, but getting started is easier than ever.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_convert_from_sql_to_nosql\">Convert SQL to NoSQL Query<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Most developers and database users are familiar with relational databases. Schemas, tables, rows and columns, SQL queries, ACID transactions. Couchbase\u2019s query language (N1QL) has long recognized that SQL is the <em>lingua franca<\/em> of databases. N1QL currently provides full SQL capabilities, including JOINs, robust indexing, aggregation, CTEs, and more. This makes it relatively straightforward for SQL developers to be productive even as newcomers to Couchbase\u2019s NoSQL offering.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p><strong>Tip<\/strong>: Check out <a href=\"https:\/\/www.techvalidate.com\/product-research\/couchbase\/charts\/2A1-8B3-4BC\">Why Developers Value Couchbase<\/a> and other independent research from TechValidate.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>What if most of the other relational concepts could be translated and converted as easily? Let\u2019s look at how SQL Server concepts could be mapped to Couchbase Server concepts.<\/p>\n<\/div>\n<div class=\"responsive-table\">\n<table class=\"tableblock frame-all grid-all spread\">\n<colgroup>\n<col style=\"width: 33.3333%\" \/>\n<col style=\"width: 33.3333%\" \/>\n<col style=\"width: 33.3334%\" \/> <\/colgroup>\n<thead>\n<tr>\n<th class=\"tableblock halign-left valign-top\">SQL Server<\/th>\n<th class=\"tableblock halign-left valign-top\">Couchbase Server<\/th>\n<th class=\"tableblock halign-left valign-top\">Notes<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">Server<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">Cluster<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">One of the primary benefits of NoSQL is scalability and high availability that clustering provides.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">Catalog\/Database<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">Bucket<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">Couchbase buckets also provide a built-in cache for improved performance<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">Schema<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">Scope<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">Schema is often just &#8220;dbo&#8221; in SQL Server, but not always.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">Table<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">Collection<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">Collections are more flexible: no pre-defined columns or constraints<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">Row<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">Document<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">JSON instead of flat data<\/p>\n<\/td>\n<\/tr>\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<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">N1QL is not &#8220;SQL-like&#8221;, it\u2019s a full SQL implementation with JSON extensions, sometimes called SQL++<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">Primary Key<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">Document Key<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">Primary keys must be unique per-table, document keys must be unique per collection<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">Index<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">Index<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">SQL: Indexes on column(s), Couchbase: Indexes on JSON field(s)<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div class=\"paragraph\">\n<p>With this mapping as a baseline, can we write a program to automatically convert the contents of a SQL Server database to a Couchbase Server database?<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>I believe we can get most of the way there, and I\u2019ve created an open-source project called <a href=\"https:\/\/github.com\/mgroves\/SqlServerToCouchbase\">SqlServerToCouchbase<\/a> to do just that.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_database_catalog_to_bucket\">Convert SQL Database to NoSQL\/Catalog to Bucket<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>I\u2019m going to use the <a href=\"https:\/\/docs.microsoft.com\/en-us\/sql\/samples\/adventureworks-install-configure#download-backup-files\">AdventureWorks<\/a> samples provided by Microsoft in SQL Server. I\u2019ll be migrating to a Couchbase 7 database (<a href=\"https:\/\/www.couchbase.com\/downloads\/\">currently in beta<\/a>, but will likely be RTM this year).<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p><strong>Note<\/strong>: I\u2019m using AdventureWorks2016 because that\u2019s what version of SQL Server I happen to have available. Most older and newer versions should work okay, but if you run into any problems, <a href=\"https:\/\/github.com\/mgroves\/SqlServerToCouchbase\">please create a GitHub issue<\/a>!<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p><span class=\"image\"><img decoding=\"async\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/02\/13002-sql-server-adventureworks.png\" alt=\"SQL Server with AdventureWorks\" \/><\/span><\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>You can create a bucket manually in Couchbase Server, or you can have the utility create the bucket for you automatically.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p><span class=\"image\"><img decoding=\"async\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/02\/13003-couchbase-adventureworks.png\" alt=\"AdventureWorks bucket in Couchbase\" \/><\/span><\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_schema_to_scope\">Schema to Scope<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>In SQL Server, a <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/framework\/data\/adonet\/sql\/ownership-and-user-schema-separation-in-sql-server\">schema<\/a> is like a &#8220;namespace&#8221; that allows you to group objects (like tables) together for organization\/security purposes. For example, AdventureWorks contains schemas like HumanResources, Person, Production, etc.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Many projects don\u2019t really use schema other than the default &#8220;dbo&#8221; schema. However, a schema might be used to group data for a specific microservice or a specific tenant in a multi-tenant app.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p><span class=\"image\"><img decoding=\"async\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/02\/13004-sql-server-schemas.png\" alt=\"SQL Server schemas\" \/><\/span><\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>In Couchbase 7, there is a very similar concept called <a href=\"https:\/\/docs.couchbase.com\/server\/7.0\/learn\/data\/scopes-and-collections.html\">&#8220;scope&#8221;<\/a>. It provides the same organization and security benefits for microservices or multi-tenancy.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p><span class=\"image\"><img decoding=\"async\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/02\/13005-couchbase-scopes.png\" alt=\"Couchbase scopes\" \/><\/span><\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Based on your preferences, the SqlServerToCouchbase utility can create scopes based on the schemas in SQL Server, or it can ignore them and put everything in a schema called &#8220;_default&#8221; (which is roughly equivalent to &#8220;dbo&#8221;). In the above example, I\u2019ve elected to create scopes for each AdventureWorks schema.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_table_to_collection\">Table to Collection<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>In SQL Server, a table is a strictly enforced relation (hence &#8220;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Relational_model\">relational<\/a>&#8221; database) that organizes data together.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p><span class=\"image\"><img decoding=\"async\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/02\/13006-sql-server-table.png\" alt=\"SQL Server table\" \/><\/span><\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>In Couchbase, there is no strictly enforced relation, but in Couchbase 7, there is a concept of a <a href=\"https:\/\/docs.couchbase.com\/server\/7.0\/learn\/data\/scopes-and-collections.html\">&#8220;collection&#8221;<\/a>. While this will be unable to enforce any constraints on the data (other than a unique document key, analogous to a primary key), it can still provide the same level of data organization.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>The SqlServerToCouchbase utility will create a collection for each table that it finds. If you elected to create scopes in the previous step, those collections will be placed inside of the appropriate scope.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p><span class=\"image\"><img decoding=\"async\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/02\/13007-couchbase-collection.png\" alt=\"Couchbase collection\" \/><\/span><\/p>\n<\/div>\n<div class=\"paragraph\">\n<p><strong>Tip<\/strong>: Table names in SQL Server are allowed to be much longer than collection names in Couchbase Server. So, if you are migrating a database with long table names, you will have to explicitly provide a new, shorter collection name.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_what_about_converting_the_sql_query\">What about converting the SQL query?<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>The SqlServerToCouchbase utility will not (yet) convert your SQL Server queries for you, but here\u2019s a comparison between a SQL Server query of AdventureWorks and the equivalent query of the converted AdventureWorks database in Couchbase.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>The below tSQL query (taken from <a href=\"https:\/\/docs.microsoft.com\/en-us\/sql\/t-sql\/queries\/from-transact-sql?view=sql-server-ver15#i-using-a-derived-table\">Microsoft documentation<\/a>) is designed to &#8220;return the first and last names of all employees and the cities in which they live&#8221;.<\/p>\n<\/div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight decode:true\"><code class=\"language-SQL\" data-lang=\"SQL\">SELECT RTRIM(p.FirstName) + ' ' + LTRIM(p.LastName) AS Name, d.City\r\nFROM AdventureWorks2016.Person.Person AS p\r\nINNER JOIN AdventureWorks2016.HumanResources.Employee e ON p.BusinessEntityID = e.BusinessEntityID\r\nINNER JOIN\r\n   (SELECT bea.BusinessEntityID, a.City\r\n    FROM AdventureWorks2016.Person.Address AS a\r\n    INNER JOIN AdventureWorks2016.Person.BusinessEntityAddress AS bea\r\n    ON a.AddressID = bea.AddressID) AS d\r\nON p.BusinessEntityID = d.BusinessEntityID\r\nORDER BY p.LastName, p.FirstName;<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"paragraph\">\n<p>The results of this query:<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p><span class=\"image\"><img decoding=\"async\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/02\/13010-sql-query-results.png\" alt=\"SQL Server query results\" \/><\/span><\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>With barely any changes, a very similar query can be run as a N1QL query in Couchbase:<\/p>\n<\/div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight decode:true\"><code class=\"language-SQL\" data-lang=\"SQL\">SELECT RTRIM(p.FirstName) || ' ' || LTRIM(p.LastName) AS Name, d.City\r\nFROM AdventureWorks2016.Person.Person AS p\r\nINNER JOIN AdventureWorks2016.HumanResources.Employee e ON p.BusinessEntityID = e.BusinessEntityID\r\nINNER JOIN\r\n   (SELECT bea.BusinessEntityID, a.City\r\n    FROM AdventureWorks2016.Person.Address AS a\r\n    INNER JOIN AdventureWorks2016.Person.BusinessEntityAddress AS bea\r\n    ON a.AddressID = bea.AddressID) AS d\r\nON p.BusinessEntityID = d.BusinessEntityID\r\nORDER BY p.LastName, p.FirstName;<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"paragraph\">\n<p>The only difference in the N1QL version is the use of <code>||<\/code> instead of <code>+<\/code> for string concatenation, and the results being JSON instead of a Result Set:<\/p>\n<\/div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight decode:true\"><code class=\"language-JavaScript\" data-lang=\"JavaScript\">[\r\n  { \"City\": \"Bothell\", \"Name\": \"Syed Abbas\" },\r\n  { \"City\": \"Carnation\", \"Name\": \"Kim Abercrombie\" },\r\n  { \"City\": \"Kenmore\", \"Name\": \"Hazem Abolrous\" },\r\n  { \"City\": \"Seattle\", \"Name\": \"Pilar Ackerman\" },\r\n  { \"City\": \"Monroe\", \"Name\": \"Jay Adams\" },\r\n  { \"City\": \"Issaquah\", \"Name\": \"Fran\u00c3\u00a7ois Ajenstat\" },\r\n  { \"City\": \"Renton\", \"Name\": \"Amy Alberts\" },\r\n  { \"City\": \"Bellevue\", \"Name\": \"Greg Alderson\" },\r\n  { \"City\": \"Renton\", \"Name\": \"Sean Alexander\" },\r\n  { \"City\": \"Renton\", \"Name\": \"Gary Altman\" },\r\n  \/\/\/ ... etc ...\r\n]<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"paragraph\">\n<p>This does <em>not<\/em> mean that the N1QL query is as optimized as possible. For example, the above N1QL query does not use document keys, and could maybe benefit from more or different indexes. (Since it only needs FirstName, LastName, and City, covering index(es) might be appropriate here, for instance). But since this is a &#8220;level 5&#8221; conversion, it should be enough to get started.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_index_to_index_conversion\">Index to Index conversion<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>SQL Server allows you to create indexes on tables for one or more columns.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Couchbase Server also allows you to <a href=\"https:\/\/docs.couchbase.com\/server\/current\/n1ql\/n1ql-intro\/queriesandresults.html#indexes\">create indexes<\/a> on collections for one or more JSON fields.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>The SqlServerToCouchbase utility will do a direct conversion of the SQL Server indexes.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>For instance, an index on SQL Server:<\/p>\n<\/div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight decode:true\"><code>CREATE INDEX SalesTaxRate_StateProvinceID_TaxType ON AdventureWorks2016.Sales.SalesTaxRate (StateProvinceID, TaxType)<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"paragraph\">\n<p>will become an index on Couchbase Server:<\/p>\n<\/div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight decode:true\"><code>CREATE INDEX sql_SalesTaxRate_StateProvinceID_TaxType ON AdventureWorks2016.Sales.SalesTaxRate (StateProvinceID, TaxType)<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"paragraph\">\n<p>Couchbase will convert all indexes, but the level of SQL Server indexing may be too high or too low, depending on the queries that you plan to execute. Fortunately, Couchbase Server 6.6 and newer has a built-in <a href=\"https:\/\/docs.couchbase.com\/server\/current\/tools\/query-workbench.html#index-advisor\">Index Advisor<\/a> (a standalone <a href=\"https:\/\/index-advisor.couchbase.com\/indexadvisor\">web-based version is also available<\/a>), that will recommend indexes for any N1QL query you want.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p><strong>Note<\/strong>: Couchbase Server does NOT allow the equivalent of full table scans (i.e. primary indexes) by default. The SqlServerToCouchbase utility does not create primary indexes for each collection. If you attempt to run a query and get an error message like &#8220;No index available on keyspace&#8221;, this is your cue to try to use the Index Advisor.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>You can also use the <a href=\"https:\/\/docs.couchbase.com\/server\/current\/manage\/monitor\/monitoring-indexes.html\">Couchbase Index monitor<\/a> to check the Index Request Rate (among other index characteristics). This may help you to identify indexes that you no longer need.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_row_to_document\">Row to Document<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Once the appropriate scopes and collections are in place, the SqlServerToCouchbase utility can be used to get all the rows of data from each table and write them into JSON documents in each collection.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p><span class=\"image\"><img decoding=\"async\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/02\/13001-sql-server-address-row.png\" alt=\"13001 sql server address row\" \/><\/span><\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>For the most part, the data types supported by SQL Server <a href=\"https:\/\/www.couchbase.com\/blog\/couchbase-for-oracle-developers-part-4-data-types\/\">map well to JSON<\/a> data types. Some examples:<\/p>\n<\/div>\n<div class=\"responsive-table\">\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 data type<\/th>\n<th class=\"tableblock halign-left valign-top\">JSON data type<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">char, varchar, nvarchar, etc<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">string<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">integer, decimal, float, real, etc<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">number<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">bit<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">boolean<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">date, datetime, time, etc<\/p>\n<\/td>\n<td class=\"tableblock halign-left valign-top\">\n<p class=\"tableblock\">string<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div class=\"paragraph\">\n<p>In addition, there are some specialized SQL Server data types that the SqlServerToCouchbase utility is also able to handle.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>For instance, SQL Server\u2019s <code>geography<\/code> type becomes a nested JSON object with properties like &#8220;Lat&#8221; and &#8220;Long&#8221; and &#8220;Z&#8221;. Here\u2019s the converted document for the row of data in the above screenshot.<\/p>\n<\/div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight decode:true\"><code class=\"language-JavaScript\" data-lang=\"JavaScript\">{\r\n  \"AddressID\": 1,\r\n  \"AddressLine1\": \"1970 Napa Ct.\",\r\n  \"AddressLine2\": null,\r\n  \"City\": \"Bothell\",\r\n  \"StateProvinceID\": 79,\r\n  \"PostalCode\": \"98011\",\r\n  \"SpatialLocation\": {\r\n    \"IsNull\": false,\r\n    \"STSrid\": 4326,\r\n    \"Lat\": 47.7869921906598,\r\n    \"Long\": -122.164644615406,\r\n    \"Z\": null,\r\n    \"M\": null,\r\n    \"HasZ\": false,\r\n    \"HasM\": false\r\n  },\r\n  \"rowguid\": \"9aadcb0d-36cf-483f-84d8-585c2d4ec6e9\",\r\n  \"ModifiedDate\": \"2007-12-04T00:00:00\"\r\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"paragraph\">\n<p>If there is a specific data type that you\u2019re curious about, try the SqlServerToCouchbase utility and see what happens. If it\u2019s not converting the data how you\u2019d expect, <a href=\"https:\/\/github.com\/mgroves\/SqlServerToCouchbase\/issues\">please create an issue on GitHub<\/a>.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_user_to_user\">User to user<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>SQL Server supports a variety of user types, security roles, and permissions at the database, schema, and table levels.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Couchbase Server has role-based authentication (RBAC) that also allows a variety of permissions to be set at the bucket, scope, and collection levels.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>The SqlServerToCouchbase utility will create matching users and do its best to convert the permissions as much as possible.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>AdventureWorks does not contain any examples of users with fine-grained permissions. I created my own to represent a subset of permissions for a few tables in the Person schema.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p><span class=\"image\"><img decoding=\"async\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/02\/13008-sql-server-user-permissions-security.png\" alt=\"SQL Server user permissions at the table level\" \/><\/span><\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>The corresponding user in Couchbase will have similar permissions:<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p><span class=\"image\"><img decoding=\"async\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2021\/02\/13009-couchbase-user-permissions-security.png\" alt=\"Couchbase user permissions at the collection level\" \/><\/span><\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>While SQL Server has only one API for working with data (tSQL), Couchbase has multiple: N1QL, key\/value, full text search, analytics, and more. Hence the number of permissions converted to the user in Couchbase is larger. As you move up to &#8220;level 4&#8221;, these can be tweaked as necessary.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p><strong>Warning<\/strong>: Users, authentication, authorization, and security is an area where caution and manual review should definitely be exercised. Do not leave this step to be completely automated until you are sure the outcome is what you want.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_next_steps\">Next Steps<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>The &#8220;conversion&#8221; utility will create a Couchbase Server conversion of your SQL Server database. However, it\u2019s currently unable to convert any client code. That\u2019s a difficult problem for any database migration, not just SQL Server to NoSQL. However, keep an eye on this blog for future articles about migrating SQL queries and client code!<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>In the meantime, some of the steps you\u2019ll need to look into:<\/p>\n<\/div>\n<div class=\"ulist\">\n<ul>\n<li>You\u2019ll need to change the data access in your client to use a Couchbase SDK. For instance, if you\u2019re using ADO.NET, Dapper, PetaPoco, etc, you\u2019ll can use the <a href=\"https:\/\/docs.couchbase.com\/dotnet-sdk\/current\/hello-world\/start-using-sdk.html\">Couchbase .NET SDK<\/a>.<\/li>\n<li>Using Entity Framework? Check out the <a href=\"https:\/\/github.com\/couchbaselabs\/Linq2Couchbase\">Linq2Couchbase project<\/a>. (If you are using Java, check out <a href=\"https:\/\/spring.io\/projects\/spring-data-couchbase\">Spring Data Couchbase<\/a>.)<\/li>\n<li>Couchbase does support ACID transactions! For .NET, <a href=\"https:\/\/www.nuget.org\/packages\/Couchbase.Transactions\/1.0.0-beta.1\">Couchbase.Transactions<\/a> are currently in beta. In Couchbase 7, N1QL also supports <a href=\"https:\/\/docs.couchbase.com\/server\/7.0\/n1ql\/n1ql-language-reference\/begin-transaction.html\"><code>BEGIN\/COMMIT\/ROLLBACK TRANSACTION<\/code><\/a><\/li>\n<li>Couchbase\u2019s N1QL is a full SQL implementation. However, like all SQL dialects, there are differences between N1QL and tSQL. A few queries may work as is, but in most cases there are likely to be syntax differences. Check out the in-browser <a href=\"https:\/\/query-tutorial.couchbase.com\/tutorial\/\">interactive N1QL tutorial<\/a>.<\/li>\n<li>Looking for a similar approach with MySQL? Check out <a href=\"https:\/\/www.couchbase.com\/blog\/hands-on-migration-from-relational-to-collections\/\">Hands-on Migration From Relational to Collections<\/a> for a similar approach that uses Python \/ CLI.<\/li>\n<li>Looking for a similar approach with PostgreSQL? Check out <a href=\"https:\/\/github.com\/metonymic-smokey\/couchgres\/tree\/main\/migrate\">Couchgres<\/a>, a community-supported open-source project that uses a similar approach with Golang \/ CLI.<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"sect1\">\n<h2 id=\"_summary\">Summary<\/h2>\n<div class=\"sectionbody\">\n<div class=\"paragraph\">\n<p>Couchbase Server 7 is set to be the biggest, most important release of Couchbase Server. Keep an eye on the Couchbase blog for more articles like this, designed to help you in your SQL to NoSQL converter journey.<\/p>\n<\/div>\n<div class=\"paragraph\">\n<p>Couchbase Server 7 beta is available right now for you to <a href=\"https:\/\/www.couchbase.com\/downloads\/\">download and try out<\/a>. Since this is a beta, any feedback or questions you have are much appreciated: check out the <a href=\"https:\/\/www.couchbase.com\/forums\/c\/beta-support\/\">Beta Support section<\/a> on the Couchbase forums for Couchbase Server 7 and other beta\/preview releases.<\/p>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>SQL to NoSQL migration seems like a contradiction, but thanks to advances and innovations in Couchbase Server\u2019s NoSQL database, it\u2019s becoming easier. In this post, I\u2019ll introduce you to a tool called SqlServerToCouchbase, an open-source attempt at an automated tool [&hellip;]<\/p>\n","protected":false},"author":71,"featured_media":10854,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1811,1816,1812],"tags":[9499,1556],"ppma_author":[8937],"class_list":["post-10832","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet","category-couchbase-server","category-n1ql-query","tag-acid-transactions","tag-sql-server"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.8 (Yoast SEO v25.8) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>SQL to NoSQL Migration: How to Convert Automatically<\/title>\n<meta name=\"description\" content=\"SQL to NoSQL migration can be at least partially automated. This article helps you find out about the new conversion features available in Couchbase Server 7.\" \/>\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\/sql-to-nosql-automated-migration\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"SQL to NoSQL: Automated Migration\" \/>\n<meta property=\"og:description\" content=\"SQL to NoSQL migration can be at least partially automated. This article helps you find out about the new conversion features available in Couchbase Server 7.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/sql-to-nosql-automated-migration\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2021-03-02T08:27:36+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-13T23:46:30+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/02\/130-hero-sql-to-nosql-handoff.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1575\" \/>\n\t<meta property=\"og:image:height\" content=\"628\" \/>\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=\"13 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/sql-to-nosql-automated-migration\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/sql-to-nosql-automated-migration\/\"},\"author\":{\"name\":\"Matthew Groves\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/3929663e372020321b0152dc4fa65a58\"},\"headline\":\"SQL to NoSQL: Automated Migration\",\"datePublished\":\"2021-03-02T08:27:36+00:00\",\"dateModified\":\"2025-06-13T23:46:30+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/sql-to-nosql-automated-migration\/\"},\"wordCount\":2175,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/sql-to-nosql-automated-migration\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/02\/130-hero-sql-to-nosql-handoff.jpg\",\"keywords\":[\"ACID transactions\",\"SQL Server\"],\"articleSection\":[\".NET\",\"Couchbase Server\",\"SQL++ \/ N1QL Query\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/sql-to-nosql-automated-migration\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/sql-to-nosql-automated-migration\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/sql-to-nosql-automated-migration\/\",\"name\":\"SQL to NoSQL Migration: How to Convert Automatically\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/sql-to-nosql-automated-migration\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/sql-to-nosql-automated-migration\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/02\/130-hero-sql-to-nosql-handoff.jpg\",\"datePublished\":\"2021-03-02T08:27:36+00:00\",\"dateModified\":\"2025-06-13T23:46:30+00:00\",\"description\":\"SQL to NoSQL migration can be at least partially automated. This article helps you find out about the new conversion features available in Couchbase Server 7.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/sql-to-nosql-automated-migration\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/sql-to-nosql-automated-migration\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/sql-to-nosql-automated-migration\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/02\/130-hero-sql-to-nosql-handoff.jpg\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/02\/130-hero-sql-to-nosql-handoff.jpg\",\"width\":1575,\"height\":628,\"caption\":\"Couchbase TLS security enhancements in 7.1\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/sql-to-nosql-automated-migration\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"SQL to NoSQL: Automated 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\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@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\":\"en-US\",\"@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\/author\/matthew-groves\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"SQL to NoSQL Migration: How to Convert Automatically","description":"SQL to NoSQL migration can be at least partially automated. This article helps you find out about the new conversion features available in Couchbase Server 7.","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\/sql-to-nosql-automated-migration\/","og_locale":"en_US","og_type":"article","og_title":"SQL to NoSQL: Automated Migration","og_description":"SQL to NoSQL migration can be at least partially automated. This article helps you find out about the new conversion features available in Couchbase Server 7.","og_url":"https:\/\/www.couchbase.com\/blog\/sql-to-nosql-automated-migration\/","og_site_name":"The Couchbase Blog","article_published_time":"2021-03-02T08:27:36+00:00","article_modified_time":"2025-06-13T23:46:30+00:00","og_image":[{"width":1575,"height":628,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/02\/130-hero-sql-to-nosql-handoff.jpg","type":"image\/jpeg"}],"author":"Matthew Groves","twitter_card":"summary_large_image","twitter_creator":"@mgroves","twitter_misc":{"Written by":"Matthew Groves","Est. reading time":"13 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/sql-to-nosql-automated-migration\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/sql-to-nosql-automated-migration\/"},"author":{"name":"Matthew Groves","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/3929663e372020321b0152dc4fa65a58"},"headline":"SQL to NoSQL: Automated Migration","datePublished":"2021-03-02T08:27:36+00:00","dateModified":"2025-06-13T23:46:30+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/sql-to-nosql-automated-migration\/"},"wordCount":2175,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/sql-to-nosql-automated-migration\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/02\/130-hero-sql-to-nosql-handoff.jpg","keywords":["ACID transactions","SQL Server"],"articleSection":[".NET","Couchbase Server","SQL++ \/ N1QL Query"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/sql-to-nosql-automated-migration\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/sql-to-nosql-automated-migration\/","url":"https:\/\/www.couchbase.com\/blog\/sql-to-nosql-automated-migration\/","name":"SQL to NoSQL Migration: How to Convert Automatically","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/sql-to-nosql-automated-migration\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/sql-to-nosql-automated-migration\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/02\/130-hero-sql-to-nosql-handoff.jpg","datePublished":"2021-03-02T08:27:36+00:00","dateModified":"2025-06-13T23:46:30+00:00","description":"SQL to NoSQL migration can be at least partially automated. This article helps you find out about the new conversion features available in Couchbase Server 7.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/sql-to-nosql-automated-migration\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/sql-to-nosql-automated-migration\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/sql-to-nosql-automated-migration\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/02\/130-hero-sql-to-nosql-handoff.jpg","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2021\/02\/130-hero-sql-to-nosql-handoff.jpg","width":1575,"height":628,"caption":"Couchbase TLS security enhancements in 7.1"},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/sql-to-nosql-automated-migration\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"SQL to NoSQL: Automated 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":"en-US"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"The Couchbase Blog","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@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":"en-US","@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\/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 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."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/10832","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/users\/71"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=10832"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/10832\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/10854"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=10832"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=10832"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=10832"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=10832"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}