<?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: phillip nzioka</title>
    <description>The latest articles on DEV Community by phillip nzioka (@yonko).</description>
    <link>https://dev.to/yonko</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%2F3952206%2F3de8bef5-9320-408a-9c44-937bcfa7f468.jpg</url>
      <title>DEV Community: phillip nzioka</title>
      <link>https://dev.to/yonko</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yonko"/>
    <language>en</language>
    <item>
      <title>Power BI Database Connections</title>
      <dc:creator>phillip nzioka</dc:creator>
      <pubDate>Sun, 05 Jul 2026 16:31:37 +0000</pubDate>
      <link>https://dev.to/yonko/power-bi-database-connections-51gm</link>
      <guid>https://dev.to/yonko/power-bi-database-connections-51gm</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Power BI is a data visualization software offered by Microsoft. It allows users to connect to various types of data including databases to derive meaningful insights. There are various connectors for each type of database to establish a data source connection in Power BI, a few of which are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SQL Server Database Connector&lt;/li&gt;
&lt;li&gt;Access Database Connector&lt;/li&gt;
&lt;li&gt;Oracle Database Connector&lt;/li&gt;
&lt;li&gt;MySQL Database Connector&lt;/li&gt;
&lt;li&gt;PostgreSQL Database Connector&lt;/li&gt;
&lt;li&gt;Google BigQuery Connector&lt;/li&gt;
&lt;li&gt;Snowflake Connector&lt;/li&gt;
&lt;li&gt;Amazon Redshift Connector&lt;/li&gt;
&lt;li&gt;ODBC Connector&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Any of these connectors may be used, along with appropriate configurations, to connect to the desired database as a data source for Power BI.&lt;br&gt;
This article will focus on connecting Power BI to a PostgreSQL database, both offline (local) and online. &lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting to the Local PostgreSQL database
&lt;/h2&gt;

&lt;p&gt;A local PostgreSQL server is a database instance installed and running directly on your personal computer, allowing you to work offline without relying on a remote or cloud-based service.&lt;br&gt;
To connect to the PostgreSQL database, you must open Power BI Desktop and navigate to &lt;strong&gt;Get Data&lt;/strong&gt; and click &lt;strong&gt;More&lt;/strong&gt; in order to select the appropriate database connector.&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%2F0do84i7oabe8quqtr828.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%2F0do84i7oabe8quqtr828.png" alt="Get Data" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you are redirected to the next window, type "postgres" in the search box, select the PostgreSQL database, and then connect.&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%2Famt5ltjhamklj5aewo0w.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%2Famt5ltjhamklj5aewo0w.png" alt="Search PostgreSQL" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enter the server and database name details. The local PostgreSQL server runs on &lt;code&gt;localhost:5432&lt;/code&gt; or &lt;code&gt;127.0.0.1:5432&lt;/code&gt; and the default database name is &lt;code&gt;postgres&lt;/code&gt;.&lt;br&gt;
Power BI offers two modes of connecting to our database:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Import&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DirectQuery&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The primary difference is that Import mode copies data into Power BI’s in-memory engine for fast performance and full DAX support, while DirectQuery mode maintains a live connection to the source database for real-time data with no internal storage.&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%2Fjnq0dn3otkg3u1iartuy.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%2Fjnq0dn3otkg3u1iartuy.png" alt="Import Mode" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After selecting &lt;code&gt;Connect&lt;/code&gt; you will be prompted to enter details for postgres database in your local machine; the &lt;strong&gt;User name&lt;/strong&gt; and the &lt;strong&gt;Password&lt;/strong&gt;. Once completed, select Connect.&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%2Fc3ruzkna97gt1qw57nq8.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%2Fc3ruzkna97gt1qw57nq8.png" alt="Local Database Details" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will be redirected to a Navigator window where you select the data you want from the database and either &lt;code&gt;Load&lt;/code&gt; or &lt;code&gt;Transform&lt;/code&gt; Data based on your needs.&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%2Fhfuke2fm497bgtz75jtu.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%2Fhfuke2fm497bgtz75jtu.png" alt="Load Data" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Loading data&lt;/strong&gt; imports raw information directly into the Power BI data model for immediate analysis and visualization without modification, whereas &lt;strong&gt;transforming data&lt;/strong&gt; uses the Power Query Editor to clean, shape, and prepare the data.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Connecting to a remote PostgreSQL database
&lt;/h2&gt;

&lt;p&gt;Remote PostgreSQL servers are primarily used to centralize data storage, enable collaboration across distributed teams, and support cloud deployments where applications and databases are separated for better scalability and security. &lt;/p&gt;

&lt;p&gt;Key benefits include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Separation of Concerns&lt;/strong&gt;: Applications can run on one server while the database resides on another, optimizing resources and security. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accessibility&lt;/strong&gt;: Teams can manage and query the database from multiple locations or machines without needing local installation. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security and Control&lt;/strong&gt;: Centralized administration allows for stricter IP whitelisting, encryption (SSL/TLS), and robust authentication policies (e.g., scram-sha-256) to protect sensitive data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article will focus on connecting to a remote PostgreSQL database on &lt;strong&gt;Aiven&lt;/strong&gt;. Aiven is a cloud-agnostic, AI-ready open source data platform that provides fully managed database and data streaming services across major public clouds, including AWS, Google Cloud, and Microsoft Azure.&lt;/p&gt;

&lt;p&gt;Login into your Aiven console, navigate to your project, locate your PostgreSQL service, ensure that it's running, and if not, power the service on.&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%2Fi0tjb0n0e7qftcpcmvij.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%2Fi0tjb0n0e7qftcpcmvij.png" alt="Power on service" width="798" height="202"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select your service, and you will be directed to the Connection Information page.&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%2F3arxf0fqq49r4hbe53cz.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%2F3arxf0fqq49r4hbe53cz.png" alt="Connection Information" width="800" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Locate and download the CA Certificate since our service requires SSL encryption to validate connections.&lt;/p&gt;

&lt;p&gt;Search and navigate into &lt;code&gt;Manage computer certificates&lt;/code&gt; on your local machine.&lt;/p&gt;

&lt;p&gt;Select the &lt;strong&gt;Trusted Root Certification Authorities folder&lt;/strong&gt;, navigate to the &lt;strong&gt;Certificates&lt;/strong&gt; folder, right click on it, hover on &lt;code&gt;All Tasks&lt;/code&gt; and select &lt;code&gt;Import&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%2Ff05jxilsgqaoautcti83.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%2Ff05jxilsgqaoautcti83.png" alt="Import certificate" width="799" height="578"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will be prompted with the Certificate Import Wizard window in order to choose the storage location. Click &lt;code&gt;Next&lt;/code&gt; to continue.&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%2Fdew5ehfap23tyzoy3fnm.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%2Fdew5ehfap23tyzoy3fnm.png" alt="Import Certificate Wizard" width="796" height="789"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select &lt;code&gt;Browse&lt;/code&gt; on the prompted window, upload the CA Certificate that you downloaded, and click Next to proceed.&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%2F7y8he0sdh92o2s2v1vd6.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%2F7y8he0sdh92o2s2v1vd6.png" alt="Upload Certificate" width="767" height="732"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will be prompted to select the storage for the certificate, then click Next.&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%2Fa2q5eta2jrypmwuq7d5t.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%2Fa2q5eta2jrypmwuq7d5t.png" alt="Certificate store" width="796" height="822"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will be directed to the next window, where you will select Finish.&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%2Fmxhgc4hf7rrpgh134dy4.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%2Fmxhgc4hf7rrpgh134dy4.png" alt="Finish Certificate Import" width="800" height="812"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Repeat the steps involved in connecting Power BI to the local PostgreSQL database, but change the server details and credentials to those from our Aiven console PostgreSQL service.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Connecting Power BI to a PostgreSQL database (whether locally or remotely)is a foundational skill for any data professional looking to harness the full potential of their data. As we've explored, the process is straightforward when approached step by step.&lt;br&gt;
For local connections, the setup is a matter of pointing Power BI to your localhost with the correct credentials, allowing you to work offline and iterate quickly on your reports. This is ideal for development, testing, or when you're working in isolated environments.&lt;/p&gt;

&lt;p&gt;For remote databases like those hosted on Aiven, the additional layer of SSL certificate configuration is essential for security. While it introduces an extra step, the benefits of centralized data management, team collaboration, and enterprise-grade security far outweigh the initial setup effort. Properly importing the CA certificate ensures that your connection is encrypted and authenticated, protecting sensitive data from unauthorized access.&lt;/p&gt;

&lt;p&gt;Remember that the choice between Import and DirectQuery modes will significantly shape your reporting experience—balancing performance against real-time data needs. Experiment with both to understand which best fits your use case.&lt;/p&gt;

&lt;p&gt;By following this guide, you've equipped yourself to connect Power BI to PostgreSQL in virtually any scenario. Whether you're building dashboards for personal projects or enterprise-wide business intelligence, this connectivity opens the door to powerful insights and data-driven decision-making.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>database</category>
      <category>analytics</category>
      <category>learning</category>
    </item>
    <item>
      <title>Modeling, Joins, Relationships and Different Schemas In Power BI</title>
      <dc:creator>phillip nzioka</dc:creator>
      <pubDate>Sun, 21 Jun 2026 10:16:39 +0000</pubDate>
      <link>https://dev.to/yonko/modeling-joins-relationships-and-different-schemas-in-power-bi-13d9</link>
      <guid>https://dev.to/yonko/modeling-joins-relationships-and-different-schemas-in-power-bi-13d9</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;To master Power BI, you need to understand how data is structured, connected, and stored. Here is a comprehensive, structured guide to &lt;em&gt;Modelling, Joins, Relationships&lt;/em&gt;, and &lt;em&gt;Schemas&lt;/em&gt; in Power BI.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Modeling in Power BI
&lt;/h3&gt;

&lt;p&gt;Data modeling is the process of identifying, organizing and defining the types of data a business collects and the relationships between them. It uses diagrams, symbols and textual definitions to visually represent how data is captured, stored and used. A well-designed data model helps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understand data requirements&lt;/li&gt;
&lt;li&gt;Ensure proper structure for reporting&lt;/li&gt;
&lt;li&gt;Align with business goals&lt;/li&gt;
&lt;li&gt;Maintain data integrity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the golden rule of Power BI. While you can use a single flat table, it is inefficient and leads to poor performance. The recommended model is the &lt;em&gt;Star Schema&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;It consists of:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fact Table (The Center)&lt;/strong&gt;: Contains quantitative data (numbers you want to aggregate). Examples: Sales Amount, Quantity Sold, Profit. Fact tables have foreign keys that link to dimension tables.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dimension Tables (The Points)&lt;/strong&gt;: Contains descriptive attributes (text/categories you want to slice by). Examples: Customer Name, Product Color, Date, Location. Dimension tables should have a unique primary key.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why? &lt;br&gt;
Star schemas reduce memory usage, speed up calculations, and make DAX formulas (like &lt;code&gt;CALCULATE&lt;/code&gt;) much easier to write.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Relationships (Connecting tables)
&lt;/h3&gt;

&lt;p&gt;Relationships are the main feature of data modelling defining all data types. Relationships helps connect with multiple data sources using &lt;em&gt;cardinality&lt;/em&gt;.&lt;br&gt;
Relationships in Power BI define how tables filter each other. You manage them in the &lt;strong&gt;Model View&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Cardinality (The "One" and "Many")
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Many-to-One (*:1)&lt;/strong&gt;: The most common and preferred. One row in the Dimension table relates to many rows in the Fact table (e.g., one &lt;code&gt;ProductID&lt;/code&gt; appears many times in the Sales table).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;One-to-One (1:1)&lt;/strong&gt;: Rare. Used when splitting a wide table for security or performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Many-to-Many (:)&lt;/strong&gt;: &lt;em&gt;Avoid if possible&lt;/em&gt;. Used when bridging two fact tables or when dimensions are not unique (e.g., a product can belong to multiple categories). It creates ambiguity and slows down performance.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Cross-Filter Direction (The Arrow)
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Single Direction (→)&lt;/strong&gt;: The default. Filters flow from the &lt;em&gt;"One"&lt;/em&gt; side (Dimension) to the &lt;em&gt;"Many"&lt;/em&gt; side (Fact). &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Both Directions (↔)&lt;/strong&gt;: Use sparingly. This allows filters to flow from Fact to Dimension, which is useful for "Row-Level Security" but can create ambiguous path errors (circular dependencies).&lt;/p&gt;

&lt;h4&gt;
  
  
  Active vs. Inactive Relationships
&lt;/h4&gt;

&lt;p&gt;You can have multiple paths between two tables, but only one can be active at a time.&lt;/p&gt;

&lt;p&gt;To use an inactive relationship (dotted line), you must activate it in a DAX measure using the &lt;code&gt;USERELATIONSHIP&lt;/code&gt; function (e.g., switching between Order Date and Ship Date).&lt;/p&gt;

&lt;h3&gt;
  
  
  Types of Joins (How Power BI combines data)
&lt;/h3&gt;

&lt;p&gt;Unlike SQL, Power BI does not use &lt;code&gt;JOIN&lt;/code&gt; in the query editor to combine tables for modelling (you use Relationships instead). However, when you merge queries in Power Query, you use standard joins:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Join Type&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Power BI Use Case&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;Keeps all rows from the left table; matches from the right.&lt;/td&gt;
&lt;td&gt;Adding City names to a Customer list.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Right Outer&lt;/td&gt;
&lt;td&gt;Keeps all rows from the right table; matches from the left.&lt;/td&gt;
&lt;td&gt;Rarely used (just swap the tables).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inner&lt;/td&gt;
&lt;td&gt;Keeps only rows that exist in both tables.&lt;/td&gt;
&lt;td&gt;Filtering out inactive customers by joining Sales to Customers.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Full Outer&lt;/td&gt;
&lt;td&gt;Keeps all rows from both tables.&lt;/td&gt;
&lt;td&gt;Merging two separate branch lists together.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Anti (Left/Right)&lt;/td&gt;
&lt;td&gt;Left Anti keeps rows in the left that have no match in the right. Right Anti keeps rows in the right that have no match in the left.&lt;/td&gt;
&lt;td&gt;Finding customers who haven't placed an order in 12 months.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Best Practice: Do as many merges/joins as possible in the source database (SQL), not in Power Query, as Power BI's merge engine is memory-intensive.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Different Schemas in Power BI
&lt;/h3&gt;

&lt;p&gt;A "Schema" is the overall blueprint of your tables and relationships. &lt;/p&gt;

&lt;h4&gt;
  
  
  Star Schema (Recommended)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Structure&lt;/strong&gt;: 1 Central Fact + Multiple Dimensions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pros&lt;/strong&gt;: Fastest performance, easiest DAX, simplest filtering.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cons&lt;/strong&gt;: Requires time to normalize your data.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Snowflake Schema
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Structure&lt;/strong&gt;: Dimensions are further normalized into sub-dimensions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pros&lt;/strong&gt;: Saves storage space (less data duplication).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cons&lt;/strong&gt;: Slower in Power BI. It creates more relationships, forcing the engine to traverse multiple tables to apply a single filter. Power BI recommends against snowflaking; denormalize your dimensions into a single flat table if possible.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Flat Schema (Single Table)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Structure&lt;/strong&gt;: A single massive table with all columns (facts and dimensions) combined.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pros&lt;/strong&gt;: No relationships needed; simple for beginners.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cons&lt;/strong&gt;: Massive file size. DAX measures become complex (you can't use &lt;code&gt;CROSSFILTER&lt;/code&gt;). Lack of date tables makes time intelligence impossible. Avoid for enterprise reports.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Best Practices for Power BI Modeling
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hide Foreign Keys&lt;/strong&gt;: In the Model view, hide the foreign key columns in your Fact table so report builders don't accidentally use them as filters.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Create a separate Date Table&lt;/strong&gt;: Never use a "datetime" column as your date. Create a dedicated calendar table (with Year, Month, Quarter, Weekday) and mark it as "Date Table" in Power BI. Connect it to your fact table(s) using a single-direction relationship.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sort By Column&lt;/strong&gt;: If you have a text month (Jan, Feb), use the "Sort by Column" feature to sort it by a numeric Month Number column.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Referential Integrity&lt;/strong&gt;: Ensure your Foreign Keys in the Fact table do not contain values that don't exist in the Dimension table. Power BI handles this by creating a blank "Unknown" row, which can skew totals.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Set the Datatype&lt;/strong&gt;: Always set numeric columns to Decimal or Whole Number (never Text), and set date columns to Date (not Date/Time) unless you need timestamps.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>learning</category>
      <category>beginners</category>
      <category>datascience</category>
      <category>analytics</category>
    </item>
    <item>
      <title>Linux Fundamentals for Data Engineering</title>
      <dc:creator>phillip nzioka</dc:creator>
      <pubDate>Sun, 07 Jun 2026 19:11:58 +0000</pubDate>
      <link>https://dev.to/yonko/linux-fundamentals-for-data-engineering-a4e</link>
      <guid>https://dev.to/yonko/linux-fundamentals-for-data-engineering-a4e</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Linux is a free, open-source Unix-like operating system (created by Linus Torvalds in 1991) that powers most cloud infrastructure and big data tools. It's essential for data engineers due to its stability, performance, and automation capabilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Linux Matters for Data Engineering
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cloud &amp;amp; Tool Dominance&lt;/strong&gt;: Runs on AWS, Azure, GCP, Docker, Kubernetes, Spark, Kafka, and Airflow&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Automation&lt;/strong&gt;: Enables ETL pipeline automation via Bash scripting and CRON jobs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Command Line Skills&lt;/strong&gt;: Requires mastery of navigation, process management, and text editing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;File System &amp;amp; Permissions&lt;/strong&gt;: Critical for secure data handling with chmod and chown&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Linux Essentials
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Basic SSH connection
&lt;/h4&gt;

&lt;p&gt;SSH (Secure Shell) lets you open an encrypted terminal session to a remote machine, typically with &lt;code&gt;ssh @&amp;lt;server_address&amp;gt;&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ssh"&gt;&lt;code&gt;&lt;span class="k"&gt;ssh&lt;/span&gt; &amp;lt;username&amp;gt;@&amp;lt;server_address&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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.amazonaws.com%2Fuploads%2Farticles%2Ffws3rlc2asj4vf7phdf1.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.amazonaws.com%2Fuploads%2Farticles%2Ffws3rlc2asj4vf7phdf1.png" alt="ssh login" width="799" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a user to a Linux server
&lt;/h3&gt;

&lt;p&gt;To create a new user, all you have to do is ‘useradd‘ or ‘adduser‘ with ‘username’. The ‘username’ is a user login name, that is used by user to login into the system.&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.amazonaws.com%2Fuploads%2Farticles%2Fmqqj873wkat8a089eksu.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.amazonaws.com%2Fuploads%2Farticles%2Fmqqj873wkat8a089eksu.png" alt="Adding user to Linux server" width="800" height="331"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you’ve created the user, you can switch to the created user&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;su - phillipN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once logged in it's important to make sure the server is upto date.&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.amazonaws.com%2Fuploads%2Farticles%2F3l3pd5c27bju5p0unamb.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.amazonaws.com%2Fuploads%2Farticles%2F3l3pd5c27bju5p0unamb.png" alt="Update" width="800" height="146"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once in a while you can upgrade the server.&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.amazonaws.com%2Fuploads%2Farticles%2Fb5i8atmju8xoyjdo0555.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.amazonaws.com%2Fuploads%2Farticles%2Fb5i8atmju8xoyjdo0555.png" alt="Upgrade" width="800" height="132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  File Operations
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;ls&lt;/code&gt;&lt;br&gt;
Lists directory contents&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.amazonaws.com%2Fuploads%2Farticles%2F77ewt6t5e82xeox1txlt.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.amazonaws.com%2Fuploads%2Farticles%2F77ewt6t5e82xeox1txlt.png" alt="List directory" width="800" height="182"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd&lt;/code&gt;&lt;br&gt;
Navigates through directories&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd &amp;lt;directory_path&amp;gt;&lt;/code&gt;  → Moves to directory&lt;br&gt;
&lt;code&gt;cd ..&lt;/code&gt; → Goes up one level&lt;br&gt;
&lt;code&gt;cd&lt;/code&gt; → Returns to home&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.amazonaws.com%2Fuploads%2Farticles%2Fue84r3fmokoohlj8tr1e.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.amazonaws.com%2Fuploads%2Farticles%2Fue84r3fmokoohlj8tr1e.png" alt="Change directory" width="799" height="109"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pwd&lt;/code&gt;&lt;br&gt;
Prints working directory&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.amazonaws.com%2Fuploads%2Farticles%2F672c2nxmsn6un0fg4u87.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.amazonaws.com%2Fuploads%2Farticles%2F672c2nxmsn6un0fg4u87.png" alt="Current directory" width="800" height="74"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mkdir&lt;/code&gt;&lt;br&gt;
Creates a directory&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mkdir &amp;lt;directory_name&amp;gt;&lt;/code&gt; → Makes directory &lt;br&gt;
&lt;code&gt;mkdir -p &amp;lt;path&amp;gt;&lt;/code&gt; → Creates parent directories&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.amazonaws.com%2Fuploads%2Farticles%2F453nm2c2y7tftqagsaox.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.amazonaws.com%2Fuploads%2Farticles%2F453nm2c2y7tftqagsaox.png" alt="Create directory" width="800" height="114"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mv&lt;/code&gt;&lt;br&gt;
mv does two jobs depending on what you give it as the destination. If you give it a new path, it moves the file there. If you give it a new name in the same folder, it renames it. Either way, the original is gone.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cp&lt;/code&gt;&lt;br&gt;
Used to copy files and directories from a source to a destination.  The basic syntax is cp [options] source destination.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Common Usage&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Copy a single file: &lt;code&gt;cp file1.txt file2.txt&lt;/code&gt; creates a copy named &lt;em&gt;file2.txt&lt;/em&gt;. &lt;br&gt;
Copy to a directory: &lt;code&gt;cp file.txt /backup/&lt;/code&gt; copies the file into the specified directory. &lt;br&gt;
Copy directories: Use the &lt;code&gt;-r&lt;/code&gt; or &lt;code&gt;-R&lt;/code&gt; (recursive) flag to copy folders: &lt;code&gt;cp -r dir1 dir2&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.amazonaws.com%2Fuploads%2Farticles%2Fr6soa4np5aw06t6lbwso.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.amazonaws.com%2Fuploads%2Farticles%2Fr6soa4np5aw06t6lbwso.png" alt="Copy Files/Folders" width="800" height="308"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;rm&lt;/code&gt;&lt;br&gt;
Deletes files or folders permanently.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;rm &amp;lt;file&amp;gt;&lt;/code&gt; → Delete file&lt;br&gt;
&lt;code&gt;rm -r &amp;lt;dir&amp;gt;&lt;/code&gt; → Delete recursively &lt;br&gt;
&lt;code&gt;rm -i &amp;lt;file&amp;gt;&lt;/code&gt; → Confirm before delete&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.amazonaws.com%2Fuploads%2Farticles%2F8je7g8bhmfqw52g9j9vq.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.amazonaws.com%2Fuploads%2Farticles%2F8je7g8bhmfqw52g9j9vq.png" alt="Delete Files/Folders" width="799" height="204"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;touch&lt;/code&gt;&lt;br&gt;
Creates empty files.&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.amazonaws.com%2Fuploads%2Farticles%2F4ohqszc36ysw1moh3gzb.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.amazonaws.com%2Fuploads%2Farticles%2F4ohqszc36ysw1moh3gzb.png" alt="touch" width="799" height="127"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  System Monitoring &amp;amp; Performance
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;top&lt;/code&gt; / &lt;code&gt;htop&lt;/code&gt;&lt;br&gt;
Process monitoring.&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.amazonaws.com%2Fuploads%2Farticles%2Frydd53c5opt8cjtmubif.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.amazonaws.com%2Fuploads%2Farticles%2Frydd53c5opt8cjtmubif.png" alt="Process monitoring" width="800" height="131"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;kill&lt;/code&gt;&lt;br&gt;
Terminate/end process.&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.amazonaws.com%2Fuploads%2Farticles%2Fqs74melfitu117rhw4ci.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.amazonaws.com%2Fuploads%2Farticles%2Fqs74melfitu117rhw4ci.png" alt="Terminate process" width="800" height="58"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;free&lt;/code&gt;&lt;br&gt;
Shows memory usage.&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.amazonaws.com%2Fuploads%2Farticles%2Fj5yo2enbosed02q2ctnx.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.amazonaws.com%2Fuploads%2Farticles%2Fj5yo2enbosed02q2ctnx.png" alt="Memory usage" width="800" height="68"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;df / du&lt;/code&gt;&lt;br&gt;
Disk usage.&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.amazonaws.com%2Fuploads%2Farticles%2Fq8xo6lmhr411q8uktr2k.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.amazonaws.com%2Fuploads%2Farticles%2Fq8xo6lmhr411q8uktr2k.png" alt="Disk usage" width="800" height="120"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;uptime&lt;/code&gt;&lt;br&gt;
Shows system uptime.&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.amazonaws.com%2Fuploads%2Farticles%2Fbh0x1xy670uycmrrvvah.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.amazonaws.com%2Fuploads%2Farticles%2Fbh0x1xy670uycmrrvvah.png" alt="uptime" width="800" height="70"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Vim Editor Essentials
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Modal editing: Normal mode (navigation) and Insert mode (typing)&lt;/li&gt;
&lt;li&gt;Key shortcuts: &lt;code&gt;i&lt;/code&gt; (insert), &lt;code&gt;Esc&lt;/code&gt; (exit mode), &lt;code&gt;:wq&lt;/code&gt; (save &amp;amp; quit), &lt;code&gt;:q!&lt;/code&gt; (quit without saving)&lt;/li&gt;
&lt;li&gt;Navigation: &lt;code&gt;h/j/k/l&lt;/code&gt; (arrows), &lt;code&gt;gg&lt;/code&gt; (top), &lt;code&gt;G&lt;/code&gt; (bottom), &lt;code&gt;/pattern&lt;/code&gt; (search)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Critical Security &amp;amp; Maintenance
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use SSH keys instead of passwords for authentication&lt;/li&gt;
&lt;li&gt;Create non-root users with &lt;code&gt;sudo&lt;/code&gt; privileges&lt;/li&gt;
&lt;li&gt;Regular system updates: &lt;code&gt;apt update &amp;amp;&amp;amp; apt upgrade&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  PostgreSQL Installation &amp;amp; Configuration for Data Engineering
&lt;/h3&gt;
&lt;h4&gt;
  
  
  1. Install PostgreSQL (Only If Not Already Installed)
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check if PostgreSQL is already installed&lt;/span&gt;
psql &lt;span class="nt"&gt;--version&lt;/span&gt;

&lt;span class="c"&gt;# If not installed, update package list and install&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; postgresql postgresql-contrib

&lt;span class="c"&gt;# Verify installation&lt;/span&gt;
systemctl status postgresql

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  2. Configure PostgreSQL to Allow Remote Traffic
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Edit the main PostgreSQL configuration file&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/postgresql/&lt;span class="k"&gt;*&lt;/span&gt;/main/postgresql.conf

&lt;span class="c"&gt;# Find and change the listen_addresses line:&lt;/span&gt;
&lt;span class="c"&gt;# From: #listen_addresses = 'localhost'&lt;/span&gt;
&lt;span class="c"&gt;# To:   listen_addresses = '*'&lt;/span&gt;

&lt;span class="c"&gt;# Save and exit (:wq in vim or Ctrl+X then Y in nano)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Edit the client authentication configuration file&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/postgresql/&lt;span class="k"&gt;*&lt;/span&gt;/main/pg_hba.conf

&lt;span class="c"&gt;# Add this line at the end to allow connections from any IP&lt;/span&gt;
host    all             all             0.0.0.0/0               md5

&lt;span class="c"&gt;# For specific subnet (more secure), use:&lt;/span&gt;
&lt;span class="c"&gt;# host    all             all             192.168.1.0/24         md5&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  3. Configure Firewall to Allow PostgreSQL Traffic (Port 5432)
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Allow PostgreSQL default port through firewall&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow 5432/tcp

&lt;span class="c"&gt;# Reload firewall to apply changes&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw reload

&lt;span class="c"&gt;# Verify firewall rules&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw status verbose

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  4. Restart PostgreSQL and Check Status
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Restart PostgreSQL to apply configuration changes&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart postgresql

&lt;span class="c"&gt;# Check service status&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status postgresql

&lt;span class="c"&gt;# Check if PostgreSQL is listening on all interfaces&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;netstat &lt;span class="nt"&gt;-tulpn&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;5432
&lt;span class="c"&gt;# OR&lt;/span&gt;
ss &lt;span class="nt"&gt;-tulpn&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;postgres

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  5. Create Database and Schema
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="o"&gt;#&lt;/span&gt; &lt;span class="n"&gt;Switch&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;postgres&lt;/span&gt; &lt;span class="k"&gt;system&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt;
&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="n"&gt;postgres&lt;/span&gt;

&lt;span class="o"&gt;#&lt;/span&gt; &lt;span class="k"&gt;Create&lt;/span&gt; &lt;span class="k"&gt;database&lt;/span&gt; &lt;span class="s1"&gt;'phillipdb'&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="n"&gt;phillipdb&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="o"&gt;#&lt;/span&gt; &lt;span class="k"&gt;Connect&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="k"&gt;database&lt;/span&gt;
&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;c&lt;/span&gt; &lt;span class="n"&gt;phillipdb&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Inside psql, create schema 'staging'&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;SCHEMA&lt;/span&gt; &lt;span class="n"&gt;staging&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Verify schema was created&lt;/span&gt;
&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;dn&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  6. Add Data to the Staging Schema
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Create a sample table in staging schema&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;staging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customers&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;SERIAL&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="nb"&gt;TIMESTAMP&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="k"&gt;CURRENT_TIMESTAMP&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Insert sample data&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;staging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customers&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt; 
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'John Doe'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'john.doe@example.com'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Jane Smith'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'jane.smith@example.com'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Phillip N'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'phillip.n@example.com'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Query to verify data&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;staging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Import data from CSV file (common data engineering task)&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt; &lt;span class="n"&gt;staging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customers&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="s1"&gt;'/data/customers.csv'&lt;/span&gt;
&lt;span class="k"&gt;DELIMITER&lt;/span&gt; &lt;span class="s1"&gt;','&lt;/span&gt;
&lt;span class="n"&gt;CSV&lt;/span&gt; &lt;span class="n"&gt;HEADER&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  SCP(Secure Copy Protocol)
&lt;/h4&gt;

&lt;p&gt;It is a Linux command-line utility used to securely transfer files and directories between a local host and a remote host, or between two remote hosts.  It operates over an SSH (Secure Shell) connection, ensuring that all data is encrypted during transit.&lt;/p&gt;
&lt;h5&gt;
  
  
  Key Syntax and Usage
&lt;/h5&gt;

&lt;p&gt;The general syntax is &lt;code&gt;scp [options] source destination&lt;/code&gt;. The source and destination can be local paths or remote paths formatted as &lt;code&gt;[user@]host:/path&lt;/code&gt;. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Local to Remote: &lt;code&gt;scp file.txt user@remote_host:/remote/path/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Remote to Local: &lt;code&gt;scp user@remote_host:/remote/file.txt ./local/path/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Remote to Remote: &lt;code&gt;scp user@host1:/path/file.txt user@host2:/path/&lt;/code&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;
  
  
  Common Options
&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;-r&lt;/code&gt;: Recursively copy entire directories. &lt;br&gt;
&lt;code&gt;-P port&lt;/code&gt;: Specify a non-standard SSH port (note the capital P). &lt;br&gt;
&lt;code&gt;-p&lt;/code&gt;: Preserve file modification times and permissions. &lt;br&gt;
&lt;code&gt;-q&lt;/code&gt;: Quiet mode; suppresses progress meter and warnings. &lt;br&gt;
&lt;code&gt;-C&lt;/code&gt;: Enable compression to speed up transfers.&lt;/p&gt;

&lt;p&gt;To copy files from a Linux server to a Windows machine using SCP, you must run the command from the Windows machine to "pull" the file, as Windows typically does not run an SSH server by default. &lt;/p&gt;
&lt;h5&gt;
  
  
  &lt;em&gt;Using Built-in OpenSSH (Windows 10/11)&lt;/em&gt;
&lt;/h5&gt;

&lt;p&gt;Modern Windows versions include a native SCP client. Open Command Prompt or PowerShell and use the following syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp username@linux_server_ip:/path/to/remote/file C:&lt;span class="se"&gt;\p&lt;/span&gt;ath&lt;span class="se"&gt;\t&lt;/span&gt;o&lt;span class="se"&gt;\l&lt;/span&gt;ocal&lt;span class="se"&gt;\d&lt;/span&gt;estination

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;username&lt;/em&gt;&lt;/strong&gt;: The Linux user account. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;linux_server_ip&lt;/em&gt;&lt;/strong&gt;: The IP address or hostname of the Linux server. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;/path/to/remote/file&lt;/em&gt;&lt;/strong&gt;: The absolute path on the Linux server. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;C:\path\to\local\destination&lt;/em&gt;&lt;/strong&gt;: The local Windows directory where the file will be saved.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Copying files from Windows machine to a specific user on a Linux server using scp&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.amazonaws.com%2Fuploads%2Farticles%2Fqq2fjj4k830bkhm08gkd.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.amazonaws.com%2Fuploads%2Farticles%2Fqq2fjj4k830bkhm08gkd.png" alt="scp -r" width="799" height="151"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Linux is not just an optional skill for data engineers—it's the foundational operating system upon which modern data engineering is built. Mastering Linux commands and concepts directly translates to the ability to build, deploy, and maintain robust data pipelines in production environments.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>beginners</category>
      <category>learning</category>
      <category>postgres</category>
    </item>
  </channel>
</rss>
