{"id":102097,"date":"2024-04-12T02:26:00","date_gmt":"2024-04-12T02:26:00","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=102097"},"modified":"2024-09-03T20:04:46","modified_gmt":"2024-09-03T20:04:46","slug":"fabric-and-azure-sql-in-a-few-clicks-mirroring-a-database","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/bi-sql-server\/fabric-and-azure-sql-in-a-few-clicks-mirroring-a-database\/","title":{"rendered":"Fabric and Azure SQL in a few clicks: Mirroring a Database"},"content":{"rendered":"<p>Finally, <a href=\"https:\/\/learn.microsoft.com\/en-us\/fabric\/database\/mirrored-database\/overview\">mirroring is available for Fabric<\/a>! You can mirror an <strong>Azure SQL<\/strong> to <strong>Fabric<\/strong>. It works for <strong>CosmoDB<\/strong> and <strong>Snowflake<\/strong> as well, but in this article, I will focus on Azure SQL. It is 100%, no, but it is definitely a feature that is really great even now.<\/p>\n<p>Before getting into a step-by-step of the process, let\u2019s understand the basics.<\/p>\n<h2>Why Mirror a Database<\/h2>\n<p>You need to read data from production to build a single source of truth. If you create pipelines reading directly from production, you will create additional load over the production environment. The mirror allows you to do much of the production reporting from the mirror, leaving the production environment to serve other users. Keep in mind, production report, but not analytics report.<\/p>\n<p>Mirroring a production database to <strong>Fabric<\/strong> is one method to ensure the load over production will be as low as possible and the data will be transferred fabric to complete the transformations from this point.<\/p>\n<p>Only this? What about avoiding pipeline creation? Not really, you still need to create pipelines, as I will explain ahead.<\/p>\n<h2>Where your data will be stored<\/h2>\n<p>If I tell you <strong>OneLake<\/strong>, you might want to slap me. Of course it\u2019s on <strong>OneLake<\/strong>, you know that! But where? A <strong>Data Warehouse<\/strong>? A <strong>Lakehouse<\/strong>? Where?<\/p>\n<p>Microsoft created a special type of object for this: The <strong>Mirrored Database<\/strong>. In the same way as the other data objects, this object also has two associated objects: A <strong>SQL Endpoint<\/strong> and a <strong>Semantic Model<\/strong>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"764\" height=\"318\" class=\"wp-image-102098\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-description-automatica-27.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<p>We can use the <strong>SQL Endpoint<\/strong> to query the mirrored data, in the same way we would do with a <strong>Data Warehouse<\/strong> or <strong>Lakehouse<\/strong>.<\/p>\n<p>Of course we can use the <strong>Semantic Model<\/strong> to build reports, but let\u2019s talk later if this is a good idea or not.<\/p>\n<h2>What to do and not to do with a mirrored database<\/h2>\n<p>Mirroring a database is like creating a landing zone in your Data Intelligence environment. While it is similar, it is a bit different from that: a landing zone keeps the data ingested, the mirrored database doesn\u2019t. When a record is updated or deleted in production the same will happen with the mirror.<\/p>\n<p>The mirrored model contains all the common mistakes of production modelling which makes it not good for analytical reporting. Usually, it will not be good to hold history and may not be representing the facts in a business point of view.<\/p>\n<p><strong><em>What you should NOT do: Use the mirrored model directly to build analytical reports and dashboards<\/em><\/strong>. The quality of this data would be low, the amount of history would be questionable, you would not have a single source of truth.<\/p>\n<p>However, keep in mind I wrote <strong><em>analytical reports<\/em><\/strong>. Production reports, which may be paginated reports, can be built over the Mirrored Database, because it has the same data as production. In this way, you remove from production the production reporting workload. But only production reporting, not analytical reporting.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"1024\" class=\"wp-image-102099\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-group-of-people-working-in-a-room-description-a.jpeg\" alt=\"A group of people working in a room\n\nDescription automatically generated\" \/><\/p>\n<p>Image created using Microsoft Designer Image Creator<\/p>\n<p><strong><em>For the analytical reporting, you need to transform the mirrored model in a data intelligence model, prepared to hold the complete history of the data and provide it according to the business meaning.<\/em><\/strong><\/p>\n<p>In this way, the mirroring feature doesn\u2019t save you from building pipelines to transform the data, only move the entire workload of these pipeline to inside Fabric and <strong>OneLake<\/strong>.<\/p>\n<p>If you are concerned about duplicating the data in the <strong>OneLake<\/strong>, it\u2019s not really a duplication due to the needed transformations you will make. You can use shortcuts to handle the few exceptions which may not need transformations. Yes, the mirrored database supports shortcuts from lakehouses.<\/p>\n<h2>Requirements For Mirroring<\/h2>\n<p>This is the list of what works and doesn\u2019t work with mirroring in Fabric. The list which you will skim and not really understand until, exactly like me, you get error messages about all these problems, one by one.<\/p>\n<ul>\n<li>It doesn\u2019t support on premises servers and data gateway<img loading=\"lazy\" decoding=\"async\" width=\"1135\" height=\"270\" class=\"wp-image-102100\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-description-automatica-28.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/li>\n<li>The <strong>Azure SQL Server<\/strong> needs to have an identity, at least a <strong>System Managed identity<br \/>\n<\/strong> <img loading=\"lazy\" decoding=\"async\" width=\"781\" height=\"66\" class=\"wp-image-102101\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/word-image-102097-4.png\" \/><\/li>\n<li>On the server, <em>Identity<\/em> blade, you only need to enable the <strong>System Managed Identity<\/strong>. <br \/>\n<img loading=\"lazy\" decoding=\"async\" width=\"1085\" height=\"488\" class=\"wp-image-102102\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-description-automatica-29.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/li>\n<li>The database needs to be at least on level <em>S3<\/em> or above.\u00a0 <strong>CDC (Change Data Capture)<\/strong> and other features related to change capture are only available from <em>S3<\/em> and above. It\u2019s the first level to have a dedicated <em>vCore<\/em>. <br \/>\n<img loading=\"lazy\" decoding=\"async\" width=\"932\" height=\"199\" class=\"wp-image-102103\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-description-automatica-30.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/li>\n<li>The database needs to be on the same <strong>Tenant<\/strong> as the Fabric workspace<\/li>\n<li>Fields using <strong>UDTs (User Defined Type)<\/strong> can\u2019t be mirrored\n<p><img loading=\"lazy\" decoding=\"async\" width=\"768\" height=\"455\" class=\"wp-image-102104\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-error-description-auto-1.png\" alt=\"A screenshot of a computer error\n\nDescription automatically generated\" \/> <br \/>\nThis one is trouble , because the sample database, <em>AdventureWorksLT<\/em>, which is so easy to create in <strong>Azure SQL<\/strong>, is not supported for mirroring to <strong>Fabric<\/strong><\/li>\n<li>Tables without primary keys can\u2019t be mirrored <br \/>\n<img loading=\"lazy\" decoding=\"async\" width=\"763\" height=\"187\" class=\"wp-image-102105\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-error-message-descript.png\" alt=\"A screenshot of a computer error message\n\nDescription automatically generated\" \/><\/li>\n<\/ul>\n<h2>Preparing the Walkthrough<\/h2>\n<p>You need a database installed in <strong>Azure SQL<\/strong> with some tables which fit the requirements in order to test this feature.<\/p>\n<p>I suggest one of these options:<\/p>\n<ul>\n<li>You can create the <em>AdventureWorksLT<\/em> and use the <em>Make_Big_Adventure<\/em> script to create to big tables. I adapted this script for the <em>AdventureWorksLT<\/em> and provided a copy on <a href=\"https:\/\/github.com\/DennesTorres\/BigAdventureAndQSHints\">https:\/\/github.com\/DennesTorres\/BigAdventureAndQSHints<\/a> The usual tables from <em>AdventureWorksLT<\/em> will not work for mirroring, but the new ones created by this script will.<\/li>\n<li>You can install one sample database (<a href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/samples\/sql-samples-where-are?view=sql-server-ver16\">https:\/\/learn.microsoft.com\/en-us\/sql\/samples\/sql-samples-where-are?view=sql-server-ver16<\/a>) in your local <strong>SQL Server <\/strong>and use <strong>Azure Data Studio<\/strong> to migrate it to <strong>Azure SQL<\/strong>. <a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/dms\/tutorial-sql-server-azure-sql-database-offline?tabs=azure-data-studio\">https:\/\/learn.microsoft.com\/en-us\/azure\/dms\/tutorial-sql-server-azure-sql-database-offline?tabs=azure-data-studio<\/a><\/li>\n<\/ul>\n<h2>Starting the Walkthrough<\/h2>\n<p><strong>1)<\/strong> Create a workspace called <em>MirroringSample<\/em> <br \/>\n<img loading=\"lazy\" decoding=\"async\" width=\"592\" height=\"548\" class=\"wp-image-102106\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-description-automatica-31.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<p><strong>2)<\/strong> Create a lakehouse called <em>BronzeLake<\/em><\/p>\n<p>The lakehouse is not required for the mirror, but we will use this for an experiment. If you need more information about creating a lakehouse, check this link: <a href=\"https:\/\/www.red-gate.com\/simple-talk\/cloud\/azure\/microsoft-fabric-lakehouse-and-data-factory-in-power-bi-environment\/\">https:\/\/www.red-gate.com\/simple-talk\/cloud\/azure\/microsoft-fabric-lakehouse-and-data-factory-in-power-bi-environment\/<\/a><\/p>\n<p><strong>3)<\/strong> Change the <strong>Experience<\/strong> to <strong>Data Warehouse<\/p>\n<p><\/strong> <img loading=\"lazy\" decoding=\"async\" width=\"320\" height=\"363\" class=\"wp-image-102107\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-description-automatica-32.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<p>Mirroring is included in the <strong>Data Warehouse<\/strong> experience.<\/p>\n<p><strong>4)<\/strong> Click the button <strong>Mirrored Azure SQL Database<\/p>\n<p><\/strong> <img loading=\"lazy\" decoding=\"async\" width=\"1137\" height=\"287\" class=\"wp-image-102108\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-description-automatica-33.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<p><strong>5) <\/strong>On the <strong>Mirror Azure SQL Database<\/strong> window, type the name <em>Adventure:<\/p>\n<p><\/em> <img loading=\"lazy\" decoding=\"async\" width=\"458\" height=\"377\" class=\"wp-image-102109\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-description-automatica-34.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<p><strong>6) <\/strong>On the <strong>Mirror Database<\/strong> window, under <strong>New Connection<\/strong>, click <strong>Azure SQL Database<\/p>\n<p><\/strong> <img loading=\"lazy\" decoding=\"async\" width=\"1534\" height=\"385\" class=\"wp-image-102110\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-white-rectangular-object-with-a-black-border-de.png\" alt=\"A white rectangular object with a black border\n\nDescription automatically generated with medium confidence\" \/><\/p>\n<p><strong>7) <\/strong>On the <strong>New Connection<\/strong> window, <strong>Server<\/strong> textbox, type the address of the <strong>Azure SQL Database<\/strong><\/p>\n<p><strong>8) <\/strong>On the <strong>Database<\/strong> textbox, type the name of the database.<\/p>\n<p><strong>9) <\/strong>On the <strong>Connection Name<\/strong> textbox, you can customize the name of the connection:<br \/>\n<img loading=\"lazy\" decoding=\"async\" width=\"690\" height=\"579\" class=\"wp-image-102111\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-description-automatica-35.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<h2>Mirroring Security<\/h2>\n<p>Before we continue with the walkthrough, we need to discuss security for a moment. The security of the mirroring solution involves two important considerations: Authentication and Network Access.<\/p>\n<h3>Authentication<\/h3>\n<p>There are 3 types of authentications supported:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"378\" height=\"128\" class=\"wp-image-102112\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-description-automatica-36.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<h4>Basic Authentication<\/h4>\n<p>SQL authentication with a user and password. Is the least secure one, and should only rarely be used, when you don\u2019t have the others available.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"424\" height=\"221\" class=\"wp-image-102113\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-description-automatica-37.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<h4>Organizational Account<\/h4>\n<p>This is the easiest way to implement, but it has many problems. Let\u2019s say this implementation option has two levels of laziness. The consequence of the implementation depends on the level of laziness.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"377\" height=\"122\" class=\"wp-image-102114\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screen-shot-of-a-computer-screen-description-au.png\" alt=\"A screen shot of a computer screen\n\nDescription automatically generated\" \/><\/p>\n<p><strong>Laziness level 1:<\/strong> Use your own Azure Entra user account for the authentication. In this scenario, the implementation is tied with your account. What happens when your password changes? When you leave the company?<\/p>\n<p><strong>Laziness level 2:<\/strong> Create a custom account to be used only by this service. This helps, but the account would still be subject to all protection policies on Azure Entra. This can create problems for the implementation. The password policies and others working over the account may stop the service out of the blue. The solution architect would need to exclude this account from all policy applications for this to work, and it would be subject to mistakes.<\/p>\n<p><strong>Correct Method:<\/strong> Use a <em>Service Principal<\/em><\/p>\n<h4>Service Principal<\/h4>\n<p>This is the safest option, but the most complex to implement. It requires an <strong>App Registration<\/strong> on <strong>Entra Id<\/strong>. The App Registration provides a client Id and key which allow it to be configured in services like the mirroring in Power BI.<\/p>\n<p>The App Registration is not subject to the same policies as a regular user.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"380\" height=\"191\" class=\"wp-image-102115\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-description-automatica-38.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<p>Check details about <a href=\"https:\/\/learn.microsoft.com\/en-us\/entra\/identity-platform\/quickstart-register-app\">App Registration<\/a><\/p>\n<h3>Network Access<\/h3>\n<p>Fabric and Azure can be on a single Tenant, but they are on different networks. If we try a direct access from Fabric to Azure, the following will happen:<\/p>\n<ul>\n<li>The connection may pass through public internet.<\/li>\n<li>The connection will be subject to the firewall of the Azure object<\/li>\n<\/ul>\n<p>We need a good method to make the connection work in a safe way.<\/p>\n<h4>The Wrong and lazy way<\/h4>\n<p><strong>Azure SQL<\/strong> has a firewall control. In order to allow <strong>Fabric to <\/strong>bypass the Firewall, we should enable the option <em>\u201cAllow Azure Services and resources to access this server\u201d.<\/em><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"389\" height=\"80\" class=\"wp-image-102116\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-black-text-on-a-white-background-description-au.png\" alt=\"A black text on a white background\n\nDescription automatically generated\" \/><\/p>\n<p>The problem with this option is that we are basically disabling one layer of security for any attempt of connection coming from Azure Services or Power BI.<\/p>\n<p>I explain <a href=\"https:\/\/www.youtube.com\/watch?v=RKZy5MkqFDQ&amp;list=PLNbt9tnNIlQ5pVwZFRVpoBG8uQTs8aIcz&amp;index=41\">on this video<\/a> why this is a bad idea and some other concepts of Azure SQL Security.<\/p>\n<h4>Using a Private Endpoint<\/h4>\n<p>Private endpoints are a recent new feature in <strong>Microsoft Fabric<\/strong>. We can create a private endpoint to bring an Azure Resource to inside a virtual managed network in Fabric.<\/p>\n<p><em>In this way, the connection would stay completely private and secure.<\/em><\/p>\n<p>I recorded a video about how to use <a href=\"https:\/\/www.youtube.com\/watch?v=mWC8LOLKGgg\">Fabric Private Endpoint<\/a><\/p>\n<h4>The Future: Workspace Identities and Trusted Workspace Access<\/h4>\n<p>Workspace Identities and Trusted workspaces is a new feature to allow a secure connection from Fabric to Azure.<\/p>\n<p>At this moment these features only allow the connection to storage accounts, but soon it will be possible to use these features to connect to other resources, such as Azure SQL.<\/p>\n<p><a href=\"https:\/\/learn.microsoft.com\/en-us\/fabric\/security\/workspace-identity#how-to-use-workspace-identity\">Read more about Workspace Identities<\/a><\/p>\n<p><a href=\"https:\/\/blog.fabric.microsoft.com\/en-us\/blog\/introducing-trusted-workspace-access-for-onelake-shortcuts?ft=11-2023:date\">Read more about Trusted Workspaces<\/a><\/p>\n<h2>Continuing the Walkthrough<\/h2>\n<p>Now that you know the security issues involved with the connection and are ready to configure the authentication to Azure SQL, let\u2019s continue the walkthrough.<\/p>\n<p>We will start back, using the choices made about the authentication and network access method.<\/p>\n<p><strong>10) <\/strong>After configuring the authentication, click the <strong>Connect<\/strong> button on the lower right side of the window.<\/p>\n<p><strong>11) <\/strong>Disable the option <strong>Mirror All Data<\/strong><\/p>\n<p>You can mirror all the data if you would like, but to choose only some tables, you need to disable this option.<\/p>\n<p><strong>12) <\/strong>Select the tables to mirror. In my example, I will select <em>DimProduct<\/em>, <em>DimCustomer<\/em> and <em>FactInternetSales<\/p>\n<p><\/em> <img loading=\"lazy\" decoding=\"async\" width=\"1530\" height=\"754\" class=\"wp-image-102117\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-description-automatica-39.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<p><strong>13) <\/strong>Click the <strong>Mirror Database<\/strong> button.<\/p>\n<p><strong>14) <\/strong>On the top of the window, click the <strong>Monitor Replication<\/strong> button <\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"686\" height=\"168\" class=\"wp-image-102118\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-description-automatica-40.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<p>There is another button with the same purpose on the centre of the replication object window as well.<\/p>\n<p><strong>15) <\/strong>On the <strong>monitoring mirrored database<\/strong> window, the <strong>Total replicated rows<\/strong> will be empty until all rows are replicated. <br \/>\n<img loading=\"lazy\" decoding=\"async\" width=\"929\" height=\"529\" class=\"wp-image-102119\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-description-automatica-41.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<p><strong>16) <\/strong>Close the monitoring window.<\/p>\n<p><strong>17) <\/strong>Click the settings button on the top of the window.<\/p>\n<p><strong>18) <\/strong>Click the <strong>SQL Endpoint<\/strong> tab.<\/p>\n<p>This illustrates the presence of a SQL Endpoint and the address to connect to it from SSMS. <\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"929\" height=\"248\" class=\"wp-image-102120\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-description-automatica-42.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<p><strong>19) <\/strong>Close the settings window.<\/p>\n<p><strong>20) <\/strong>On the left bar, close the <em>Adventure<\/em> object <br \/>\n<img loading=\"lazy\" decoding=\"async\" width=\"76\" height=\"75\" class=\"wp-image-102121\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-description-automatica-43.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<p>This is how the workspace should be at this point:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"856\" height=\"529\" class=\"wp-image-102122\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-description-automatica-44.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<h2>Testing the Mirroring<\/h2>\n<p>Let\u2019s confirm the mirroring is working and continuously updating <strong>Fabric<\/strong> with new information from <strong>Azure SQL<\/strong><\/p>\n<p><strong>21) <\/strong>Open the <em>Adventure<\/em> <strong>SQL Endpoint<\/strong><\/p>\n<p>The names of the mirrored tables are creating concatenating the schema of the tables with the name. For example, <em>dbo.DimCustomer<\/em> will become <em>dbo.dbo_DimCustomer<br \/>\n<\/em> <img loading=\"lazy\" decoding=\"async\" width=\"311\" height=\"661\" class=\"wp-image-102123\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-description-automatica-45.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<p><strong>22) <\/strong>Click on the <strong>New Query<\/strong> button<\/p>\n<p><strong>23) <\/strong>Execute the following query:<\/p>\n<p><code>select * from dbo_DimCustomer<\/code><br \/>\n<code>where FirstName='Jon' and LastName='Yang'<\/p>\n<p><\/code> <img loading=\"lazy\" decoding=\"async\" width=\"711\" height=\"271\" class=\"wp-image-102124\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-description-automatica-46.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<p><strong>24) <\/strong>Open <strong>SSMS<\/strong><\/p>\n<p><strong>25) <\/strong>Connect to your <strong>Azure SQL<\/p>\n<p><\/strong> <img loading=\"lazy\" decoding=\"async\" width=\"444\" height=\"198\" class=\"wp-image-102125\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-description-automatica-47.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<p><strong>26) <\/strong>Update the<em> EnglishOccupation<\/em> field of the same record <\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"693\" height=\"73\" class=\"wp-image-102126\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/word-image-102097-29.png\" \/><\/p>\n<p><strong>27) <\/strong>Query this row to confirm it\u2019s updated <\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"534\" height=\"109\" class=\"wp-image-102127\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-description-automatica-48.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/> <br \/>\nYou should get the following output:<br \/>\n<img loading=\"lazy\" decoding=\"async\" width=\"707\" height=\"96\" class=\"wp-image-102128\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-description-automatica-49.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<p><strong>28) <\/strong>On the <strong>SQL Endpoint<\/strong>, query the same record <\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"704\" height=\"270\" class=\"wp-image-102129\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-description-automatica-50.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<p>In this way, we could see the mirroring in action, synchronizing updates between <strong>Azure SQL<\/strong> and <strong>Fabric<\/strong><\/p>\n<p><strong>29) <\/strong>Close the <strong>SQL Endpoint<\/strong><\/p>\n<h2>Creating a Shortcut<\/h2>\n<p>As mentioned before, you will need to create pipelines to transform the mirrored data from the production model to a Data Intelligence model.<\/p>\n<p>However, it\u2019s possible some secondary tables may not need transformation. In this case, the possibility to create a shortcut will avoid data duplication in <strong>OneLake<\/strong><\/p>\n<p><strong>30) <\/strong>Open the <em>BronzeLake<\/em> lakehouse<\/p>\n<p><strong>31) <\/strong>Right click the <strong>Tables<\/strong> folder<\/p>\n<p><strong>32) <\/strong>Click <strong>New Shortcut<\/strong> menu item <\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"501\" height=\"413\" class=\"wp-image-102130\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-description-automatica-51.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<ol>\n<li>On the <em>Select a data source type<\/em> window, select <em>Adventure<\/em><\/li>\n<\/ol>\n<p>This illustrates the Mirrored Database can be used as source for shortcuts <\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1274\" height=\"719\" class=\"wp-image-102131\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-description-automatica-52.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<p><strong>34) <\/strong>Click <strong>Next<\/strong> button<\/p>\n<p><strong>35) <\/strong>On the <strong>New Shortcut<\/strong> window, select the table <em>dbo_DimCustomer<\/p>\n<p><\/em> <img loading=\"lazy\" decoding=\"async\" width=\"1277\" height=\"718\" class=\"wp-image-102132\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-description-automatica-53.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<p><strong>36) <\/strong>Click <strong>Next<\/strong> button<\/p>\n<p><strong>37) <\/strong>Click the <strong>Create<\/strong> button <\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-102133\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-description-automatica-54.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" width=\"784\" height=\"442\" \/> <br \/>\n<img loading=\"lazy\" decoding=\"async\" width=\"270\" height=\"354\" class=\"wp-image-102134\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/04\/a-screenshot-of-a-computer-description-automatica-55.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<h2>Summary<\/h2>\n<p>The mirroring feature can be very useful if used correctly, but still has a long way to go. You can also check <a href=\"https:\/\/www.kevinrchant.com\/2024\/04\/08\/initial-testing-of-mirroring-azure-cosmos-db-databases-in-microsoft-fabric\/\">Kevin Chant article about mirroring with CosmoDB<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Finally, mirroring is available for Fabric! You can mirror an Azure SQL to Fabric. It works for CosmoDB and Snowflake as well, but in this article, I will focus on Azure SQL. It is 100%, no, but it is definitely a feature that is really great even now. Before getting into a step-by-step of the&#8230;&hellip;<\/p>\n","protected":false},"author":50808,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143528,53,159164],"tags":[158997],"coauthors":[6810],"class_list":["post-102097","post","type-post","status-publish","format-standard","hentry","category-bi-sql-server","category-featured","category-microsoft-fabric","tag-microsoft-fabric"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/102097","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/50808"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=102097"}],"version-history":[{"count":6,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/102097\/revisions"}],"predecessor-version":[{"id":102140,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/102097\/revisions\/102140"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=102097"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=102097"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=102097"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=102097"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}