{"id":3570,"date":"2021-08-23T14:06:47","date_gmt":"2021-08-23T14:06:47","guid":{"rendered":"https:\/\/cloudsurfers.it\/?p=3570"},"modified":"2021-08-23T14:06:51","modified_gmt":"2021-08-23T14:06:51","slug":"storicizzazione-del-dato-differenze-fra-strutture-dati-json-in-sql-server-e-strutture-nosql-con-cosmosdb","status":"publish","type":"post","link":"https:\/\/cloudsurfers.it\/index.php\/storicizzazione-del-dato-differenze-fra-strutture-dati-json-in-sql-server-e-strutture-nosql-con-cosmosdb\/","title":{"rendered":"Storicizzazione del dato, differenze fra strutture dati JSON in SQL Server e strutture NoSQL con CosmosDB"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"538\" src=\"https:\/\/cloudsurfers.it\/wp-content\/uploads\/2021\/08\/download-1024x538.png\" alt=\"\" class=\"wp-image-3588\" srcset=\"https:\/\/cloudsurfers.it\/wp-content\/uploads\/2021\/08\/download-1024x538.png 1024w, https:\/\/cloudsurfers.it\/wp-content\/uploads\/2021\/08\/download-300x158.png 300w, https:\/\/cloudsurfers.it\/wp-content\/uploads\/2021\/08\/download-768x403.png 768w, https:\/\/cloudsurfers.it\/wp-content\/uploads\/2021\/08\/download-600x315.png 600w, https:\/\/cloudsurfers.it\/wp-content\/uploads\/2021\/08\/download.png 1200w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\n\n\n\n<p>Nell&#8217;articolo del mese scorso &#8220;<a rel=\"noreferrer noopener\" href=\"https:\/\/cloudsurfers.it\/index.php\/storicizzazione-del-dato-compressione-e-interrogazione-di-strutture-dati-json-in-sql-server\/\" target=\"_blank\">Storicizzazione del dato, compressione e interrogazione di strutture dati JSON in SQL Server<\/a>&#8221; abbiamo analizzato, sia in termini prestazionali che in termini di peso, la storicizzazione del dato utilizzando gli strumenti <em>JSON <\/em>introdotti con <strong>SQL Server 2016<\/strong>. Abbiamo anche toccato la tematica della compressione e successivamente dell&#8217;interrogazione del dato compresso.<\/p>\n\n\n\n<p>Quel tipo di approccio affrontato lo possiamo chiamare approccio ibrido in quanto utilizza una base dati relazionale, <em>SQL Server<\/em> per l&#8217;appunto, per salvare dei dati in un formato struttura non relazionale, <em>JSON <\/em>nel nostro caso.<\/p>\n\n\n\n<p>E se avessimo affrontato la stessa tematica utilizzando uno strumento creato appositamente per la gestione di strutture non relazionali?<\/p>\n\n\n\n<p>Vediamo una piccola analisi utilizzando, con la stessa base dati dell&#8217;articolo precedente, <strong>CosmosDB <\/strong>restando quindi sempre in casa <em>Microsoft<\/em>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Premessa<\/h3>\n\n\n\n<p>La base dati utilizzata \u00e8 la stessa dell&#8217;articolo del mese scorso, un set di 100 mila record con una struttura <em>JSON <\/em>nidificata su pi\u00f9 livelli.<\/p>\n\n\n\n<p>Tutte le interrogazioni e quindi i numeri che vedremo, sono eseguite sulla medesima macchina utilizzata precedentemente, ricapitolando:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><em>Laptop Lenovo X1 Carbon 6a generazione<\/em><\/li><li><em>Intel i7-8550U<\/em><\/li><li><em>16GB di memoria RAM LPDDR3<\/em><\/li><li><em>SSD Samsung<\/em><\/li><\/ul>\n\n\n\n<p>Per la base dati <em>NoSQL <\/em>\u00e8 stato utilizzato il software <strong><a href=\"https:\/\/docs.microsoft.com\/it-it\/azure\/cosmos-db\/local-emulator?tabs=ssl-netstd21\" target=\"_blank\" rel=\"noreferrer noopener\">Azure Cosmos DB Emulator<\/a><\/strong> che permette di avere un&#8217;istanza <em>CosmosDB <\/em>locale di test prima di lavorare direttamente su <em>Azure <\/em>in cloud.<\/p>\n\n\n\n<p>Inoltre questa analisi non vuole presentarsi come una guida passo passo per l&#8217;utilizzo di <em>Azure CosmosDB<\/em>. Risulta utile per dare qualche spunto di riflessione in merito all&#8217;argomento. In pi\u00f9 utilizzando una sintassi <em>SQL-like<\/em>, noterete come il &#8220;<em>porting<\/em>&#8221; delle <em>query <\/em>di interrogazione utilizzate precedentemente sia estremamente semplice da rendere molto intuitivo il passaggio da <em>SQL Server<\/em> a <em>CosmosDB<\/em>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Migrazione dei dati<\/h3>\n\n\n\n<p>La base dati utilizzata \u00e8 un database <em>SQL Server<\/em> con una tabella chiamata &#8220;<strong>TabellaInChiaro<\/strong>&#8221; composta da due campi: <strong>Id<\/strong>, chiave primaria intera numerica, ed un campo chiamato <strong>Json <\/strong>di tipo <em>NVARCHAR(MAX)<\/em>.<\/p>\n\n\n\n<p>La tabella \u00e8 popolata con 100 mila record ed all&#8217;interno del campo <strong>Json <\/strong>di ciascun record \u00e8 presente una struttura <em>JSON <\/em>nidificata su pi\u00f9 livelli.<\/p>\n\n\n\n<p>Iniziamo quindi a predisporre la nuova base dati <em>NoSQL<\/em>, avviamo <strong>CosmosDB Emulator<\/strong> e creiamo un nuovo database, nel nostro caso chiamato <strong>dbtest<\/strong>:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"437\" height=\"412\" src=\"https:\/\/cloudsurfers.it\/wp-content\/uploads\/2021\/08\/new_database_1.png\" alt=\"\" class=\"wp-image-3574\" srcset=\"https:\/\/cloudsurfers.it\/wp-content\/uploads\/2021\/08\/new_database_1.png 437w, https:\/\/cloudsurfers.it\/wp-content\/uploads\/2021\/08\/new_database_1-300x283.png 300w\" sizes=\"auto, (max-width: 437px) 100vw, 437px\" \/><figcaption>La pagina di creazione di un nuovo database<\/figcaption><\/figure><\/div>\n\n\n\n<p>Aggiungiamo alla base dati un nuovo <em>container<\/em>, che nel nostro caso chiamiamo &#8220;<strong>tabella<\/strong>&#8220;, ed indichiamo una chiave di partizione che chiamiamo &#8220;<strong>id<\/strong>&#8220;:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"435\" height=\"475\" src=\"https:\/\/cloudsurfers.it\/wp-content\/uploads\/2021\/08\/new_database_2.png\" alt=\"\" class=\"wp-image-3575\" srcset=\"https:\/\/cloudsurfers.it\/wp-content\/uploads\/2021\/08\/new_database_2.png 435w, https:\/\/cloudsurfers.it\/wp-content\/uploads\/2021\/08\/new_database_2-275x300.png 275w\" sizes=\"auto, (max-width: 435px) 100vw, 435px\" \/><\/figure><\/div>\n\n\n\n<p>Ora partendo dalla base dati <em>SQL Server<\/em> dobbiamo creare un file <em>JSON <\/em>strutturato come la struttura finale che vorremmo ottenere per i nostri record (<em>item <\/em>su <em>CosmosDB<\/em>) ed importarlo dalla sezione <strong>Upload Items<\/strong>:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"431\" height=\"159\" src=\"https:\/\/cloudsurfers.it\/wp-content\/uploads\/2021\/08\/new_database_3.png\" alt=\"\" class=\"wp-image-3577\" srcset=\"https:\/\/cloudsurfers.it\/wp-content\/uploads\/2021\/08\/new_database_3.png 431w, https:\/\/cloudsurfers.it\/wp-content\/uploads\/2021\/08\/new_database_3-300x111.png 300w\" sizes=\"auto, (max-width: 431px) 100vw, 431px\" \/><\/figure><\/div>\n\n\n\n<p>Alternativamente all&#8217;importatore tramite pagine Web, \u00e8 possibile utilizzare lo strumento <strong><a rel=\"noreferrer noopener\" href=\"https:\/\/www.microsoft.com\/en-us\/download\/details.aspx?id=46436\" target=\"_blank\">Azure DocumentDb Migration Tool<\/a><\/strong>, open source, questo risulta molto pi\u00f9 veloce rispetto all&#8217;importazione da pagina Web come mostrato sopra.<\/p>\n\n\n\n<p><em>Nota personale: per la creazione del file JSON da importare, ho trovato molto comodo l&#8217;utilizzo dello strumento <strong><a rel=\"noreferrer noopener\" href=\"https:\/\/docs.microsoft.com\/it-it\/sql\/relational-databases\/json\/format-query-results-as-json-with-for-json-sql-server?view=sql-server-ver15\" target=\"_blank\">FOR JSON PATH<\/a><\/strong>, questo permette di formattare i risultati di una query SQL in formato JSON e quindi con un po&#8217; di manipolazione sui dati, permette di arrivare al file di importazione molto comodamente.<\/em><\/p>\n\n\n\n<p>Al termine dell&#8217;importazione ci troveremo davanti la nostra base dati <em>NoSQL<\/em>:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"643\" height=\"281\" src=\"https:\/\/cloudsurfers.it\/wp-content\/uploads\/2021\/08\/new_database_4.png\" alt=\"\" class=\"wp-image-3579\" srcset=\"https:\/\/cloudsurfers.it\/wp-content\/uploads\/2021\/08\/new_database_4.png 643w, https:\/\/cloudsurfers.it\/wp-content\/uploads\/2021\/08\/new_database_4-300x131.png 300w, https:\/\/cloudsurfers.it\/wp-content\/uploads\/2021\/08\/new_database_4-640x281.png 640w, https:\/\/cloudsurfers.it\/wp-content\/uploads\/2021\/08\/new_database_4-600x262.png 600w\" sizes=\"auto, (max-width: 643px) 100vw, 643px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Dimensioni<\/h3>\n\n\n\n<p>Andiamo ad analizzare le dimensioni totali della tabella (<em>container <\/em>su <em>CosmosDB<\/em>):<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong> TabellaInChiaro (megabyte)<\/strong><\/td><td><strong> Azure CosmosDB (megabyte)<\/strong><\/td><\/tr><tr><td>316<\/td><td>146<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>La differenza \u00e8 netta, la base dati <em>NoSQL <\/em>essendo ottimizzata per strutture non-relazionali gestisce al meglio il peso del dato su disco risultando praticamente il doppio pi\u00f9 leggero rispetto allo stesso dato su <em>SQL Server<\/em>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Prestazioni<\/h3>\n\n\n\n<p>Vediamo ora le prestazioni di interrogazione del dato, prima con una <em>query SQL<\/em> che utilizza lo strumento <strong>OPENJSON<\/strong>, successivamente con la stessa <em>query <\/em>utilizzando per\u00f2 <strong>JSON_VALUE<\/strong> su <em>SQL Server<\/em> (per la differenza dei due strumenti potete fare riferimento a <a rel=\"noreferrer noopener\" href=\"https:\/\/cloudsurfers.it\/index.php\/storicizzazione-del-dato-compressione-e-interrogazione-di-strutture-dati-json-in-sql-server\/\" target=\"_blank\">questo articolo<\/a>).<\/p>\n\n\n\n<p><strong>OPENJSON<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SELECT Nome FROM TabellaInChiaro CROSS APPLY OPENJSON(&#91;Json]) WITH (Nome NVARCHAR(MAX))<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>SQL Server (ms)<\/strong><\/td><td><strong>Azure CosmosDB (ms)<\/strong><\/td><\/tr><tr><td>2617<\/td><td>534<\/td><\/tr><\/tbody><\/table><figcaption>Azure CosmosDB \u00e8 l&#8217;80% pi\u00f9 veloce rispetto a SQL Server<\/figcaption><\/figure>\n\n\n\n<p><strong>JSON_VALUE<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SELECT JSON_VALUE(&#91;Json], '$.Nome') FROM TabellaInChiaro<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>SQL Server (ms)<\/strong><\/td><td><strong>Azure CosmosDB (ms)<\/strong><\/td><\/tr><tr><td>595<\/td><td>534<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Utilizzando lo strumento <em>JSON_VALUE<\/em> ed <strong>interrogando il primo livello della struttura<\/strong> <em>JSON<\/em>, non c&#8217;\u00e8 differenza nella velocit\u00e0 di interrogazione del dato.<\/p>\n\n\n\n<p>Passiamo ora ad una <em>query <\/em>pi\u00f9 complessa che interroghi pi\u00f9 elementi nidificati:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SELECT P.Nome, P.Prezzo, P.Qta, T.Nome, T.Prezzo, T.Qta FROM TabellaInChiaro CROSS APPLY OPENJSON(&#91;Json]) WITH (Nome NVARCHAR(MAX), Prezzo INT, Qta INT, SottoProdotto NVARCHAR(MAX) AS JSON) P CROSS APPLY OPENJSON(SottoProdotto) WITH (Nome NVARCHAR(MAX), Prezzo INT, Qta INT, SottoProdotto NVARCHAR(MAX) AS JSON) T<\/code><\/pre>\n\n\n\n<p>la stessa <em>query<\/em> su <em>CosmosDB <\/em>diventa:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SELECT c.Json.Nome, c.Json.Prezzo, c.Json.Qta, \nc.Json.SottoProdotto.Nome AS NomeSottoProdotto, c.Json.SottoProdotto.Prezzo AS PrezzoSottoProdotto, \nc.Json.SottoProdotto.Qta AS QtaSottoProdotto FROM c<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>SQL Server (ms)<\/strong><\/td><td><strong>Azure CosmosDB (ms)<\/strong><\/td><\/tr><tr><td>6345<\/td><td>514<\/td><\/tr><\/tbody><\/table><figcaption>Azure CosmosDB \u00e8 il 92% pi\u00f9 veloce rispetto a SQL Server<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Conclusioni<\/h3>\n\n\n\n<p>Partiamo con il dire che <em>Azure CosmosDB<\/em> essendo uno strumento dedicato e specifico per questo tipo di gestione del dato non relazionale, sia in termini di peso che in termini di prestazioni ha un&#8217;ottimizzazione notevolmente maggiore rispetto a SQL Server.<\/p>\n\n\n\n<p>Differenza comunque non troppo marcata con <em>SQL Server<\/em> (<strong>JSON_VALUE<\/strong>) se si effettuano interrogazioni semplici su un unico livello di nidificazione, qui i due strumenti sembrano equivalersi.<\/p>\n\n\n\n<p>Storia che invece cambia nettamente effettuando interrogazioni complesse in cui vengono prese in esame strutture nidificate su pi\u00f9 livelli. Differenze marcate anche a livello di peso come visto sopra.<\/p>\n\n\n\n<p>Concludendo, ogni metodo ha i suoi pro e i suoi contro, questa piccola analisi non serve per decretare un vincitore, ma per mettere in luce le differenze concrete dei due strumenti utilizzando una stessa base dati. Facendo un esempio, in sistemi preesistenti pu\u00f2 essere migliore l&#8217;accoppiata <em>SQL Server<\/em> e strumenti <em>JSON<\/em> per evitare di aggiungere punti di rotture e sfruttare la base dati esistente evitando un collegamento con una base dati esterna. In progetti nuovi al contrario, per avere uno spazio e una velocit\u00e0 di interrogazione pi\u00f9 efficiente, pu\u00f2 essere un bene adottare fin da subito una base dati non relazionale <em>NoSQL <\/em>piuttosto che il classico DB <em>SQL Server<\/em>. Ad ognuno la propria scelta.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Link Utili<\/h3>\n\n\n\n<p><a href=\"https:\/\/docs.microsoft.com\/it-it\/azure\/cosmos-db\/local-emulator?tabs=ssl-netstd21\">https:\/\/docs.microsoft.com\/it-it\/azure\/cosmos-db\/local-emulator?tabs=ssl-netstd21<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/www.microsoft.com\/en-us\/download\/details.aspx?id=46436\">https:\/\/www.microsoft.com\/en-us\/download\/details.aspx?id=46436<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/docs.microsoft.com\/it-it\/sql\/relational-databases\/json\/format-query-results-as-json-with-for-json-sql-server?view=sql-server-ver15\">https:\/\/docs.microsoft.com\/it-it\/sql\/relational-databases\/json\/format-query-results-as-json-with-for-json-sql-server?view=sql-server-ver15<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nell&#8217;articolo del mese scorso &#8220;Storicizzazione del dato, compressione e interrogazione di strutture dati JSON in SQL Server&#8221; abbiamo analizzato, sia in termini prestazionali che in termini di peso, la storicizzazione del dato utilizzando gli strumenti JSON introdotti con SQL Server 2016. Abbiamo anche toccato la tematica della compressione e successivamente dell&#8217;interrogazione del dato compresso.<\/p>\n<p>Vediamo una piccola analisi utilizzando, con la stessa base dati dell&#8217;articolo precedente, CosmosDB restando quindi sempre in casa Microsoft.<\/p>\n","protected":false},"author":3,"featured_media":3588,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"wds_primary_category":0,"footnotes":""},"categories":[130,160,139],"tags":[43,161,162,38],"class_list":["post-3570","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-insights","category-azure-cosmosdb","category-sql-server-insights","tag-azure","tag-cosmosdb","tag-nosql","tag-sql-server"],"_links":{"self":[{"href":"https:\/\/cloudsurfers.it\/index.php\/wp-json\/wp\/v2\/posts\/3570","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cloudsurfers.it\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudsurfers.it\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudsurfers.it\/index.php\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudsurfers.it\/index.php\/wp-json\/wp\/v2\/comments?post=3570"}],"version-history":[{"count":0,"href":"https:\/\/cloudsurfers.it\/index.php\/wp-json\/wp\/v2\/posts\/3570\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudsurfers.it\/index.php\/wp-json\/wp\/v2\/media\/3588"}],"wp:attachment":[{"href":"https:\/\/cloudsurfers.it\/index.php\/wp-json\/wp\/v2\/media?parent=3570"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudsurfers.it\/index.php\/wp-json\/wp\/v2\/categories?post=3570"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudsurfers.it\/index.php\/wp-json\/wp\/v2\/tags?post=3570"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}