<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kunu Wako</title>
    <description>The latest articles on DEV Community by Kunu Wako (@kunu_wako).</description>
    <link>https://dev.to/kunu_wako</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4070909%2F651a0673-6713-44a4-a786-f2b59fc2b93d.png</url>
      <title>DEV Community: Kunu Wako</title>
      <link>https://dev.to/kunu_wako</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kunu_wako"/>
    <language>en</language>
    <item>
      <title>Power BI Data Modelling, Relationships &amp; Joins</title>
      <dc:creator>Kunu Wako</dc:creator>
      <pubDate>Sun, 13 Sep 2026 11:30:35 +0000</pubDate>
      <link>https://dev.to/kunu_wako/power-bi-data-modelling-relationships-joins-hdm</link>
      <guid>https://dev.to/kunu_wako/power-bi-data-modelling-relationships-joins-hdm</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Data modelling involves organizing tables, defining relationships between them, determining how filters move through the model, and deciding how business data should be represented for analysis. In a typical business intelligence environment, data may come from databases, Excel files, APIs, enterprise systems, or cloud platforms. These sources often contain related information in separate tables. For example, a retail company may maintain customers in one table, products in another, transactions in a sales table, and calendar information in a date table. Power BI must understand how these tables are related before it can correctly answer questions such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which products generated the most revenue?&lt;/li&gt;
&lt;li&gt;How much did each customer spend?&lt;/li&gt;
&lt;li&gt;Which region recorded the highest sales?&lt;/li&gt;
&lt;li&gt;How did monthly revenue change over time?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article explores the major concepts involved in building such a model: &lt;strong&gt;flat tables, star schemas, snowflake schemas, fact and dimension tables, relationships, cardinality, filter direction, Power Query joins, and the difference between joins and model relationships&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  1. Data Modelling in Power BI
&lt;/h1&gt;

&lt;p&gt;As defined above, data modelling in Power BI is the process of structuring data into logically related tables so that it can be efficiently analyzed. A good model makes it easier for Power BI to determine how information from different tables should interact. Microsoft's Power BI guidance recommends models in which dimension tables are generally used for &lt;strong&gt;filtering and grouping&lt;/strong&gt;, while fact tables are used for &lt;strong&gt;summarization&lt;/strong&gt;. Microsoft also recommends maintaining fact tables at a consistent grain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Data Modelling Matters
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Reporting
&lt;/h3&gt;

&lt;p&gt;Report developers can easily understand which fields should be placed in slicers, axes, tables, and measures. A clear model makes calculations easier to write.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;Total&lt;/span&gt; &lt;span class="n"&gt;Sales&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FactSales&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;SalesAmount&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With a properly related &lt;code&gt;DimProduct&lt;/code&gt; table, the same measure automatically works when the report is filtered by product, brand, or category.&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance
&lt;/h3&gt;

&lt;p&gt;Poorly designed models can contain unnecessary columns, repeated descriptive information, excessive relationships, or ambiguous filter paths. A simplified star-shaped model normally allows Power BI to evaluate queries more predictably.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scalability
&lt;/h3&gt;

&lt;p&gt;A model containing a million sales transactions should not need the customer's name, location, category, and other descriptive values repeatedly stored in every sales row. Dimensions allow descriptive data to be stored separately and reused.&lt;/p&gt;

&lt;h3&gt;
  
  
  Maintainability
&lt;/h3&gt;

&lt;p&gt;Logical separation makes troubleshooting easier. If product descriptions change, developers know to investigate the product dimension instead of searching a massive sales table.&lt;/p&gt;




&lt;h1&gt;
  
  
  2. Flat Table Model
&lt;/h1&gt;

&lt;p&gt;A flat table stores most or all information in one table.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;OrderID&lt;/th&gt;
&lt;th&gt;Date&lt;/th&gt;
&lt;th&gt;Customer&lt;/th&gt;
&lt;th&gt;County&lt;/th&gt;
&lt;th&gt;Product&lt;/th&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Quantity&lt;/th&gt;
&lt;th&gt;UnitPrice&lt;/th&gt;
&lt;th&gt;SalesAmount&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1001&lt;/td&gt;
&lt;td&gt;2026-09-01&lt;/td&gt;
&lt;td&gt;Amina&lt;/td&gt;
&lt;td&gt;Nairobi&lt;/td&gt;
&lt;td&gt;Laptop&lt;/td&gt;
&lt;td&gt;Electronics&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;85000&lt;/td&gt;
&lt;td&gt;85000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1002&lt;/td&gt;
&lt;td&gt;2026-09-01&lt;/td&gt;
&lt;td&gt;Brian&lt;/td&gt;
&lt;td&gt;Nakuru&lt;/td&gt;
&lt;td&gt;Mouse&lt;/td&gt;
&lt;td&gt;Accessories&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;1500&lt;/td&gt;
&lt;td&gt;3000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1003&lt;/td&gt;
&lt;td&gt;2026-09-02&lt;/td&gt;
&lt;td&gt;Amina&lt;/td&gt;
&lt;td&gt;Nairobi&lt;/td&gt;
&lt;td&gt;Keyboard&lt;/td&gt;
&lt;td&gt;Accessories&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;4500&lt;/td&gt;
&lt;td&gt;4500&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The table combines transaction information with customer, location, product, and date attributes. There are no relationships because all the required information exists inside the same table.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advantages
&lt;/h2&gt;

&lt;p&gt;A flat table is simple to understand and can be appropriate for small datasets or quick exploratory analyses. It also avoids the need to create relationships because visualizations can reference columns directly from one table.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disadvantages
&lt;/h2&gt;

&lt;p&gt;The biggest problem is &lt;strong&gt;data repetition&lt;/strong&gt;. If a customer makes 10,000 purchases, their name, county, and other customer details may appear 10,000 times. This creates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;unnecessary redundancy&lt;/li&gt;
&lt;li&gt;larger models&lt;/li&gt;
&lt;li&gt;more difficult maintenance&lt;/li&gt;
&lt;li&gt;less intuitive organization&lt;/li&gt;
&lt;li&gt;potential data quality problems&lt;/li&gt;
&lt;li&gt;reduced scalability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A flat table can also make it difficult to distinguish between descriptive attributes and measurable business events.&lt;br&gt;
A flat table can be useful when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the dataset is small&lt;/li&gt;
&lt;li&gt;there is only one analytical subject&lt;/li&gt;
&lt;li&gt;a report is temporary&lt;/li&gt;
&lt;li&gt;the source is already highly simplified&lt;/li&gt;
&lt;li&gt;the model contains few columns&lt;/li&gt;
&lt;li&gt;complex analytical relationships are unnecessary&lt;/li&gt;
&lt;/ul&gt;


&lt;h1&gt;
  
  
  3. Star Schema
&lt;/h1&gt;

&lt;p&gt;A &lt;strong&gt;star schema&lt;/strong&gt; consists of a central fact table surrounded by dimension tables. The fact table contains measurable business events while dimensions contain information describing those events. The structure resembles a star, which gives the schema its name.&lt;/p&gt;

&lt;p&gt;Consider a retail sales model:&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart TB
    CUSTOMER["DimCustomer&amp;lt;br/&amp;gt;CustomerID&amp;lt;br/&amp;gt;CustomerName&amp;lt;br/&amp;gt;Segment"]
    PRODUCT["DimProduct&amp;lt;br/&amp;gt;ProductID&amp;lt;br/&amp;gt;ProductName&amp;lt;br/&amp;gt;Category"]
    DATE["DimDate&amp;lt;br/&amp;gt;DateKey&amp;lt;br/&amp;gt;Date&amp;lt;br/&amp;gt;Month&amp;lt;br/&amp;gt;Year"]
    LOCATION["DimLocation&amp;lt;br/&amp;gt;LocationID&amp;lt;br/&amp;gt;County&amp;lt;br/&amp;gt;Region"]

    SALES["FactSales&amp;lt;br/&amp;gt;SaleID&amp;lt;br/&amp;gt;CustomerID&amp;lt;br/&amp;gt;ProductID&amp;lt;br/&amp;gt;DateKey&amp;lt;br/&amp;gt;LocationID&amp;lt;br/&amp;gt;Quantity&amp;lt;br/&amp;gt;SalesAmount"]

    CUSTOMER --&amp;gt; SALES
    PRODUCT --&amp;gt; SALES
    DATE --&amp;gt; SALES
    LOCATION --&amp;gt; SALES&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjy914ezkejg9fllby7hs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjy914ezkejg9fllby7hs.png" alt=" " width="800" height="505"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Advantages
&lt;/h2&gt;

&lt;p&gt;A star schema provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;clear separation of facts and dimensions&lt;/li&gt;
&lt;li&gt;simple relationships&lt;/li&gt;
&lt;li&gt;simpler DAX&lt;/li&gt;
&lt;li&gt;predictable filter propagation&lt;/li&gt;
&lt;li&gt;improved model readability&lt;/li&gt;
&lt;li&gt;easier reporting&lt;/li&gt;
&lt;li&gt;good scalability&lt;/li&gt;
&lt;li&gt;reduced duplication of descriptive attributes&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Disadvantages
&lt;/h2&gt;

&lt;p&gt;Creating a star schema normally requires some preparation. Source systems frequently do not provide perfectly structured fact and dimension tables, so developers may need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;clean data&lt;/li&gt;
&lt;li&gt;create surrogate keys&lt;/li&gt;
&lt;li&gt;remove duplicates&lt;/li&gt;
&lt;li&gt;build dimension tables&lt;/li&gt;
&lt;li&gt;combine multiple operational sources&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A star schema can therefore require more initial modelling work than simply loading one flat spreadsheet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Appropriate Situations
&lt;/h2&gt;

&lt;p&gt;Star schemas are particularly suitable for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sales analysis&lt;/li&gt;
&lt;li&gt;financial reporting&lt;/li&gt;
&lt;li&gt;inventory reporting&lt;/li&gt;
&lt;li&gt;marketing analytics&lt;/li&gt;
&lt;li&gt;customer analytics&lt;/li&gt;
&lt;li&gt;operational dashboards&lt;/li&gt;
&lt;li&gt;enterprise BI systems&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  4. Snowflake Schema
&lt;/h1&gt;

&lt;p&gt;A &lt;strong&gt;snowflake schema&lt;/strong&gt; extends a star schema by further normalizing dimensions into related tables. For example, instead of keeping category information inside &lt;code&gt;DimProduct&lt;/code&gt;, product categories may have their own table.&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart LR
    CATEGORY["DimCategory&amp;lt;br/&amp;gt;CategoryID&amp;lt;br/&amp;gt;CategoryName"]
    PRODUCT["DimProduct&amp;lt;br/&amp;gt;ProductID&amp;lt;br/&amp;gt;ProductName&amp;lt;br/&amp;gt;CategoryID"]
    SALES["FactSales&amp;lt;br/&amp;gt;SaleID&amp;lt;br/&amp;gt;ProductID&amp;lt;br/&amp;gt;CustomerID&amp;lt;br/&amp;gt;DateKey&amp;lt;br/&amp;gt;SalesAmount"]
    CUSTOMER["DimCustomer"]
    DATE["DimDate"]

    CATEGORY --&amp;gt; PRODUCT
    PRODUCT --&amp;gt; SALES
    CUSTOMER --&amp;gt; SALES
    DATE --&amp;gt; SALES&lt;/code&gt;&lt;/pre&gt;



&lt;h2&gt;
  
  
  Advantages
&lt;/h2&gt;

&lt;p&gt;Snowflaking can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;reduce duplicated dimension attributes&lt;/li&gt;
&lt;li&gt;represent complex organizational hierarchies&lt;/li&gt;
&lt;li&gt;closely reflect normalized warehouse structures&lt;/li&gt;
&lt;li&gt;allow some dimensions to be reused&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Disadvantages
&lt;/h2&gt;

&lt;p&gt;The model contains more tables and relationships. This can create:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;more complex filter paths&lt;/li&gt;
&lt;li&gt;a less intuitive Fields pane&lt;/li&gt;
&lt;li&gt;more relationships to maintain&lt;/li&gt;
&lt;li&gt;more work for report developers&lt;/li&gt;
&lt;li&gt;potentially more complex queries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Snowflake structures can make sense where dimensions contain substantial reusable hierarchies or where the Power BI model intentionally reflects an existing enterprise data warehouse. However, unnecessary snowflaking should generally be avoided where dimension tables can reasonably be flattened.&lt;/p&gt;




&lt;h1&gt;
  
  
  5. Comparing the Three Modelling Approaches
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Characteristic&lt;/th&gt;
&lt;th&gt;Flat Table&lt;/th&gt;
&lt;th&gt;Star Schema&lt;/th&gt;
&lt;th&gt;Snowflake Schema&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Number of tables&lt;/td&gt;
&lt;td&gt;Usually one&lt;/td&gt;
&lt;td&gt;Several&lt;/td&gt;
&lt;td&gt;Several/many&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Complexity&lt;/td&gt;
&lt;td&gt;Low initially&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;td&gt;Higher&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data redundancy&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Low/moderate&lt;/td&gt;
&lt;td&gt;Lowest&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Relationships&lt;/td&gt;
&lt;td&gt;Few/none&lt;/td&gt;
&lt;td&gt;Simple&lt;/td&gt;
&lt;td&gt;More complex&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DAX usability&lt;/td&gt;
&lt;td&gt;Acceptable for simple models&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;td&gt;Can be more complex&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scalability&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Model readability&lt;/td&gt;
&lt;td&gt;Declines as table grows&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BI suitability&lt;/td&gt;
&lt;td&gt;Small/simple analysis&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;td&gt;Specialized scenarios&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maintenance&lt;/td&gt;
&lt;td&gt;Difficult at scale&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;td&gt;More relationships to manage&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For most Power BI business intelligence solutions, the &lt;strong&gt;star schema offers the best balance between performance, usability and maintainability&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  6. Fact Tables and Dimension Tables
&lt;/h1&gt;

&lt;p&gt;The distinction between fact and dimension tables is fundamental to dimensional modelling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fact Tables
&lt;/h2&gt;

&lt;p&gt;A fact table records &lt;strong&gt;business events&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a sale&lt;/li&gt;
&lt;li&gt;an order&lt;/li&gt;
&lt;li&gt;a payment&lt;/li&gt;
&lt;li&gt;a website visit&lt;/li&gt;
&lt;li&gt;a bank transaction&lt;/li&gt;
&lt;li&gt;an inventory movement&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frfr3yif17dh6ev6nlqf3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frfr3yif17dh6ev6nlqf3.png" alt=" " width="800" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fact tables are normally the largest tables in analytical systems.&lt;/p&gt;




&lt;h1&gt;
  
  
  7. Dimension Tables
&lt;/h1&gt;

&lt;p&gt;Dimension tables contain descriptive information used to classify, filter, and group business events. Microsoft describes dimension tables as tables that support filtering and grouping, whereas fact tables support summarization. &lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzaeoj5u69qoy3uygco3i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzaeoj5u69qoy3uygco3i.png" alt=" " width="566" height="607"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5kbubbc6bmud64zc8lgk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5kbubbc6bmud64zc8lgk.png" alt=" " width="777" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Typical dimensions include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;DimCustomer&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DimProduct&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DimDate&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DimLocation&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DimEmployee&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DimSupplier&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  8. Measures Versus Descriptive Attributes
&lt;/h1&gt;

&lt;p&gt;An easy way to understand the distinction is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DIMENSIONS describe:
Who?
What?
Where?
When?

FACTS measure:
How many?
How much?
How long?
How often?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CustomerName ─┐
ProductName  ─┼──► describe the sale
County       ─┤
Month        ─┘

Quantity     ─┐
Revenue      ─┼──► measure the sale
Profit       ─┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A report might therefore ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What was &lt;strong&gt;Total Sales&lt;/strong&gt; by &lt;strong&gt;Product Category&lt;/strong&gt; in &lt;strong&gt;Nairobi&lt;/strong&gt; during &lt;strong&gt;August 2026&lt;/strong&gt;?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this question:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Total Sales = fact/measure&lt;/li&gt;
&lt;li&gt;Product Category = dimension&lt;/li&gt;
&lt;li&gt;Nairobi = dimension&lt;/li&gt;
&lt;li&gt;August 2026 = dimension&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  9. Grain or Granularity
&lt;/h1&gt;

&lt;p&gt;The &lt;strong&gt;grain&lt;/strong&gt; of a fact table defines what one row represents. This must be decided before designing the table. For example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;One row in &lt;code&gt;FactSales&lt;/code&gt; represents one product line on one customer transaction.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Suppose order &lt;code&gt;ORD1001&lt;/code&gt; contains three products.&lt;/p&gt;

&lt;p&gt;The fact table would contain three rows:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;OrderID&lt;/th&gt;
&lt;th&gt;ProductID&lt;/th&gt;
&lt;th&gt;Quantity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ORD1001&lt;/td&gt;
&lt;td&gt;P01&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ORD1001&lt;/td&gt;
&lt;td&gt;P03&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ORD1001&lt;/td&gt;
&lt;td&gt;P09&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The grain is therefore not one row per order but one row per product per order.&lt;/p&gt;

&lt;p&gt;Mixing different grains in the same fact table can produce incorrect aggregations. Microsoft specifically recommends that fact tables load data at a consistent grain. &lt;/p&gt;




&lt;h1&gt;
  
  
  10. Practical Star Schema Example
&lt;/h1&gt;

&lt;p&gt;Consider an electronics retailer.&lt;/p&gt;

&lt;p&gt;The company wants to analyze:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sales by month;&lt;/li&gt;
&lt;li&gt;sales by customer;&lt;/li&gt;
&lt;li&gt;revenue by county;&lt;/li&gt;
&lt;li&gt;sales by product category;&lt;/li&gt;
&lt;li&gt;quantity sold by product.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A suitable model is:&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart TB
    C["DimCustomer&amp;lt;br/&amp;gt;CustomerID (PK)&amp;lt;br/&amp;gt;CustomerName&amp;lt;br/&amp;gt;Segment"]
    P["DimProduct&amp;lt;br/&amp;gt;ProductID (PK)&amp;lt;br/&amp;gt;ProductName&amp;lt;br/&amp;gt;Category"]
    D["DimDate&amp;lt;br/&amp;gt;DateKey (PK)&amp;lt;br/&amp;gt;Date&amp;lt;br/&amp;gt;Month&amp;lt;br/&amp;gt;Quarter&amp;lt;br/&amp;gt;Year"]
    L["DimLocation&amp;lt;br/&amp;gt;LocationID (PK)&amp;lt;br/&amp;gt;County&amp;lt;br/&amp;gt;Region"]

    F["FactSales&amp;lt;br/&amp;gt;SaleID&amp;lt;br/&amp;gt;CustomerID (FK)&amp;lt;br/&amp;gt;ProductID (FK)&amp;lt;br/&amp;gt;DateKey (FK)&amp;lt;br/&amp;gt;LocationID (FK)&amp;lt;br/&amp;gt;Quantity&amp;lt;br/&amp;gt;SalesAmount"]

    C --&amp;gt;|1 : many| F
    P --&amp;gt;|1 : many| F
    D --&amp;gt;|1 : many| F
    L --&amp;gt;|1 : many| F&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;Each dimension contains unique keys while those keys can occur repeatedly in the fact table.&lt;/p&gt;




&lt;h1&gt;
  
  
  11. Relationships in Power BI
&lt;/h1&gt;

&lt;p&gt;A &lt;strong&gt;relationship&lt;/strong&gt; defines how two tables are logically connected. Suppose customer information is stored in &lt;code&gt;DimCustomer&lt;/code&gt; and transactions are stored in &lt;code&gt;FactSales&lt;/code&gt;. Without a relationship, Power BI does not automatically know which sales belong to which customer.&lt;br&gt;
The relationship might be:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft42bbme4k3z771ojq1l9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft42bbme4k3z771ojq1l9.png" alt=" " width="393" height="367"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h1&gt;
  
  
  12. Primary and Foreign Keys
&lt;/h1&gt;
&lt;h2&gt;
  
  
  Primary Key
&lt;/h2&gt;

&lt;p&gt;A primary key uniquely identifies each record in a table.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;
&lt;h3&gt;
  
  
  DimCustomer
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;CustomerID&lt;/th&gt;
&lt;th&gt;CustomerName&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;C001&lt;/td&gt;
&lt;td&gt;Amina&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C002&lt;/td&gt;
&lt;td&gt;Brian&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C003&lt;/td&gt;
&lt;td&gt;Carol&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;CustomerID&lt;/code&gt; contains unique values.&lt;/p&gt;

&lt;p&gt;It can therefore identify a particular customer.&lt;/p&gt;
&lt;h2&gt;
  
  
  Foreign Key
&lt;/h2&gt;

&lt;p&gt;A foreign key points to the corresponding key in another table.&lt;/p&gt;
&lt;h3&gt;
  
  
  FactSales
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;SaleID&lt;/th&gt;
&lt;th&gt;CustomerID&lt;/th&gt;
&lt;th&gt;Amount&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;S01&lt;/td&gt;
&lt;td&gt;C001&lt;/td&gt;
&lt;td&gt;2500&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S02&lt;/td&gt;
&lt;td&gt;C001&lt;/td&gt;
&lt;td&gt;5000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S03&lt;/td&gt;
&lt;td&gt;C002&lt;/td&gt;
&lt;td&gt;1200&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S04&lt;/td&gt;
&lt;td&gt;C001&lt;/td&gt;
&lt;td&gt;800&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;C001&lt;/code&gt; appears multiple times because Amina can make several purchases.&lt;/p&gt;

&lt;p&gt;Therefore:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DimCustomer                  FactSales

CustomerID                   CustomerID
-----------                  ----------
C001 ─────────────────────── C001
  │                          C001
  │                          C001
C002 ─────────────────────── C002
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This produces a &lt;strong&gt;one-to-many relationship&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  13. Cardinality
&lt;/h1&gt;

&lt;p&gt;Cardinality describes how rows from one table correspond to rows in another table. Power BI supports relationship types including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one-to-many;&lt;/li&gt;
&lt;li&gt;one-to-one;&lt;/li&gt;
&lt;li&gt;many-to-many.&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  14. One-to-Many Relationship (1:*)
&lt;/h1&gt;

&lt;p&gt;This is the most common relationship in a Power BI star schema.&lt;/p&gt;

&lt;p&gt;One row on the dimension side can correspond to many rows in the fact table.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DimCustomer          FactSales

C001 ─────────────── S001
  │                  S002
  └───────────────── S008

C002 ─────────────── S003
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model relationship is:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fywdpkaebsww6a9goo5mj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fywdpkaebsww6a9goo5mj.png" alt=" " width="315" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the &lt;code&gt;1&lt;/code&gt; side to work correctly, the dimension key must contain unique values.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to Use It
&lt;/h2&gt;

&lt;p&gt;It is ideal for relationships such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer → Sales
Product  → Sales
Date     → Sales
Location → Sales
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should normally be the dominant relationship pattern in a star schema.&lt;/p&gt;




&lt;h1&gt;
  
  
  15. One-to-One Relationship (1:1)
&lt;/h1&gt;

&lt;p&gt;In a one-to-one relationship, each key occurs only once in each table.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Employee                         EmployeeSecurity
EmployeeID                       EmployeeID
----------                       ----------
E001 ─────────────────────────── E001
E002 ─────────────────────────── E002
E003 ─────────────────────────── E003
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each employee has exactly one corresponding security profile.&lt;/p&gt;

&lt;p&gt;Possible reasons for such a design include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;separating sensitive information&lt;/li&gt;
&lt;li&gt;combining data from separate systems&lt;/li&gt;
&lt;li&gt;temporarily extending an existing entity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, a one-to-one relationship can sometimes indicate that the two tables should simply be combined. Microsoft notes that one-to-one relationships always filter in both directions and generally recommends considering alternative modelling designs before using them extensively.&lt;/p&gt;




&lt;h1&gt;
  
  
  16. Many-to-Many Relationships (&lt;em&gt;:&lt;/em&gt;)
&lt;/h1&gt;

&lt;p&gt;A many-to-many relationship occurs when multiple rows from one side can relate to multiple rows from the other. Consider students and courses. A student may register for several courses, and each course may contain several students.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Students                     Courses

Alice ─────────────┐      ┌─ Data Engineering
                   ├──────┤
                   │      └─ Machine Learning
                   │
Brian ─────────────┼──────── Data Engineering
                   │
                   └──────── Power BI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In relational modelling, this is usually resolved with a bridge table:&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart LR
    S["DimStudent&amp;lt;br/&amp;gt;StudentID"]
    B["BridgeEnrollment&amp;lt;br/&amp;gt;StudentID&amp;lt;br/&amp;gt;CourseID"]
    C["DimCourse&amp;lt;br/&amp;gt;CourseID"]

    S --&amp;gt;|1 : many| B
    C --&amp;gt;|1 : many| B&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;The bridge table converts the conceptual many-to-many relationship into two one-to-many relationships. Direct many-to-many relationships are supported by Power BI, but they should be used deliberately because they can make filter behavior and calculations harder to reason about.&lt;/p&gt;




&lt;h1&gt;
  
  
  17. Referential Integrity
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Referential integrity&lt;/strong&gt; means that foreign-key values correctly reference corresponding records.&lt;/p&gt;

&lt;p&gt;Suppose &lt;code&gt;FactSales&lt;/code&gt; contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CustomerID = C900
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but there is no &lt;code&gt;C900&lt;/code&gt; in &lt;code&gt;DimCustomer&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The sales row has no matching customer dimension record. Ideally, every sale has a matching customer ID. Maintaining referential integrity prevents unexplained or unmatched records and produces more reliable analytics.&lt;/p&gt;




&lt;h1&gt;
  
  
  18. Active and Inactive Relationships
&lt;/h1&gt;

&lt;p&gt;Power BI relationships can be &lt;strong&gt;active&lt;/strong&gt; or &lt;strong&gt;inactive&lt;/strong&gt;. An active relationship is automatically used during filter propagation. It appears as a solid relationship line in Model View.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fevjdlavjri7whe2r9b9l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fevjdlavjri7whe2r9b9l.png" alt=" " width="335" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  An inactive relationship is represented by a dashed line. 
&lt;/h2&gt;

&lt;h1&gt;
  
  
  19. Filter Direction
&lt;/h1&gt;

&lt;p&gt;Relationships do more than connect tables. They determine how filters propagate through the model.&lt;/p&gt;

&lt;p&gt;Consider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DimProduct
    1
    │
    ▼
    *
FactSales
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Suppose a user chooses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Category = "Computers"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in a slicer using &lt;code&gt;DimProduct[Category]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Power BI first identifies products belonging to Computers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DimProduct

P01 Laptop       Computers ✓
P02 Desktop      Computers ✓
P03 Mouse        Accessories
P04 Keyboard     Accessories
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The relationship then filters &lt;code&gt;FactSales&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FactSales

P01  85,000 ✓
P01  72,000 ✓
P02  54,000 ✓
P03   1,500 ✗
P04   4,500 ✗
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The sales measure therefore evaluates only the transactions belonging to the selected products.&lt;/p&gt;




&lt;h1&gt;
  
  
  20. Single-Direction Filtering
&lt;/h1&gt;

&lt;p&gt;Single-direction filtering allows filters to travel in one direction.&lt;/p&gt;

&lt;p&gt;Typical star-schema behavior is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DIMENSION          FACT
   1                *
   │                │
   └──────────────► │
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DimProduct ─────► FactSales
DimCustomer ────► FactSales
DimDate ────────► FactSales
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is usually easy to understand:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A product filters sales.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It does not automatically mean:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Sales should filter the product dimension and continue through the model.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For one-to-many relationships, Power BI can use single-direction filtering from the &lt;code&gt;1&lt;/code&gt; side toward the &lt;code&gt;*&lt;/code&gt; side. Single-direction relationships are generally preferable where they satisfy the reporting requirement because the filter behavior remains predictable.&lt;/p&gt;




&lt;h1&gt;
  
  
  21. Bidirectional Filtering
&lt;/h1&gt;

&lt;p&gt;A bidirectional relationship permits filters to move both ways.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DimProduct ◄──────► FactSales
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can be useful in certain scenarios such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;bridge-table designs&lt;/li&gt;
&lt;li&gt;specific many-to-many requirements&lt;/li&gt;
&lt;li&gt;dimension-to-dimension analysis&lt;/li&gt;
&lt;li&gt;scenarios where slicers must display only values having corresponding fact data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, bidirectional filtering should not be enabled everywhere. Microsoft recommends minimizing its use because it can negatively affect query performance and create confusing model behavior.&lt;/p&gt;

&lt;p&gt;A major problem is &lt;strong&gt;ambiguous filter paths&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Consider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;          DimProduct
          ↕        ↕
       FactSales  Bridge
          ↕        ↕
          DimCustomer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If several bidirectional paths exist, Power BI may have multiple ways of propagating the same filter. Microsoft notes that bidirectional relationships can negatively affect performance and can create ambiguous propagation paths. Power BI may prevent some ambiguous configurations from being created.&lt;/p&gt;




&lt;h1&gt;
  
  
  22. Joins in Power Query
&lt;/h1&gt;

&lt;p&gt;A &lt;strong&gt;join&lt;/strong&gt; combines rows from two tables based on matching columns. In Power Query, joins are normally created using:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Home → Merge Queries&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fol8r8tz5vw3izxoo3032.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fol8r8tz5vw3izxoo3032.png" alt=" " width="738" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Consider two tables.&lt;/p&gt;

&lt;h2&gt;
  
  
  Customers
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;CustomerID&lt;/th&gt;
&lt;th&gt;CustomerName&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;C001&lt;/td&gt;
&lt;td&gt;Amina&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C002&lt;/td&gt;
&lt;td&gt;Brian&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C003&lt;/td&gt;
&lt;td&gt;Carol&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C004&lt;/td&gt;
&lt;td&gt;David&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Orders
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;OrderID&lt;/th&gt;
&lt;th&gt;CustomerID&lt;/th&gt;
&lt;th&gt;Amount&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;O101&lt;/td&gt;
&lt;td&gt;C001&lt;/td&gt;
&lt;td&gt;5000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;O102&lt;/td&gt;
&lt;td&gt;C001&lt;/td&gt;
&lt;td&gt;2500&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;O103&lt;/td&gt;
&lt;td&gt;C003&lt;/td&gt;
&lt;td&gt;7000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;O104&lt;/td&gt;
&lt;td&gt;C005&lt;/td&gt;
&lt;td&gt;3000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Notice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;C001&lt;/code&gt; appears in both tables.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;C003&lt;/code&gt; appears in both tables.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;C002&lt;/code&gt; and &lt;code&gt;C004&lt;/code&gt; have no orders.&lt;/li&gt;
&lt;li&gt;order &lt;code&gt;O104&lt;/code&gt; belongs to &lt;code&gt;C005&lt;/code&gt;, which is not in the Customers table.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These tables demonstrate each Power Query join type.&lt;/p&gt;

&lt;p&gt;Power Query currently provides Left Outer, Right Outer, Full Outer, Inner, Left Anti and Right Anti join options through Merge operations. &lt;/p&gt;




&lt;h1&gt;
  
  
  23. Left Outer Join
&lt;/h1&gt;

&lt;p&gt;Microsoft defines the Left Outer join as retaining every row from the left table and matching information from the right table. A &lt;strong&gt;Left Outer Join&lt;/strong&gt; keeps:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;All rows from the left table plus matching rows from the right table.&lt;br&gt;
Conceptually:&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LEFT TABLE              RIGHT TABLE
████████████        ┌───────────────┐
████████████────────█████████████████
████████████        └───────────────┘

Keep ALL left + matches from right
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With Customers as the left table:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;CustomerID&lt;/th&gt;
&lt;th&gt;CustomerName&lt;/th&gt;
&lt;th&gt;OrderID&lt;/th&gt;
&lt;th&gt;Amount&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;C001&lt;/td&gt;
&lt;td&gt;Amina&lt;/td&gt;
&lt;td&gt;O101&lt;/td&gt;
&lt;td&gt;5000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C001&lt;/td&gt;
&lt;td&gt;Amina&lt;/td&gt;
&lt;td&gt;O102&lt;/td&gt;
&lt;td&gt;2500&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C002&lt;/td&gt;
&lt;td&gt;Brian&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C003&lt;/td&gt;
&lt;td&gt;Carol&lt;/td&gt;
&lt;td&gt;O103&lt;/td&gt;
&lt;td&gt;7000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C004&lt;/td&gt;
&lt;td&gt;David&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Brian and David remain even though they have no orders.&lt;/p&gt;

&lt;h3&gt;
  
  
  Practical Use
&lt;/h3&gt;

&lt;p&gt;Use a Left Outer Join when the left table represents the records that must be retained.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Keep every customer and attach their order details where available.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Folpua56a9r55c9ekuox1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Folpua56a9r55c9ekuox1.png" alt=" " width="800" height="411"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  24. Right Outer Join
&lt;/h1&gt;

&lt;p&gt;A &lt;strong&gt;Right Outer Join&lt;/strong&gt; is effectively the reverse. It retains:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Every row from the right table plus matching information from the left table. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Using Orders as the right table:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;CustomerID&lt;/th&gt;
&lt;th&gt;CustomerName&lt;/th&gt;
&lt;th&gt;OrderID&lt;/th&gt;
&lt;th&gt;Amount&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;C001&lt;/td&gt;
&lt;td&gt;Amina&lt;/td&gt;
&lt;td&gt;O101&lt;/td&gt;
&lt;td&gt;5000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C001&lt;/td&gt;
&lt;td&gt;Amina&lt;/td&gt;
&lt;td&gt;O102&lt;/td&gt;
&lt;td&gt;2500&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C003&lt;/td&gt;
&lt;td&gt;Carol&lt;/td&gt;
&lt;td&gt;O103&lt;/td&gt;
&lt;td&gt;7000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C005&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;td&gt;O104&lt;/td&gt;
&lt;td&gt;3000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;C005&lt;/code&gt; order remains even though no corresponding customer exists. Use this when all records from the second table must survive the merge.&lt;/p&gt;




&lt;h1&gt;
  
  
  25. Full Outer Join
&lt;/h1&gt;

&lt;p&gt;A &lt;strong&gt;Full Outer Join&lt;/strong&gt; keeps every record from both tables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customers             Orders
┌─────────┐         ┌─────────┐
│█████████│█████████│█████████│
└─────────┘         └─────────┘

Everything from both sides
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;CustomerID&lt;/th&gt;
&lt;th&gt;CustomerName&lt;/th&gt;
&lt;th&gt;OrderID&lt;/th&gt;
&lt;th&gt;Amount&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;C001&lt;/td&gt;
&lt;td&gt;Amina&lt;/td&gt;
&lt;td&gt;O101&lt;/td&gt;
&lt;td&gt;5000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C001&lt;/td&gt;
&lt;td&gt;Amina&lt;/td&gt;
&lt;td&gt;O102&lt;/td&gt;
&lt;td&gt;2500&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C002&lt;/td&gt;
&lt;td&gt;Brian&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C003&lt;/td&gt;
&lt;td&gt;Carol&lt;/td&gt;
&lt;td&gt;O103&lt;/td&gt;
&lt;td&gt;7000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C004&lt;/td&gt;
&lt;td&gt;David&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C005&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;td&gt;O104&lt;/td&gt;
&lt;td&gt;3000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;No records are intentionally discarded.&lt;/p&gt;

&lt;h3&gt;
  
  
  Practical Use
&lt;/h3&gt;

&lt;p&gt;This is useful for reconciliation tasks such as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Compare two systems and retain all records regardless of whether a match exists.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  26. Inner Join
&lt;/h1&gt;

&lt;p&gt;An &lt;strong&gt;Inner Join&lt;/strong&gt; keeps only records that match in both tables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customers           Orders
    ┌─────────────┐
────│ MATCH ONLY  │────
    └─────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;CustomerID&lt;/th&gt;
&lt;th&gt;CustomerName&lt;/th&gt;
&lt;th&gt;OrderID&lt;/th&gt;
&lt;th&gt;Amount&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;C001&lt;/td&gt;
&lt;td&gt;Amina&lt;/td&gt;
&lt;td&gt;O101&lt;/td&gt;
&lt;td&gt;5000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C001&lt;/td&gt;
&lt;td&gt;Amina&lt;/td&gt;
&lt;td&gt;O102&lt;/td&gt;
&lt;td&gt;2500&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C003&lt;/td&gt;
&lt;td&gt;Carol&lt;/td&gt;
&lt;td&gt;O103&lt;/td&gt;
&lt;td&gt;7000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The following records disappear:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;C002 Brian
C004 David
O104 / C005
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;because they do not have matches on both sides.&lt;/p&gt;

&lt;h3&gt;
  
  
  Practical Use
&lt;/h3&gt;

&lt;p&gt;Use an Inner Join when only matched records are relevant.&lt;/p&gt;

&lt;p&gt;For example: Return only customers who have made purchases.&lt;/p&gt;




&lt;h1&gt;
  
  
  27. Left Anti Join
&lt;/h1&gt;

&lt;p&gt;A &lt;strong&gt;Left Anti Join&lt;/strong&gt; returns rows from the left table that &lt;strong&gt;do not have a match&lt;/strong&gt; in the right table. Power Query describes this join as returning only left-side rows without corresponding right-side matches.&lt;/p&gt;

&lt;p&gt;Result:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;CustomerID&lt;/th&gt;
&lt;th&gt;CustomerName&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;C002&lt;/td&gt;
&lt;td&gt;Brian&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C004&lt;/td&gt;
&lt;td&gt;David&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These are the customers who have no matching orders.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customers                     Orders

C001 ───────────────────────► MATCH     remove
C002 ──X                                KEEP
C003 ───────────────────────► MATCH     remove
C004 ──X                                KEEP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Practical Use
&lt;/h3&gt;

&lt;p&gt;Left Anti Join is extremely useful for data-quality analysis.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;customers without orders&lt;/li&gt;
&lt;li&gt;products never sold&lt;/li&gt;
&lt;li&gt;employees without payroll records&lt;/li&gt;
&lt;li&gt;database records missing from another system&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  28. Right Anti Join
&lt;/h1&gt;

&lt;p&gt;A &lt;strong&gt;Right Anti Join&lt;/strong&gt; returns rows from the right table that do not have matches in the left table.&lt;/p&gt;

&lt;p&gt;With the example data:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;OrderID&lt;/th&gt;
&lt;th&gt;CustomerID&lt;/th&gt;
&lt;th&gt;Amount&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;O104&lt;/td&gt;
&lt;td&gt;C005&lt;/td&gt;
&lt;td&gt;3000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This identifies an order whose CustomerID does not exist in the customer master table.&lt;/p&gt;

&lt;h3&gt;
  
  
  Practical Use
&lt;/h3&gt;

&lt;p&gt;Right Anti Join can be used to discover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;orphan transactions&lt;/li&gt;
&lt;li&gt;unmatched IDs&lt;/li&gt;
&lt;li&gt;missing master-data records&lt;/li&gt;
&lt;li&gt;synchronization problems between systems&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  29. Visual Summary of Power Query Join Types
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LEFT OUTER
Customers ◄──── priority
Keep all Customers + matching Orders


RIGHT OUTER
priority ────► Orders
Keep all Orders + matching Customers


INNER
Customers ∩ Orders
Keep matches only


FULL OUTER
Customers ∪ Orders
Keep everything


LEFT ANTI
Customers - Orders
Customers with NO matching Orders


RIGHT ANTI
Orders - Customers
Orders with NO matching Customers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A compact comparison is:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Join&lt;/th&gt;
&lt;th&gt;Left Matches&lt;/th&gt;
&lt;th&gt;Left Non-Matches&lt;/th&gt;
&lt;th&gt;Right Matches&lt;/th&gt;
&lt;th&gt;Right Non-Matches&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Left Outer&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Right Outer&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Full Outer&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inner&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Left Anti&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Right Anti&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h1&gt;
  
  
  30. Power Query Joins vs Power BI Relationships
&lt;/h1&gt;

&lt;p&gt;Joins and relationships are related concepts but perform fundamentally different tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Power Query Merge
&lt;/h2&gt;

&lt;p&gt;A merge happens during the &lt;strong&gt;data preparation stage&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customers
   +
Orders
   │
   ▼
Power Query Merge
   │
   ▼
Combined Query
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A merge can physically bring columns from another query into the resulting table.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;h3&gt;
  
  
  Before Merge
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FactSales
ProductID
Quantity
Amount
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DimProduct
ProductID
ProductName
Category
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After merging and expanding the columns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sales
ProductID
ProductName
Category
Quantity
Amount
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The product attributes have effectively been added to the sales dataset.&lt;/p&gt;




&lt;h1&gt;
  
  
  31. Relationship
&lt;/h1&gt;

&lt;p&gt;A Power BI relationship does &lt;strong&gt;not physically combine the tables&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DimProduct                FactSales
ProductID                 ProductID
ProductName     1 ─── *   Quantity
Category                   Amount
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The tables remain separate.&lt;/p&gt;

&lt;p&gt;The relationship simply tells the semantic model how they are connected and how filters can propagate between them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MERGE
Two queries → physically combined result

RELATIONSHIP
Two model tables → remain separate but logically connected
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  32. When Each Operation Happens
&lt;/h1&gt;

&lt;p&gt;The typical sequence is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. DATA SOURCE
      │
      ▼
2. POWER QUERY
   - clean
   - transform
   - merge
   - append
      │
      ▼
3. DATA MODEL
   - relationships
   - cardinality
   - filter direction
      │
      ▼
4. DAX
   - measures
   - calculations
      │
      ▼
5. REPORT
   - visuals
   - slicers
   - dashboards
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A merge therefore occurs primarily during the &lt;strong&gt;transformation stage&lt;/strong&gt;. A relationship exists within the &lt;strong&gt;semantic model stage&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  33. When Should a Merge Be Used?
&lt;/h1&gt;

&lt;p&gt;Merging is appropriate when two datasets logically need to become one query. Examples include:&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding lookup information during transformation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Transaction table
+
Exchange-rate table
=
Transactions with exchange rates
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Combining information representing the same logical entity
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Employee details
+
Employee extension attributes
=
Employee dimension
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Data validation
&lt;/h3&gt;

&lt;p&gt;Anti joins can identify records missing from another system.&lt;/p&gt;

&lt;h3&gt;
  
  
  Preparing dimensions
&lt;/h3&gt;

&lt;p&gt;Several source tables may need to be merged before producing a clean &lt;code&gt;DimProduct&lt;/code&gt; table.&lt;/p&gt;




&lt;h1&gt;
  
  
  34. When Should a Relationship Be Used?
&lt;/h1&gt;

&lt;p&gt;Relationships are preferable when tables represent different analytical roles.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DimCustomer
DimProduct
DimDate
DimLocation
FactSales
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These tables naturally represent a star schema.&lt;/p&gt;

&lt;p&gt;Flattening all of them through repeated Power Query merges would destroy the logical separation between dimensions and facts.&lt;/p&gt;

&lt;p&gt;Instead:&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart TB
    A["DimCustomer"] --&amp;gt; F["FactSales"]
    B["DimProduct"] --&amp;gt; F
    C["DimDate"] --&amp;gt; F
    D["DimLocation"] --&amp;gt; F&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;The model remains easy to understand and extend.&lt;/p&gt;




&lt;h1&gt;
  
  
  35. Problems With Excessive Merging
&lt;/h1&gt;

&lt;p&gt;Suppose this star model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DimCustomer ─┐
DimProduct ──┤
DimDate ─────┼──► FactSales
DimLocation ─┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is converted into:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MegaSalesTable
├── Sale fields
├── Customer fields
├── Product fields
├── Date fields
└── Location fields
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can cause dimensions to be repeated across potentially millions of transaction rows. For example, the string 'Nairobi' may be repeated hundreds of thousands of times instead of being represented through a location dimension.&lt;/p&gt;

&lt;p&gt;More importantly, the semantic distinction between:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WHO   = Customer
WHAT  = Product
WHEN  = Date
WHERE = Location
EVENT = Sale
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;becomes less clear.&lt;/p&gt;

&lt;p&gt;Keeping facts and dimensions separate therefore provides organizational as well as technical benefits.&lt;/p&gt;




&lt;h1&gt;
  
  
  36. Practical Comparison
&lt;/h1&gt;

&lt;p&gt;Suppose management asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What were laptop sales in Nairobi during September?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Using a Star Schema
&lt;/h2&gt;

&lt;p&gt;Filters originate in dimensions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DimProduct
Category = Laptop
      │
      ▼
FactSales
      ▲
      │
DimLocation
County = Nairobi
      ▲
      │
DimDate
Month = September
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same measure can remain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Total Sales =
SUM(FactSales[SalesAmount])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The relationships supply the filter context. This is one of the main strengths of a properly designed Power BI model: &lt;strong&gt;simple measures can answer complex analytical questions because the model handles context&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  37. Recommended Power BI Model
&lt;/h1&gt;

&lt;p&gt;For a typical business intelligence project, I would recommend a &lt;strong&gt;star schema&lt;/strong&gt;. Consider a company analysing sales, customers, locations, products, and dates. The model could be:&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart TB
    DATE["DimDate&amp;lt;br/&amp;gt;DateKey&amp;lt;br/&amp;gt;Day&amp;lt;br/&amp;gt;Month&amp;lt;br/&amp;gt;Quarter&amp;lt;br/&amp;gt;Year"]
    CUSTOMER["DimCustomer&amp;lt;br/&amp;gt;CustomerID&amp;lt;br/&amp;gt;Customer&amp;lt;br/&amp;gt;Segment"]
    PRODUCT["DimProduct&amp;lt;br/&amp;gt;ProductID&amp;lt;br/&amp;gt;Product&amp;lt;br/&amp;gt;Category&amp;lt;br/&amp;gt;Brand"]
    LOCATION["DimLocation&amp;lt;br/&amp;gt;LocationID&amp;lt;br/&amp;gt;County&amp;lt;br/&amp;gt;Region"]

    SALES["FactSales&amp;lt;br/&amp;gt;SaleID&amp;lt;br/&amp;gt;DateKey&amp;lt;br/&amp;gt;CustomerID&amp;lt;br/&amp;gt;ProductID&amp;lt;br/&amp;gt;LocationID&amp;lt;br/&amp;gt;Quantity&amp;lt;br/&amp;gt;Revenue&amp;lt;br/&amp;gt;Cost"]

    DATE --&amp;gt;|1 to many| SALES
    CUSTOMER --&amp;gt;|1 to many| SALES
    PRODUCT --&amp;gt;|1 to many| SALES
    LOCATION --&amp;gt;|1 to many| SALES&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;The design would normally use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dimension     Relationship      Fact
---------     ------------      ----
DimDate       1 ───────── *     FactSales
DimCustomer   1 ───────── *     FactSales
DimProduct    1 ───────── *     FactSales
DimLocation   1 ───────── *     FactSales
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Filter direction would generally be Dimension to Fact, rather than bidirectional relationships everywhere.&lt;/p&gt;




&lt;h1&gt;
  
  
  38. Why the Star Schema Is Recommended
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Query and Report Performance
&lt;/h2&gt;

&lt;p&gt;The star design gives the engine a predictable structure in which relatively small dimensions filter a potentially large fact table. It also avoids unnecessary relationship chains.&lt;/p&gt;

&lt;h2&gt;
  
  
  DAX Simplicity
&lt;/h2&gt;

&lt;p&gt;A measure such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Total Revenue =
SUM(FactSales[SalesAmount])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can be reused for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Revenue by Product
Revenue by Customer
Revenue by County
Revenue by Month
Revenue by Year
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;without rewriting the measure. Filter context is supplied by the dimensions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Model Readability
&lt;/h2&gt;

&lt;p&gt;A developer opening Model View can immediately understand the analytical structure, rather than attempting to interpret dozens of arbitrary table connections.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scalability
&lt;/h2&gt;

&lt;p&gt;Additional dimensions can be introduced logically.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DimSalesperson
       │
       ▼
FactSales
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Likewise, another fact table can potentially reuse conformed dimensions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;              DimDate
              /     \
             ▼       ▼
       FactSales   FactBudget
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Reduced Data Redundancy
&lt;/h2&gt;

&lt;p&gt;Customer and product descriptions do not have to be unnecessarily repeated throughout every fact row.&lt;/p&gt;

&lt;h2&gt;
  
  
  Maintainability
&lt;/h2&gt;

&lt;p&gt;Changes can be isolated to appropriate tables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Product changes  → DimProduct
Customer changes → DimCustomer
Calendar logic   → DimDate
Transactions     → FactSales
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Ease of Reporting
&lt;/h2&gt;

&lt;p&gt;Report creators naturally choose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dimensions → slicers, axes and groupings
Facts      → measures and aggregations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Predictable Filter Propagation
&lt;/h2&gt;

&lt;p&gt;Single-direction filters from dimensions to the fact table create a clear path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DimProduct ─────► FactSales
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;instead of a network of unnecessary bidirectional relationships. Microsoft's Power BI modelling guidance similarly emphasizes star-schema concepts, consistent fact-table grain, and clear fact/dimension separation. &lt;/p&gt;




&lt;h1&gt;
  
  
  39. Recommended Design Principles
&lt;/h1&gt;

&lt;p&gt;For most projects, I would therefore use the following approach:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Build a &lt;strong&gt;star schema&lt;/strong&gt; wherever practical.&lt;/li&gt;
&lt;li&gt;Store measurable business events in &lt;strong&gt;fact tables&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Store descriptive attributes in &lt;strong&gt;dimension tables&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Define a clear and consistent &lt;strong&gt;grain&lt;/strong&gt; for every fact table.&lt;/li&gt;
&lt;li&gt;Create unique keys on dimension tables.&lt;/li&gt;
&lt;li&gt;Reference those keys as foreign keys in fact tables.&lt;/li&gt;
&lt;li&gt;Prefer &lt;strong&gt;one-to-many relationships&lt;/strong&gt; between dimensions and facts.&lt;/li&gt;
&lt;li&gt;Prefer &lt;strong&gt;single-direction filtering from dimensions to facts&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Use bidirectional relationships only when there is a specific analytical reason.&lt;/li&gt;
&lt;li&gt;Use many-to-many relationships carefully and introduce bridge tables when appropriate.&lt;/li&gt;
&lt;li&gt;Keep relationships active where they represent the default analytical path.&lt;/li&gt;
&lt;li&gt;Use inactive relationships or role-playing dimensions for alternative relationships such as Order Date and Ship Date.&lt;/li&gt;
&lt;li&gt;Use Power Query merges for &lt;strong&gt;data preparation&lt;/strong&gt;, rather than as a replacement for proper dimensional modelling.&lt;/li&gt;
&lt;li&gt;Avoid turning an otherwise logical dimensional model into one flat table without a clear reason.&lt;/li&gt;
&lt;/ol&gt;




&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Flat tables can be effective for small and simple datasets, but their redundancy and lack of structure make them increasingly difficult to manage as data volumes and reporting requirements grow. Snowflake schemas provide additional normalization and can be useful when dimensions contain complex hierarchies, although the additional tables and relationships can make a Power BI model harder to use. For most business intelligence applications, a &lt;strong&gt;star schema provides the strongest balance between simplicity, scalability, performance, maintainability, and analytical flexibility&lt;/strong&gt;.&lt;br&gt;
Power Query joins solve a different problem. They transform and physically combine query data before or during loading, whereas Power BI relationships preserve separate tables and establish logical connections within the semantic model. Understanding when to merge data and when to relate tables is therefore essential. Ultimately, good Power BI development depends on designing the model before designing the dashboard. When the underlying schema, grain, keys, relationships, and filter directions are correct, DAX becomes simpler, reports become easier to build, and the resulting analytics are both more reliable and easier to maintain.&lt;/p&gt;

</description>
      <category>powerbi</category>
      <category>datamodelling</category>
      <category>datacleaning</category>
      <category>dataanalysis</category>
    </item>
    <item>
      <title>Understanding the Git Workflow: Working Directory, Staging, Commit and Push</title>
      <dc:creator>Kunu Wako</dc:creator>
      <pubDate>Sat, 22 Aug 2026 09:26:52 +0000</pubDate>
      <link>https://dev.to/kunu_wako/understanding-the-git-workflow-working-directory-staging-commit-and-push-2ph9</link>
      <guid>https://dev.to/kunu_wako/understanding-the-git-workflow-working-directory-staging-commit-and-push-2ph9</guid>
      <description>&lt;p&gt;Git and GitHub can be very confusing concepts, especially for beginners. The best differentiation is that GitHub is the platform where we store the code, while git is the language we use to store and retrieve this code. When dealing with Git and GitHub, we have to understand the different stages that make up the entire process. From our local computer working directory, to staging the changes, to committing, and finally pushing to GitHub.&lt;/p&gt;

&lt;h2&gt;
  
  
  Working Directory
&lt;/h2&gt;

&lt;p&gt;Working directory means the folder that we are currently in. It is important to know your working directory as the changes occur here. We check the working directory in cmd by using the command &lt;code&gt;pwd&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1f7crvfxy4pjz4bvw6j8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1f7crvfxy4pjz4bvw6j8.png" alt=" " width="581" height="128"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When making changes to the files in your working directory, git can see and track the changes. You can check this by using &lt;code&gt;git status&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftmtm25aluejml40ekg98.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftmtm25aluejml40ekg98.png" alt=" " width="566" height="151"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Staging Area
&lt;/h2&gt;

&lt;p&gt;In the staging area, we put up files that are ready to be committed to your GitHub repository. This is done using the &lt;code&gt;git add&lt;/code&gt; command. You can use &lt;code&gt;git add .&lt;/code&gt; to stage all the files, or use a specific file's name to stage it. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnossktgpgp5tu1wd4t40.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnossktgpgp5tu1wd4t40.png" alt=" " width="565" height="205"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Commit
&lt;/h2&gt;

&lt;p&gt;After staging, committing your changes creates a snapshot of the current state of the project and stores it in the local git repository. We commit using the &lt;code&gt;git commit -m ""&lt;/code&gt; command. The commit message in the quotes is supposed to describe the changes made. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjahkzun0k5ssnl98onyy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjahkzun0k5ssnl98onyy.png" alt=" " width="579" height="118"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Push
&lt;/h2&gt;

&lt;p&gt;The final stage is the push. This stage uploads the local changes to the remote GitHub repository. We do this using the &lt;code&gt;git push&lt;/code&gt; command. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F51qfm0bhtwy12e08tcr4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F51qfm0bhtwy12e08tcr4.png" alt=" " width="572" height="154"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>bash</category>
    </item>
  </channel>
</rss>
