<?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: Nile Lazarus</title>
    <description>The latest articles on DEV Community by Nile Lazarus (@nilelazarus).</description>
    <link>https://dev.to/nilelazarus</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1102506%2F7abdbfcd-4494-43bb-879c-f3d4186be2fa.jpg</url>
      <title>DEV Community: Nile Lazarus</title>
      <link>https://dev.to/nilelazarus</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nilelazarus"/>
    <language>en</language>
    <item>
      <title>A Guide to Setting Up Pgadmin for Development on Windows(Updated)</title>
      <dc:creator>Nile Lazarus</dc:creator>
      <pubDate>Thu, 12 Oct 2023 14:16:20 +0000</pubDate>
      <link>https://dev.to/nilelazarus/a-guide-to-setting-up-pgadmin-for-development-on-windowsupdated-3fc6</link>
      <guid>https://dev.to/nilelazarus/a-guide-to-setting-up-pgadmin-for-development-on-windowsupdated-3fc6</guid>
      <description>&lt;p&gt;In my last guide on this topic, some instructions may not have worked for everyone who attempted it.&lt;br&gt;
This time around, the issues with my last guide have been resolved and thoroughly tested to see if they work for anyone and everyone wanting to configure pgadmin 4 for development on a Windows system.&lt;/p&gt;
&lt;h3&gt;
  
  
  Install prerequisites
&lt;/h3&gt;

&lt;p&gt;First and foremost, please ensure that you have all of the following requirements fulfilled for your system.&lt;/p&gt;

&lt;p&gt;git (&lt;a href="https://git-scm.com/downloads"&gt;https://git-scm.com/downloads&lt;/a&gt;)&lt;br&gt;
Node.js 16 and above (&lt;a href="https://nodejs.org/en/download"&gt;https://nodejs.org/en/download&lt;/a&gt;)&lt;br&gt;
yarn (&lt;a href="https://classic.yarnpkg.com/lang/en/docs/install"&gt;https://classic.yarnpkg.com/lang/en/docs/install&lt;/a&gt;)&lt;br&gt;
Python 3.7 and above (&lt;a href="https://www.python.org/downloads/"&gt;https://www.python.org/downloads/&lt;/a&gt;)&lt;br&gt;
PostgreSQL server (&lt;a href="https://www.postgresql.org/download"&gt;https://www.postgresql.org/download&lt;/a&gt;)&lt;/p&gt;
&lt;h3&gt;
  
  
  Steps
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;1. Open a terminal of your choice, I will be using gitbash.&lt;/li&gt;
&lt;li&gt;Create a directory for your setup and navigate to the directory
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir pgadmin
cd pgadmin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Clone the pgadmin 4 git repository
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/pgadmin-org/pgadmin4.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You can now begin building the runtime for your frontend&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to &lt;code&gt;/pgadmin4/runtime&lt;/code&gt; directory (while in the &lt;code&gt;pgadmin&lt;/code&gt; directory created above)
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd pgadmin4/runtime
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Run the following command and copy the contents of the &lt;code&gt;dev_config.json.in&lt;/code&gt; file
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat dev_config.json.in
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The contents will look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "pythonPath": "C:/Python38/python.exe",
    "pgadminFile": "../web/pgAdmin4.py"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the string stored in &lt;code&gt;pythonPath&lt;/code&gt; with the actual path to &lt;code&gt;python.exe&lt;/code&gt; stored on your system.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Now run this command to create a new file called &lt;code&gt;dev_config.json&lt;/code&gt; and open it for file writing
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat &amp;gt; dev_config.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A blank line will appear when you enter this command. Paste the contents of the file copied earlier and hit &lt;code&gt;CTRL + D&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run the command
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Execute the runtime by running this command
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node_modules/nw/nwjs/nw
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now configure the Python environment for the backend&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigate out of the runtime directory
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd ..
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create a virtual environment using whatever name you wish. I named my environment &lt;code&gt;pgenv&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python -m virtualenv pgenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Activate the environment
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;source pgenv/Scripts/activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Upgrade to the latest version of pip
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install --upgrade pip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Add the path to your PostgreSQL installation bin directory to your environment variables with this command
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export PATH="$PATH:/c/Program Files/PostgreSQL/13/bin"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'm using PostgreSQL v13 but you can change the path to match the version you have installed.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install dependencies
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install -r requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Open up a second terminal and navigate to the web directory. Then run the following command:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn run webpacker --watch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;In the first terminal, navigate to the web directory again. Ensure that your virtual environment has been activated and start the server by running
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python pgAdmin.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will get a message like &lt;code&gt;Starting pgAdmin 4. Please navigate to http://127.0.0.1:5050 in your browser.&lt;/code&gt;. Navigate to &lt;code&gt;http://127.0.0.1:5050&lt;/code&gt; in your browser.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>webdev</category>
      <category>opensource</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Install and Configure Kerberos on Windows 10</title>
      <dc:creator>Nile Lazarus</dc:creator>
      <pubDate>Mon, 28 Aug 2023 16:23:57 +0000</pubDate>
      <link>https://dev.to/nilelazarus/how-to-install-and-configure-kerberos-on-windows-10-1jlm</link>
      <guid>https://dev.to/nilelazarus/how-to-install-and-configure-kerberos-on-windows-10-1jlm</guid>
      <description>&lt;p&gt;Cybercrime is an unfortunate part of reality which most of have been victim to in one way or another. As a developer or cyber security specialist, it is important to keep yourself up-to-date and aware of measures you can take to prevent or reduce cyber threats to you applications.&lt;/p&gt;

&lt;p&gt;Kerberos can be a great starting point.&lt;/p&gt;

&lt;p&gt;Kerberos is a computer network security protocol that authenticates service requests between two or more trusted hosts across an untrusted network, like the internet. It uses secret key cryptography and third party authentication for authenticating client-server applications and verifying users' identities.&lt;/p&gt;

&lt;p&gt;In this blog, I will show you how to install and configure Kerberos on your system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Head over to this &lt;a href="https://www.secure-endpoints.com/netidmgr/v2/#download"&gt;site&lt;/a&gt; and navigate to the "&lt;strong&gt;Downloads&lt;/strong&gt;" section&lt;/li&gt;
&lt;li&gt;Click on the 64-bit version to download: "&lt;strong&gt;Network Identity Manager 2.5.0.106 (64-bit MSI)&lt;/strong&gt;".&lt;/li&gt;
&lt;li&gt;Once the download is done, open up the installer and select the "&lt;strong&gt;Typical&lt;/strong&gt;" installation option.&lt;/li&gt;
&lt;li&gt;Now access this &lt;a href="https://www.secure-endpoints.com/heimdal/#download"&gt;site&lt;/a&gt; and once again navigate to the "&lt;strong&gt;Downloads&lt;/strong&gt;" section.&lt;/li&gt;
&lt;li&gt;Click on "&lt;strong&gt;Heimdal 7.4.0 (64-bit and 32-bit)&lt;/strong&gt;" to download.&lt;/li&gt;
&lt;li&gt;Once it is finished downloading, open the installer and follow the default installation steps.&lt;/li&gt;
&lt;li&gt;Once everything has been installed, restart your computer.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Configuration
&lt;/h2&gt;

&lt;p&gt;Follow these steps to get your own valid Kerberos ticket.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open your Start menu and search for "&lt;strong&gt;Network Identity Manager&lt;/strong&gt;".&lt;/li&gt;
&lt;li&gt;Open the application and right-click on "&lt;strong&gt;My Keystore&lt;/strong&gt;" and then "&lt;strong&gt;Obtain new credentials&lt;/strong&gt;".
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0uP48VAn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c8y77n6rprqd7vhsytls.png" alt="Image description" width="450" height="419"&gt;
&lt;/li&gt;
&lt;li&gt;Enter in a username and default realm.&lt;/li&gt;
&lt;li&gt;Enter your system's password.&lt;/li&gt;
&lt;li&gt;(Optional) Set up your Keystore.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>kerberos</category>
      <category>tutorial</category>
      <category>cybersecurity</category>
      <category>security</category>
    </item>
    <item>
      <title>Graph Databases and Their Applications</title>
      <dc:creator>Nile Lazarus</dc:creator>
      <pubDate>Sun, 27 Aug 2023 19:57:01 +0000</pubDate>
      <link>https://dev.to/nilelazarus/graph-databases-and-their-applications-dba</link>
      <guid>https://dev.to/nilelazarus/graph-databases-and-their-applications-dba</guid>
      <description>&lt;p&gt;Real-life relationships and data are usually heavily interconnected and extremely complex. A lot of valuable information cannot be restricted to simple tables and documents. This is where graph databases come in handy.&lt;/p&gt;

&lt;p&gt;A graph database (GDB) is a NoSQL database that uses graph structures to store data. It uses nodes, edges, and properties instead of rows, columns, tables, and documents like traditional databases. The edges represent relationships between nodes (can be entities). Graph databases are crucial for applications where relationships between data elements are more important.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Cases and Applications
&lt;/h2&gt;

&lt;p&gt;Graph databases shine the brightest in scenarios where understanding the complexity of relationships is placed at the forefront.&lt;br&gt;
The first such scenario that should come to mind is social networks. Social network platforms rely heavily on the capabilities that GDBs offer. An example would be using a GDB to discover hidden patterns within friend circles, interests, and interactions, and utilizing them to provide users with a more personalized experience.&lt;br&gt;
GDBs are also used in the e-commerce realm to provide personalized recommendations by analyzing past purchases and shared preferences.&lt;br&gt;
Additionally, search engines are also fueled by knowledge graphs and so are fraud detection systems which utilize connections to spot anomalous behaviour.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bitnine Global Inc's Graph Database Software
&lt;/h2&gt;

&lt;p&gt;Bitnine is a company that specializes in fully integrated graph databases.&lt;br&gt;
Apache AGE is an open-source GDB offered by Bitnine. Its key features are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is a GDB plugin for PostgreSQL&lt;/li&gt;
&lt;li&gt;Allows hybrid queries (OpenCypher and SQL)&lt;/li&gt;
&lt;li&gt;Fast Graph query processing, and&lt;/li&gt;
&lt;li&gt;Graph visualization and analytics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AgensGraph is their closed-source GDB option. Its key features are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hybrid query processing (Cypher and SQL)&lt;/li&gt;
&lt;li&gt;Enhanced security&lt;/li&gt;
&lt;li&gt;Data sharding&lt;/li&gt;
&lt;li&gt;Native graph storage&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Apache AGE vs AgensGraph
&lt;/h3&gt;

&lt;p&gt;The main difference between the two is that AGE is an openCypher plugin for PostgreSQL whereas AgensGraph is a complete graph database built upon PostgreSQL.&lt;/p&gt;

&lt;p&gt;By being a fork of PostgreSQL, AgensGraph is tied to a specific version of PostgreSQL. However, AGE is an extension and is not tied to any specific version of PostgreSQL.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learn More
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://bitnine.net/"&gt;Bitnine Global Inc. official website&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/apache/age"&gt;Apache AGE repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/bitnine-oss/agensgraph"&gt;AgensGraph repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>database</category>
      <category>bitnine</category>
      <category>learning</category>
      <category>postgres</category>
    </item>
    <item>
      <title>How to install pgadmin from source code for development on Windows</title>
      <dc:creator>Nile Lazarus</dc:creator>
      <pubDate>Thu, 24 Aug 2023 21:50:39 +0000</pubDate>
      <link>https://dev.to/nilelazarus/how-to-install-pgadmin-from-source-code-for-development-on-windows-3551</link>
      <guid>https://dev.to/nilelazarus/how-to-install-pgadmin-from-source-code-for-development-on-windows-3551</guid>
      <description>&lt;p&gt;pgAdmin is an open-source, web-based tool designed for the administration and management of PostgreSQL databases. Users can use its intuitive graphical interface (GUI) to interact with their PostgreSQL databases.&lt;br&gt;
pgAdmin is available for Windows, macOS, and Linux, making it a versatile cross-platform choice for database administrators and developers.&lt;/p&gt;

&lt;p&gt;Usually, pgadmin 4 can be installed by default on Windows when installing PostgreSQL. However, if you are interested in contributing to pgAdmin development or need to work with a specific version of pgAdmin, knowing how to configure it for development is crucial.&lt;/p&gt;

&lt;p&gt;In this blog, I will show you how to install and configure pgadmin for development on Windows.&lt;/p&gt;
&lt;h2&gt;
  
  
  Guide
&lt;/h2&gt;

&lt;p&gt;The two easiest ways to setup pgadmin for development are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;using virtual environment and python for backend&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;using Node.js and Yarn for frontend&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I will be covering the second method in this guide as it allows for dedicated frontend tools which yield better optimization and overall development, and also allows a separation of frontend and backend development environments. It is slightly more complicated to set up as compared to the first approach but offers more flexibility.&lt;/p&gt;

&lt;p&gt;It goes without saying that this method requires you to have Python 3.6 or later installed as well as Node.js and Yarn.&lt;/p&gt;
&lt;h3&gt;
  
  
  Steps
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Open a terminal of your choice, I will be using gitbash.&lt;/li&gt;
&lt;li&gt;Create a directory for your setup and navigate to the directory
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir pgadmin
cd pgadmin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Clone the pgadmin 4 git repository
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/pgadmin-org/pgadmin4.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You can now begin building the runtime for your frontend&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to &lt;code&gt;/pgadmin4/runtime&lt;/code&gt; directory (while in the &lt;code&gt;pgadmin&lt;/code&gt; directory created above)
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd pgadmin4/runtime
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Run the following command and copy the contents of the &lt;code&gt;dev_config.json.in&lt;/code&gt; file
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat dev_config.json.in
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The contents will look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "pythonPath": "C:/Python38/python.exe",
    "pgadminFile": "../web/pgAdmin4.py"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the string stored in &lt;code&gt;pythonPath&lt;/code&gt; with the actual path to &lt;code&gt;python.exe&lt;/code&gt; stored on your system.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Now run this command to create a new file called &lt;code&gt;dev_config.json&lt;/code&gt; and open it for file writing
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat &amp;gt; dev_config.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A blank line will appear when you enter this command. Paste the contents of the file copied earlier and hit &lt;code&gt;CTRL + D&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run the command
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Execute the runtime by running this command
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node_modules/nw/nwjs/nw
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now configure the Python environment for the backend&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigate out of the runtime directory
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd ..
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create a virtual environment using whatever name you wish. I named my environment &lt;code&gt;pgenv&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python -m virtualenv pgenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Activate the environment
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;source pgenv/Scripts/activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Upgrade to the latest version of pip
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install --upgrade pip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Add the path to your PostgreSQL installation bin directory to your environment variables with this command
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export PATH="$PATH:/c/Program Files/PostgreSQL/13/bin"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'm using PostgreSQL v13 but you can change the path to match the version you have installed.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install dependencies
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install -r requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Start the server by running
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python web/pgAdmin.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will get a message like &lt;code&gt;Starting pgAdmin 4. Please navigate to http://127.0.0.1:5050 in your browser.&lt;/code&gt;. Navigate to &lt;code&gt;http://127.0.0.1:5050&lt;/code&gt; in your browser.&lt;/p&gt;

</description>
      <category>development</category>
      <category>opensource</category>
      <category>postgres</category>
      <category>webdev</category>
    </item>
    <item>
      <title>An Introduction to Postgres Enterprise Manager</title>
      <dc:creator>Nile Lazarus</dc:creator>
      <pubDate>Sat, 19 Aug 2023 14:51:54 +0000</pubDate>
      <link>https://dev.to/nilelazarus/an-introduction-to-postgres-enterprise-manager-l54</link>
      <guid>https://dev.to/nilelazarus/an-introduction-to-postgres-enterprise-manager-l54</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Postgres Enterprise Manager (PEM) is an all-in-one database administration solution which offers management, monitoring, and performance tuning capabilties.&lt;br&gt;
This blog will attempt to briefly explain what PEM is and the core features it offers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Postgres Enterprise Manager (PEM)
&lt;/h2&gt;

&lt;p&gt;When you install PostgreSQL, you are given the option of also installing pgadmin. If you've ever used pgadmin before, you may already be familiar with PEM. PEM can be described as a more advanced version of pgadmin 4.&lt;br&gt;
PEM provides database administrators with a browser-based console platform for monitoring, performance tuning, backup management, and security enhancement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Features of Postgres Enterprise Manager
&lt;/h2&gt;

&lt;p&gt;Performance Monitoring and Tuning: PEM provides key insights into database performance, identification of bottlenecks, and query optimization.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Alert Management&lt;/strong&gt;: PEM empowers database adiministrators to proactively tackle issues by allowing them to create customized alerts and notifications of critical events and potential issues.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database Diagnostics&lt;/strong&gt;: PEM's diagnostic tools help administrators troubleshoot by highlighting performance problems. This allows for speedy root cause analysis and easy identification of effective solutions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backup and Recovery Management&lt;/strong&gt;: PEM simplifies backup and recovery, safeguards data integrity, and minimizes downtime through features such as Barman, Bart, and Failover Manager.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User Management and Security&lt;/strong&gt;: PEM provides extensive capabilities to efficiently manage user access and fine-tune security controls.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Query Analysis&lt;/strong&gt;: PEM can help administrators optimize database performance by analyzing complex SQL queries and pinpointing where improvements could be made. This is a crucial feature for improving query response times and increasing efficiency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Capacity Planning&lt;/strong&gt;: PEM can provide forecasts and predictions to aid in resource planning. This can help administrators anticipate growth and allocate resources efficiently.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Learn More
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.enterprisedb.com/docs/pem/latest/"&gt;PEM official documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtube.com/playlist?list=PLownlFUq_rL6rhJZTQJY6f_jGDZRV51Ot"&gt;Official PEM Demo Videos&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>postgres</category>
      <category>database</category>
      <category>postgressql</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Exploring PostgreSQL Extensions: Enhance Your Database Capabilities</title>
      <dc:creator>Nile Lazarus</dc:creator>
      <pubDate>Sat, 19 Aug 2023 13:15:20 +0000</pubDate>
      <link>https://dev.to/nilelazarus/exploring-postgresql-extensions-enhance-your-database-capabilities-576o</link>
      <guid>https://dev.to/nilelazarus/exploring-postgresql-extensions-enhance-your-database-capabilities-576o</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In today’s world, organizations grapple with increasingly complex data challenges, and the need for a robust yet flexible database system has never been more apparent. This is where PostgreSQL’s exceptional feature set comes into play, with one particular aspect shining brightly: extensions.&lt;/p&gt;

&lt;p&gt;Being able to tailor database solutions to suit your specific needs is an invaluable asset for database administration. PostgreSQL seems to understand this need and allows users to seamlessly enhance PostgreSQL’s capabilities without altering its core codebase.&lt;/p&gt;

&lt;p&gt;In this blog, we’ll delve into the purpose and potential of these extensions, exploring how they transform a standard PostgreSQL installation into a powerhouse of specialized functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding PostgreSQL Extensions
&lt;/h2&gt;

&lt;p&gt;Think of extensions as specialized tools that can be plugged into PostgreSQL to give you exactly those functionalities which you require without needing to touch the codebase.&lt;/p&gt;

&lt;p&gt;This allows you to get the capabilities you need without making any risky, complex changes to PostgreSQL’s architecture. Adding extensions provides benefits like retaining a maintainable architecture, customization without complexity, flexibility, adaptability, and community-driven innovation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Commonly Used PostgreSQL Extensions and Their Functions
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;pg_trgm&lt;/strong&gt;: A text similarity measurement extension that facilitates efficient text search and comparison, crucial for applications involving natural language processing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;hstore&lt;/strong&gt;: Key-value storage model, ideal for managing semi-structured or schema-less data within PostgreSQL.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PostGIS&lt;/strong&gt;: Equips PostgreSQL with geospatial objects and allows for advanced location-based queries, used for spatial data management.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;uuid-ossp&lt;/strong&gt;: Generates universally unique identifiers (UUIDs), essential for ensuring data integrity and uniqueness across distributed systems.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;pg_stat_statements&lt;/strong&gt;: Provides insights into query optimization, enabling better database performance by tracking and analyzing SQL query performance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;citext&lt;/strong&gt;: Useful in scenarios requiring case-insensitive text searching and matching.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Advanced Extensions for Specialized Use Cases
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;TimescaleDB&lt;/strong&gt;: Tailored for time-series data, optimizes data storage and retrieval for temporal datasets This extension is a must-have for IoT applications and financial analyses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;pgBouncer&lt;/strong&gt;: Addresses connection pooling, and efficiently manages database connections. Useful for enhancing resource utilization and scalability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PL/Python&lt;/strong&gt; and &lt;strong&gt;PL/pgSQL&lt;/strong&gt;: Enable the incorporation of Python and SQL procedural languages, respectively. Ideal for creating custom functions and stored procedures that best fit with your application's logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;pgAudit&lt;/strong&gt;: Provides detailed database auditing and monitoring capabilities, essential for tracking data access and changes.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>postgres</category>
      <category>opensource</category>
      <category>database</category>
      <category>extensions</category>
    </item>
    <item>
      <title>Unraveling pgAdmin: A Comprehensive Guide to PostgreSQL Management</title>
      <dc:creator>Nile Lazarus</dc:creator>
      <pubDate>Sun, 23 Jul 2023 18:06:49 +0000</pubDate>
      <link>https://dev.to/nilelazarus/unraveling-pgadmin-a-comprehensive-guide-to-postgresql-management-482o</link>
      <guid>https://dev.to/nilelazarus/unraveling-pgadmin-a-comprehensive-guide-to-postgresql-management-482o</guid>
      <description>&lt;p&gt;In the world of database management systems (RDBMS), PostgreSQL has become a leading choice for both businesses and developers alike due to its robustness, scalability, and adaptability due its open-source nature. To effectively manage PostgreSQL databases, an essential tool comes into play - pgAdmin.&lt;br&gt;
In this blog, we'll delve into the features of pgAdmin to better understand its significance in database management.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is pgAdmin?
&lt;/h2&gt;

&lt;p&gt;pgAdmin is an open-source, web-based tool designed for the administration and management of PostgreSQL databases. Users can use its intuitive graphical interface (GUI) to interact with their PostgreSQL databases.&lt;br&gt;
pgAdmin is available for Windows, macOS, and Linux, making it a versatile cross-platform choice for database administrators and developers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;User-Friendly Interface: pgAdmin offers an well-organised, intuitive, and extremely easy-to-use Graphical User Interface that makes it highly accessible for both beginners and seasoned database administrators alike. &lt;/li&gt;
&lt;li&gt;SQL Query Editor: the SQL query editor in pgAdmin allows users to query their databases directly. It supports syntax highlighting, code completion, error checking, and enhances the overall development experience.&lt;/li&gt;
&lt;li&gt;Database Object Management: pgAdmin provides users with a hassle-free way to manage database objects like tables, views, indexes, triggers, and functions. The tool is equipped with a variety of options to create, modify, and delete these objects.&lt;/li&gt;
&lt;li&gt;Server Dashboard: the server dashboard feature provides users with all the essential information needed to monitor their PostgreSQL server. This includes details regarding active connections, resource utilisation, and overall performance.&lt;/li&gt;
&lt;li&gt;Backup and Restore: database administrators can easily create and manage database backups as well as restore data from said backups.&lt;/li&gt;
&lt;li&gt;Data Visualization and Reporting: users can visualise data through charts, graphs, and pivot tables. They can also set up triggers to generate custom reports based on specific query results.&lt;/li&gt;
&lt;li&gt;Security and User Management: pgAdmin provides user and group management capabilities which help ensure secure and controlled access of users to the databases.&lt;/li&gt;
&lt;li&gt;Foreign Data Wrappers (FDW) Support: I've discussed Foreign Data Wrappers in detail in &lt;a href="https://dev.to/nilelazarus/demystifying-the-internals-of-postgresql-chapter-4-1da9"&gt;part 4&lt;/a&gt; of my Internals of PostgreSQL series. In short, Foreign Data Wrappers enable users to connect to external data sources/ foreign tables and manage them alongside their own PostgreSQL data. pgAdmin supports FDWs and allows users to manage them directly from the application.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;pgAdmin is a powerful and versatile tool for PostgreSQL databases. It's equipped with an extremely user-friendly, easy-to-navigate Graphical User Interface designed to empower beginners and database experts alike with all the essential database management capabilities they would need to efficiently manage PostgreSQL databases. Like PostgreSQL itself, pgAdmin is also open-source, has a strong community, and regular updates. All these factors make it a great choice for developers and database administrators seeking a more flexible and convenient way to interact with their databases.&lt;/p&gt;

</description>
      <category>pgadmin</category>
      <category>postgres</category>
      <category>database</category>
    </item>
    <item>
      <title>EDB BigAnimal: Harnessing the Power of Cloud PostgreSQL</title>
      <dc:creator>Nile Lazarus</dc:creator>
      <pubDate>Mon, 17 Jul 2023 09:36:51 +0000</pubDate>
      <link>https://dev.to/nilelazarus/edb-biganimal-harnessing-the-power-of-cloud-postgresql-23fo</link>
      <guid>https://dev.to/nilelazarus/edb-biganimal-harnessing-the-power-of-cloud-postgresql-23fo</guid>
      <description>&lt;p&gt;In today's data-driven world, businesses face immense pressure to handle and process vast amounts of data efficiently. This has led to the emergence of advanced database solutions that are both highly scalable and provide optimal performance. EDB BigAnimal is one such technology that offers such a solution for managing large-scale PostgreSQL databases in the cloud.&lt;/p&gt;

&lt;p&gt;In this blog we will be exploring the different features, benefits, and capabilities of EDB BigAnimal.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is EDB BigAnimal?
&lt;/h2&gt;

&lt;p&gt;BigAnimal is a cloud-based, fully managed, PostgreSQL database solution. It was developed by EnterpriseDB (EDB), a leading global provider of Postgres software and services.&lt;br&gt;
BigAnimal allows users to migrate from Oracle and offer deep compatibility and a plethora of useful tools and features aimed at helping users avail the benefits of using PostgreSQL.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features and Functionality
&lt;/h3&gt;

&lt;p&gt;Let's take a closer look at the features and functionalities EDB BigAnimal has to offer.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: BigANimal is designed to handle massive workloads and scale horizontally to effectively tackle ever increasing data demands. Organisations using BigAnimal can easily add or remove nodes, enabling their data infrastructure to remain flexible and adaptable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High Availability&lt;/strong&gt;: Ensuring high availability is crucial for any business. Users need to be able access any of their data, at any time and from anywhere. BigAnimal offers high availability configurations such as synchronous and asynchronous replication, automatic failover, and data redundancy to minimise downtime and prevent data loss.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Disaster Recovery&lt;/strong&gt;: Protecting data and ensuring disaster recovery is also a crucial requirement in database management. BigAnimal provides robust disaster recovery solutions and allows organisations to enable point-in-time recovery and to minimise damage from data loss caused by unforeseen disasters.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Geo-distributed Data&lt;/strong&gt;: BigAnimal allows users to implement Active-active architecture and deploy clusters across various regions and/or availability zones with multi-write access equipped.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance Monitoring and Tuning&lt;/strong&gt;: BigAnimal offers advanced performance monitoring and tubing capabilities where users can tune up to 97% of available parameters. This provides administrators with valuable insights into database performance and resource utilisation optimization.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-Platform Support&lt;/strong&gt;: BigAnimal is specifically designed to support various operating systems and ensure compatibility with any cloud providers and on-premises deployments as well. You can deploy on any cloud, in your account or on EDB BigAnimal as well.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Command Line Interface (CLI)
&lt;/h2&gt;

&lt;p&gt;BigAnimal offers a user-friendly CLI for management and configuration activities. The CLI can be installed on Linux, MacOS, and Windows operating systems and enables system administrators and developers to script and automate BigAnimal operations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Oracle Compatibility
&lt;/h2&gt;

&lt;p&gt;We have already discussed how BigAnimal is built to provide a smooth migration from Oracle database to PostgreSQL. But that's not all.&lt;br&gt;
BigAnimal offers compatibility with Oracle SQL and PL/SQL and also allows procedures written in PL/SQL to be converted to PL/pgSQL (PostgreSQL's procedural language).&lt;/p&gt;

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

&lt;p&gt;EDB BigAnimal is a fairly robust and scalable PostgreSQL database management solution which empowers enterprises to meet the challenges of handling large-scale data workloads head-on. It offers high availability, disaster recovery, and performance optimization features. It also provides a powerful and reliable option for organisations seeking to utilise the full potential of PostgreSQL in the cloud.&lt;/p&gt;

</description>
      <category>database</category>
      <category>postgres</category>
    </item>
    <item>
      <title>The Importance of String Distances: Levenshtein, Jaro, Naive Recursive</title>
      <dc:creator>Nile Lazarus</dc:creator>
      <pubDate>Sat, 15 Jul 2023 15:13:41 +0000</pubDate>
      <link>https://dev.to/nilelazarus/the-importance-of-string-distances-levenshtein-jaro-naive-recursive-2jno</link>
      <guid>https://dev.to/nilelazarus/the-importance-of-string-distances-levenshtein-jaro-naive-recursive-2jno</guid>
      <description>&lt;p&gt;Being able to calculate the similarity or dissimilarity between strings in the most accurate and cost efficient manner is a crucial task in various domains like natural language processing, data mining and database management.&lt;br&gt;
In regards to databases, string distance algorithms allow tasks like spell checking, record linkage, data deduplication, and information retrieval to be effectively carried out.&lt;br&gt;
In this blog, we will be focusing on three popular string distance algorithms:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Levenshtein distance&lt;/li&gt;
&lt;li&gt;Jaro similarity&lt;/li&gt;
&lt;li&gt;Naive Recursive (Edit Distance)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We will be discussing how each algorithm works, their significance in databases, and what the advantages and disadvantages are for each.&lt;br&gt;
Additionally, we will also cover the UTL_MATCH package available in Oracle Database for string comparison.&lt;/p&gt;
&lt;h2&gt;
  
  
  Levenshtein Distance
&lt;/h2&gt;

&lt;p&gt;The Levenshtein Distance was named after the Soviet mathematician Vladimir Levenshtein , who introduced it in 1965.&lt;br&gt;
It follows a simple concept of calculating the minimum (least) number of single character edits required to transform one string into another. These edits include insertions, deletions and substitutions.&lt;/p&gt;

&lt;p&gt;Let's try to understand it better with an example:&lt;br&gt;
Suppose two words/strings: "kangaroo" and "potato"&lt;/p&gt;

&lt;p&gt;This would be the initial matrix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|   |   | k | a | n | g | a | r | o | o |
|---|---|---|---|---|---|---|---|---|---|
|   | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| p | 1 |   |   |   |   |   |   |   |   |
| o | 2 |   |   |   |   |   |   |   |   |
| t | 3 |   |   |   |   |   |   |   |   |
| a | 4 |   |   |   |   |   |   |   |   |
| t | 5 |   |   |   |   |   |   |   |   |
| o | 6 |   |   |   |   |   |   |   |   |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's fill the matrix. Compare each character of the two strings. If a character matches, the value from the diagonal cell is copied. If they do not match, the minimum value out of those present in the left, diagonal and upper cells is selected and incremented by one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|   |   | k | a | n | g | a | r | o | o |
|---|---|---|---|---|---|---|---|---|---|
|   | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| p | 1 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| o | 2 | 2 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| t | 3 | 3 | 2 | 2 | 3 | 4 | 5 | 6 | 7 |
| a | 4 | 4 | 3 | 3 | 3 | 4 | 5 | 6 | 7 |
| t | 5 | 5 | 4 | 4 | 4 | 4 | 5 | 6 | 7 |
| o | 6 | 6 | 5 | 5 | 5 | 5 | 5 | 6 | 7 |

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

&lt;/div&gt;



&lt;p&gt;The final value for the Levenshtein distance is the value calculated for the bottom right cell of the matrix, which in our case is 7.&lt;/p&gt;

&lt;p&gt;Advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provides a precise value for string dissimilarity considering edits required.&lt;/li&gt;
&lt;li&gt;Suitable for fuzzy matching, spell checking, and data deduplication.&lt;/li&gt;
&lt;li&gt;Can handle strings of differing lengths.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Disadvantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Computationally expensive. Time complexity is &lt;em&gt;O(m*n)&lt;/em&gt; where &lt;em&gt;m&lt;/em&gt; and &lt;em&gt;n&lt;/em&gt; are the lengths of the two strings.&lt;/li&gt;
&lt;li&gt;May perform poorly with lengthier strings.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Jaro Similarity
&lt;/h2&gt;

&lt;p&gt;The Jaro similarity algorithm was introduced in 1989 by William E. Jaro. The algorithm calculates the similarity between two strings by comparing their characters and the order in which they appear. The algorithm provides a resultant value between 0 and 1, where 0 indicates no similarity at all and 1 indicates a perfect match.&lt;/p&gt;

&lt;p&gt;Let's use an example to try to understand better.&lt;br&gt;
Suppose two strings: "marble" and "table"&lt;/p&gt;

&lt;p&gt;Jaro similarity is calculated using the following formula:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--C0S5dWCx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dbtolhsre46ef2e1ze6x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C0S5dWCx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dbtolhsre46ef2e1ze6x.png" alt="JaroWinklerDist" width="407" height="103"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;m is the number of matching character&lt;/li&gt;
&lt;li&gt;t is half the number of transpositions&lt;/li&gt;
&lt;li&gt;|s1| and |s2| are the lengths of string 1 and string 2 respectively.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For our example ("marble" &amp;amp; "table"):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;4 matching characters. &lt;strong&gt;m = 4&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;No transpositions. &lt;strong&gt;t = 0&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Jaro Distance = (4 / 6 + 4 / 5 + (4 - 0) / 4) / 3 = &lt;strong&gt;0.822&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Jaro-Winkler Similarity
&lt;/h3&gt;

&lt;p&gt;Jaro-Winkler similarity is a slight modification of the Jaro similarity. It gives additional weightage to common prefixes (substring that appears at the beginning of the string itself).&lt;br&gt;
It is useful for calculating similarity between shorter strings or when you want to focus on strings with similar prefixes.&lt;/p&gt;

&lt;p&gt;Here are the steps to calculate the Jaro-Winkler similarity:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Calculate the Jaro similarity as done earlier. We will continue with the value from our example (8.22).&lt;/li&gt;
&lt;li&gt;Calculate &lt;em&gt;prefix scaling factor (p)&lt;/em&gt;. The formula for this is:
&lt;em&gt;p = 0.1 * common prefix length * (1 - Jaro Similarity)&lt;/em&gt;
According to our example, this would be:
p = 0.1 * 0 * (1 - 0.822) = 0&lt;/li&gt;
&lt;li&gt;Calculate Jaro-Winkler similarity using formula:
&lt;em&gt;Jaro-Winkler similarity = Jaro similarity + p ^(1 - Jaro similarity)&lt;/em&gt;
We would get:
Jaro-Winkler similarity = 8.22 + 0 * (1 - 8.22) = &lt;strong&gt;8.22&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Consider the order of characters when calculating string similarity.&lt;/li&gt;
&lt;li&gt;Used in tasks such as record linkage, string matching, and deduplication.&lt;/li&gt;
&lt;li&gt;Can handle strings of different lengths as well as strings having transpositions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Disadvantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not as accurate as Levenshtein distance as edits are not considered in the calculations.&lt;/li&gt;
&lt;li&gt;May not perform well in cases where common prefixes are not that significant.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Naive Recursive (Edit Distance):
&lt;/h2&gt;

&lt;p&gt;The Naive Recursive algorithm, also known as Edit Distance algorithm, is similar to the Levenshtein distance algorithm in that it also uses a minimum number of edits to compare strings. However, unlike Levenshtein, this algorithm uses a recursive approach. It breaks down the problem into smaller subproblems and solves them recursively.&lt;/p&gt;

&lt;p&gt;Let's once again use an example to understand this better using the strings "book" and "back".&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;If either string is null/empty, the distance is set to the length of the other string.&lt;/li&gt;
&lt;li&gt;If the last characters of the strings match (common postfix), the distance for the remaining substrings is calculated.&lt;/li&gt;
&lt;li&gt;If the conditions above are false, the distance is calculated using the following three recursive calls:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Insertion: EditDistance(s1, s2[:-1]) + 1&lt;/li&gt;
&lt;li&gt;Deletion: EditDistance(s1[:-1], s2) + 1&lt;/li&gt;
&lt;li&gt;Substitution: EditDistance(s1[:-1], s2[:-1]) + 1&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For our example, the Edit Distance would be 2.&lt;/p&gt;

&lt;p&gt;Advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simplistic, easy to understand and implement.&lt;/li&gt;
&lt;li&gt;Calculates an accurate distance between strings.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Disadvantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Exponential time complexity hence only suitable for short strings.&lt;/li&gt;
&lt;li&gt;Not suitable for real-world use with large datasets and real-time applications due to time complexity.&lt;/li&gt;
&lt;li&gt;Computationally costly.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Oracle Database
&lt;/h2&gt;

&lt;p&gt;Oracle database offers all of the above capabilities in its UTL_MATCH package. This package offers a wide variety of string comparison functions including the Levenshtein distance and Jaro-Winkler similarity algorithms discussed above.&lt;/p&gt;

&lt;p&gt;Here is how the Levenshtein Distance is calculated using UTL_MATCH.EDIT_DISTANCE function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DECLARE
  distance NUMBER;
BEGIN
  distance := UTL_MATCH.EDIT_DISTANCE('kangaroo', 'potato');
  DBMS_OUTPUT.PUT_LINE('Levenshtein Distance: ' || distance);
END;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output will be: 'Levenshtein Distance: 7'&lt;/p&gt;

&lt;p&gt;We can also use the UTL_MATCH.JARO_WINKLER_SIMILARITY function to calculate the Jaro-Winkler similarity:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DECLARE
  similarity NUMBER;
BEGIN
  similarity := UTL_MATCH.JARO_WINKLER_SIMILARITY('marble', 'table');
  DBMS_OUTPUT.PUT_LINE('Jaro-Winkler Similarity: ' || similarity);
END;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output here will be: 'Jaro-Winkler Similarity: 0.822'&lt;/p&gt;

&lt;p&gt;The UTL_MATCH package in Oracle Database offers optimised functions for string comparison, further enhancing the capabilities of databases in handling string-related operations.&lt;br&gt;
Understanding and utilising these algorithms and tools can greatly enhance the efficiency and accuracy of database systems.&lt;/p&gt;

</description>
      <category>database</category>
      <category>oracle</category>
    </item>
    <item>
      <title>Demystifying the Internals of PostgreSQL - Chapter 6</title>
      <dc:creator>Nile Lazarus</dc:creator>
      <pubDate>Wed, 28 Jun 2023 23:06:20 +0000</pubDate>
      <link>https://dev.to/nilelazarus/demystifying-the-internals-of-postgresql-chapter-6-3i87</link>
      <guid>https://dev.to/nilelazarus/demystifying-the-internals-of-postgresql-chapter-6-3i87</guid>
      <description>&lt;p&gt;Welcome back to the sixth instalment in our journey towards understanding The Internals of PostgreSQL.&lt;/p&gt;

&lt;p&gt;In the last blog, we covered chapter 5 which delves into how PostgreSQL handles Concurrency Control.&lt;/p&gt;

&lt;p&gt;In this blog, we will be exploring chapter 6 which covers Vacuum Processing. So without further ado, let's begin.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Vacuum Processing is a maintenance process in PostgreSQL which we briefly touched upon at the end of the last blog. The main responsibilities that Vacuum Processing handles are removing dead tuples and freezing transaction IDs.&lt;/p&gt;

&lt;p&gt;There are two types of methods used in vacuum processing of dead tuples:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Concurrent VACUUM: dead tuples are simply removed and other transactions can still read the table during this process.&lt;/li&gt;
&lt;li&gt;Full VACUUM: dead tuples are removed and live tuples are defragmented as well. Other transactions cannot read the table while this process is underway.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Up until version 8.0 of PostgreSQL, vacuum processing had to be done manually and was only automated in 2005.&lt;br&gt;
Additionally, this is a costly process which is why the Visibility Map (VM) feature was introduced in version 8.4 to increase efficiency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Outline of Concurrent VACUUM
&lt;/h2&gt;

&lt;p&gt;Vacuum Processing handles 3 tasks for all or some tables in the database:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Removing dead tuples: removes dead tuples, defragments live tuples, and and removes indices of dead tuples.&lt;/li&gt;
&lt;li&gt;Freezing old txids: freeze old txids, update frozen txids, and remove unnecessary parts of the clog if possible&lt;/li&gt;
&lt;li&gt;Others: update FSM and VM of processed tables, and update statistics like pg_stat_all_tables.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For each table in the database, PostgreSQL implements processing techniques called first block, second block, and then third block. After this, statistics and system catalogs are updated, and unnecessary files and pages of the clog are removed if possible.&lt;br&gt;
Let's now delve into what exactly the first block, second block, and third block do.&lt;/p&gt;

&lt;h3&gt;
  
  
  First Block
&lt;/h3&gt;

&lt;p&gt;First block is responsible for freeze processing and removing index tuples which point to dead tuples.&lt;br&gt;
PostgreSQL will first create a list of dead tuples, freeze old tuples, and store the list in maintenance_work_mem. After this, the list is used to remove the index tuples of the dead tuples.&lt;br&gt;
Once this is done, PostgreSQL moves onto Second Block.&lt;/p&gt;

&lt;h3&gt;
  
  
  Second Block
&lt;/h3&gt;

&lt;p&gt;Second block removes dead tuples and updates the FSM and VM.&lt;br&gt;
Dead tuples are removed and the remaining live tuples are reordered (defragmentation) after which the FSM and VM of the page this was performed on are updated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Third Block
&lt;/h2&gt;

&lt;p&gt;Third block performs &lt;em&gt;cleanup&lt;/em&gt; for the deleted indexes and updates the statistics and system catalogs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Visibility Map
&lt;/h2&gt;

&lt;p&gt;As mentioned before, vacuum processing is a costly process hence PostgreSQL introduced the Visibility Map in version 8.4 to improve efficiency.&lt;br&gt;
The VM basically holds information on which pages have dead tuples which allows the vacuum process to skip pages that have no dead tuples.&lt;br&gt;
The efficiency provided by VMs was further enhanced in version 9.6 such that VMs now also had page visibility and information on which pages contain frozen tuples.&lt;/p&gt;

&lt;h2&gt;
  
  
  Freeze Processing
&lt;/h2&gt;

&lt;p&gt;Freeze processing has two modes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Lazy Mode: only pages which contain dead tuples are scanned using the VM of each respective table. Tuples whose t_xmin is less than the freezeLimit txid are frozen. The following formula is used to calculate freezeLimit txid:&lt;br&gt;
&lt;em&gt;freezeLimit_txid = (OldestXmin − vacuum_freeze_min_age)&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Eager Mode: every page is scanned regardless of whether it does or does not contain dead tuples. System catalogs are also updated and unnecessary parts of the clog are removed if possible. The eager mode is performed when the following condition is satisfied:&lt;br&gt;
&lt;em&gt;pg_database.datfrozenxid &amp;lt; (OldestXmin − vacuum_freeze_table_age)&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Full VACUUM
&lt;/h2&gt;

&lt;p&gt;Although Concurrent VACUUM seems thorough at a glance, it falls short in several areas such as reducing table sizes even after several dead tuples have been removed.&lt;br&gt;
This negatively impacts both the efficiency of disk space usage and the overall performance of the database.&lt;br&gt;
To tackle this issue, PostgreSQL provides the Full VACUUM mode which takes the following steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Creates new table file&lt;/li&gt;
&lt;li&gt;Copies live tuples to the new table file&lt;/li&gt;
&lt;li&gt;Deletes the old file, rebuilds indexes and updates statistics, FSM, and VM&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>postgres</category>
      <category>database</category>
      <category>opensource</category>
      <category>sql</category>
    </item>
    <item>
      <title>Demystifying the Internals of PostgreSQL - Chapter 5</title>
      <dc:creator>Nile Lazarus</dc:creator>
      <pubDate>Wed, 28 Jun 2023 01:07:36 +0000</pubDate>
      <link>https://dev.to/nilelazarus/demystifying-the-internals-of-postgresql-chapter-5-2pe4</link>
      <guid>https://dev.to/nilelazarus/demystifying-the-internals-of-postgresql-chapter-5-2pe4</guid>
      <description>&lt;p&gt;Welcome back to another step in our journey towards understanding the Internals of PostgreSQL.&lt;/p&gt;

&lt;p&gt;In the last blog, we covered chapter 4 which explains Foreign Data Wrappers and Parallel Query.&lt;/p&gt;

&lt;p&gt;Now we're going to be moving on to chapter 5 which explains how PostgreSQL manages Concurrency Control. Let's jump right in!&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;When multiple transactions are running simultaneously in a database, concurrency control is needed to maintain &lt;em&gt;atomicity&lt;/em&gt; and &lt;em&gt;isolation&lt;/em&gt; which are two crucial ACID properties.&lt;/p&gt;

&lt;p&gt;There are three concurrency control techniques commonly used:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Multi-version Concurrency Control (MVCC)&lt;/li&gt;
&lt;li&gt;Strict Two-Phase Locking (S2PL)&lt;/li&gt;
&lt;li&gt;Optimistic Concurrency Control (OCC)
Each technique has its own variations. PostgreSQL uses a variation of MVCC called Snapshot Isolation (SI). In MVCC, when a write is performed, a new version of the data item is created while also retaining the old version. Then when a transaction attempts to read a data item, the selects one of the old versions to ensure isolation. In this way, read operations dont block write operations and vice versa.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In SI used by other RDBMSs, old versions of the data items being written to are stored in rollback segments. In the variation PostgreSQL uses, the new data item is inserted directly into the target table. When reading an item, PostgreSQL selects the appropriate version of the item through &lt;em&gt;visibility check rules&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;SI does not allow &lt;em&gt;Dirty Reads, Non-Repeatable Reads, and Phantom Reads&lt;/em&gt;. However, SI allows serialisation anomalies which makes it unable to achieve true serializability. To handle this issue, PostgreSQL uses Serializable Snapshot Isolation (SSI) which was added as of version 9.1. This enables PostgreSQL to offer true SERIALIZABLE isolation level.&lt;/p&gt;

&lt;h2&gt;
  
  
  Transaction ID
&lt;/h2&gt;

&lt;p&gt;When a transaction begins, it is assigned a unique identifier called transaction id (txid) by the transaction manager. In postgreSQL, the txid is a 32-bit unsigned integer. To view the current transactions txid, execute the &lt;em&gt;txid_current()&lt;/em&gt;. PostgreSQL will then return either the current txid or one of the three following txids reserved by it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;0&lt;/strong&gt; which means Invalid txid&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1&lt;/strong&gt; which means Bootstrap txid (used in the initialization of database cluster)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2&lt;/strong&gt; which means Frozen txid&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;txids can be compared with one another however a concept of &lt;em&gt;past&lt;/em&gt; and &lt;em&gt;present&lt;/em&gt; is to be kept in mind. If your current txid is 100, you can only view txids less than that since they are considered &lt;em&gt;past&lt;/em&gt;. Transaction ids greater than that will not be viewable as they are considered future and hence invisible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tuple Structure
&lt;/h2&gt;

&lt;p&gt;Heap tuples in table pages have three parts: HeapTupleHeaderData structure, NULL bitmap, and user data.&lt;/p&gt;

&lt;p&gt;The HeapTupleHeaderData has seven fields, for of which are described in this chapter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;t_xmin&lt;/strong&gt; contains the txid of the transaction which inserted this tuple.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;t_xmax&lt;/strong&gt; contains the txid of the transaction which deleted or updated this tuple while 0 would mean this tuple has not been deleted or updated as of yet&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;t_cid&lt;/strong&gt; holds the current command id (cid)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;t_ctid&lt;/strong&gt; holds the tuple id (tid) that points to itself or to a new tuple id if tuple has been updated.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Inserting, Deleting and Updating Tuples
&lt;/h2&gt;

&lt;p&gt;This section of the chapter contains in-depth examples of what happens when inserting, deleting or updating a tuple and of how a Free Space Map (FSM) is used by PostgreSQL.&lt;/p&gt;

&lt;p&gt;I highly recommend reading this section from the book to better understand through the examples and diagrams provided.&lt;/p&gt;

&lt;h2&gt;
  
  
  Commit Log (clog)
&lt;/h2&gt;

&lt;p&gt;The statuses of transactions performed are stored in the Commit Log (clog) in PostgreSQL.&lt;/p&gt;

&lt;p&gt;PostgreSQL has 4 defined transaction states:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;IN_PROGRESS&lt;/strong&gt;: transaction is in progress&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;COMMITTED&lt;/strong&gt;: transaction has been committed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ABORTED&lt;/strong&gt;: transaction has been aborted&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SUB_COMMITTED&lt;/strong&gt;: denotes sub-transactions (not elaborated upon in the book)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The clog takes up one or more pages of 8KB each in the shared memory and logically forms an array. The indices of this array match respective transaction ids. The status of each transaction is stored at its respective index in the table.&lt;br&gt;
When the current txid goes beyond the capacity of the clog, a new page is appended.&lt;/p&gt;

&lt;p&gt;In the case that PostgreSQL shuts down or if the checkpoint process is run, the contents of the clog are copied into files stored in the &lt;em&gt;pg_xact&lt;/em&gt; sub directory. The files are named from 0000, 0001 to so on and so forth. The maximum file size is 256 KB. When PostgreSQL starts up, the data from files stored in pg_xact is used to initialise the clog.&lt;/p&gt;

&lt;h2&gt;
  
  
  Transaction Snapshot
&lt;/h2&gt;

&lt;p&gt;A transaction snapshot stores data about whether transactions are or are not active at a certain point in time.&lt;br&gt;
In PostgreSQL, this is textually represented in a form such as '100 : 100 :' which denotes that txids less than 100 are not active and txids greater than or equal to 100 are active.&lt;/p&gt;

&lt;p&gt;Transaction Snapshots are provided by the Transaction Manager. These snapshots are then used for visibility checks by PostgreSQL as mentioned above.&lt;/p&gt;

&lt;h2&gt;
  
  
  Visibility Check Rules
&lt;/h2&gt;

&lt;p&gt;Visibility checks rules determine whether a tuple is invisible (future) or visible (past) by using the data stored in t_xmin, t_xmax, clog, and the transaction snapshot. This chapter only goes into the minimal rules used for visibility checks.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rule 1&lt;/strong&gt;: if t_xmin status is ABORTED, tuple is invisible&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rule 2&lt;/strong&gt;: if t_xmin status is IN_PROGRESS, its value is equal to current txid, and t_xmax is &lt;strong&gt;INVALID&lt;/strong&gt; then transaction is visible&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;If Status(t_xmin) = IN_PROGRESS ∧ t_xmin = current_txid ∧ t_xmax = INVALID ⇒ Visible&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rule 3&lt;/strong&gt;: if t_xmin status is IN_PROGRESS and its value is equal to current txid (given that t_xmax is &lt;strong&gt;not INVALID&lt;/strong&gt;), tuple is invisible&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;If Status(t_xmin) = IN_PROGRESS ∧ t_xmin = current_txid ∧ t_xmax ≠ INVALID ⇒ Invisible&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rule 4&lt;/strong&gt;: if the tuple is inserted by another transaction (txid is &lt;strong&gt;not&lt;/strong&gt; equal to current txid) and t_xmin staus is IN_PROGRESS, tuple is invisible&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;If Status(t_xmin) = IN_PROGRESS ∧ t_xmin ≠ current_txid ⇒ Invisible&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Rule 5&lt;/strong&gt;: &lt;em&gt;If Status(t_xmin) = COMMITTED ∧ Snapshot(t_xmin) = active ⇒ Invisible&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Rule 6&lt;/strong&gt;: &lt;em&gt;If Status(t_xmin) = COMMITTED ∧ (t_xmax = INVALID ∨ Status(t_xmax) = ABORTED) ⇒ Visible&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Rule 7&lt;/strong&gt;: &lt;em&gt;If Status(t_xmin) = COMMITTED ∧ Status(t_xmax) = IN_PROGRESS ∧ t_xmax = current_txid ⇒ Invisible&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Rule 8&lt;/strong&gt;: &lt;em&gt;If Status(t_xmin) = COMMITTED ∧ Status(t_xmax) = IN_PROGRESS ∧ t_xmax ≠ current_txid ⇒ Visible&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Rule 9&lt;/strong&gt;: &lt;em&gt;If Status(t_xmin) = COMMITTED ∧ Status(t_xmax) = COMMITTED ∧ Snapshot(t_xmax) = active ⇒ Visible&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Rule 10&lt;/strong&gt;: &lt;em&gt;If Status(t_xmin) = COMMITTED ∧ Status(t_xmax) = COMMITTED ∧ Snapshot(t_xmax) ≠ active ⇒ Invisible&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This chapter goes into further detail about how these rules are implemented along with how Lost Updates* are prevented through scenarios and examples which I highly recommend reading.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;a Lost Update (also called a ww-conflict) is an anomaly which occurs when two transactions attempt to updates the same rows simultaneously&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Serializable Snapshot Isolation
&lt;/h2&gt;

&lt;p&gt;If a cycle is created containing conflicts in the precedence graph, a serialisation anomaly will occur.&lt;/p&gt;

&lt;p&gt;There are three types of conflicts: wr-conflicts (Dirty Reads), ww-conflicts (Lost Updates), and rw-conflicts. wr and ww conflicts are already prevented by PostgreSQL, hence SSI implementation in PostgreSQL only handles rw-conflicts using the following strategy:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Record all objects (tuples, pages, relations) accessed by transactions as SIREAD locks.&lt;/li&gt;
&lt;li&gt;Detect rw-conflicts using SIREAD locks whenever any heap or index tuple is written.&lt;/li&gt;
&lt;li&gt;Abort the transaction if a serialisation anomaly is detected by checking detected rw-conflicts.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Required Maintenance Processes
&lt;/h2&gt;

&lt;p&gt;The following maintenance processes are required by PostgreSQL's concurrency control mechanism:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Remove dead tuples and index tuples that point to corresponding dead tuples&lt;/li&gt;
&lt;li&gt;Remove unnecessary parts of the clog&lt;/li&gt;
&lt;li&gt;Freeze old txids*&lt;/li&gt;
&lt;li&gt;Update FSM, VM, and the statistics&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;FREEZE is a process in PostgreSQL whereby a frozen txid is defined in such a way that it is always older than other txids and is hence always inactive and visible&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>postgres</category>
      <category>database</category>
      <category>sql</category>
    </item>
    <item>
      <title>Demystifying the Internals of PostgreSQL - Chapter 4</title>
      <dc:creator>Nile Lazarus</dc:creator>
      <pubDate>Fri, 23 Jun 2023 19:40:54 +0000</pubDate>
      <link>https://dev.to/nilelazarus/demystifying-the-internals-of-postgresql-chapter-4-1da9</link>
      <guid>https://dev.to/nilelazarus/demystifying-the-internals-of-postgresql-chapter-4-1da9</guid>
      <description>&lt;p&gt;Welcome back to our journey into &lt;a href="https://www.interdb.jp/pg/index.html"&gt;The Internals of PostgreSQL&lt;/a&gt;.&lt;br&gt;
In the last blog in this series, we covered Chapter 3 'Query Processing'.&lt;br&gt;
Now we're going to cover &lt;a href="https://www.interdb.jp/pg/pgsql04.html"&gt;Chapter 4 'Foreign Data Wrappers and Parallel Query'&lt;/a&gt;. Let's jump right in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Foreign Data Wrappers (FDW)
&lt;/h2&gt;

&lt;p&gt;SQL Management of External Data (SQL/MED) is a part of the SQL Standard that was added in 2003. It states that a table on a remote server is called a &lt;em&gt;foreign table&lt;/em&gt;. PostgreSQL's Foreign Data Wrappers (FDW) use SQL/MED to manage these foreign tables.&lt;br&gt;
Once you install the required extension and configure your settings appropriately, you can begin accessing foreign tables on remote servers. For example, you can use SELECT queries to access foreign tables  stored in different servers.&lt;br&gt;
Many different FDW extensions have been developed and are listed in the Postgres wiki but the only properly maintained one is the postgres_fdw extension which has been officially developed and maintained by PostgreSQL Global Development Group.&lt;/p&gt;

&lt;p&gt;To use the FDW feature, you will need to not only install the required extension but also execute setup commands like  CREATE FOREIGN TABLE, CREATE SERVER and CREATE USER MAPPING.&lt;br&gt;
The work flow of the FDW feature in PostgreSQL is as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The Analyzer creates a query tree for the given SQL query using the foreign tables definitions. These definitions are stored in the pg_catalog.pg_class and pg_catalog.pg_foreign_table catalogs.&lt;/li&gt;
&lt;li&gt;The Planner or Executor then connects to the remote server using the appropriate library. For example, postgres_fdw uses libpq to connect to a remote PostgreSQL server, and mysql_fdw uses libmysqlclient to connect to a mysql server.&lt;/li&gt;
&lt;li&gt;If the &lt;em&gt;use_remote_estimate&lt;/em&gt; option has been enabled, EXPLAIN commands are executed by the Planner for cost estimation of each plan path. If not, the embedded constant values are used by default.&lt;/li&gt;
&lt;li&gt;Planner creates a plain text SQL statement from the plan tree. This process is called &lt;em&gt;deparsing&lt;/em&gt; in PostgreSQL.&lt;/li&gt;
&lt;li&gt;Executor sends the plain text SQL statement created by the Planner to the remote server and receives the result.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This section also details how the postgres_fdw extension performs and how it has evolved over the course of multiple versions of PostgreSQL starting with version 9.3. I highly recommend reading through it yourself to understand better as this section contains many examples which can help you better understand how different SQL operations and functions are handled by the FDW.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This section also includes Parallel Query however it is currently under construction&lt;/em&gt;&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>database</category>
      <category>sql</category>
    </item>
  </channel>
</rss>
