<?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: Mohammed Azim J</title>
    <description>The latest articles on DEV Community by Mohammed Azim J (@mohammed_azim_j).</description>
    <link>https://dev.to/mohammed_azim_j</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%2F3837119%2Fcde19818-01c6-4676-97ff-2d909c5de7d0.png</url>
      <title>DEV Community: Mohammed Azim J</title>
      <link>https://dev.to/mohammed_azim_j</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mohammed_azim_j"/>
    <language>en</language>
    <item>
      <title>CA 30 - Basic Select SQL Queries</title>
      <dc:creator>Mohammed Azim J</dc:creator>
      <pubDate>Sun, 29 Mar 2026 13:53:04 +0000</pubDate>
      <link>https://dev.to/mohammed_azim_j/ca-30-basic-select-sql-queries-25b5</link>
      <guid>https://dev.to/mohammed_azim_j/ca-30-basic-select-sql-queries-25b5</guid>
      <description>&lt;p&gt;First problem was Select By ID. The question was to select all columns from CITY table where ID = 1661.&lt;/p&gt;

&lt;p&gt;SELECT * &lt;br&gt;
FROM CITY&lt;br&gt;
WHERE ID = 1661;&lt;/p&gt;

&lt;p&gt;This was simple, we just filter using WHERE and ID. Since we need all columns, we used *.&lt;/p&gt;

&lt;p&gt;Next was Japanese Cities Attributes. We need to get all columns for cities in Japan.&lt;/p&gt;

&lt;p&gt;SELECT * &lt;br&gt;
FROM CITY&lt;br&gt;
WHERE COUNTRYCODE = 'JPN';&lt;/p&gt;

&lt;p&gt;Here we filter rows where country code is JPN. Again * because all columns needed.&lt;/p&gt;

&lt;p&gt;Next was Revising the Select Query 2. We need city names where population &amp;gt; 120000.&lt;/p&gt;

&lt;p&gt;SELECT NAME&lt;br&gt;
FROM CITY&lt;br&gt;
WHERE POPULATION &amp;gt; 120000;&lt;/p&gt;

&lt;p&gt;Here we only need NAME column so we did not use *.&lt;/p&gt;

&lt;p&gt;Next was Weather Observation Station 9. We need city names that do not start with vowels.&lt;/p&gt;

&lt;p&gt;SELECT DISTINCT CITY&lt;br&gt;
FROM STATION&lt;br&gt;
WHERE CITY NOT LIKE 'A%'&lt;br&gt;
AND CITY NOT LIKE 'E%'&lt;br&gt;
AND CITY NOT LIKE 'I%'&lt;br&gt;
AND CITY NOT LIKE 'O%'&lt;br&gt;
AND CITY NOT LIKE 'U%';&lt;/p&gt;

&lt;p&gt;I used NOT LIKE because we need cities not starting with vowels and DISTINCT to remove duplicates.&lt;/p&gt;

&lt;p&gt;Next was Weather Observation Station 1. We need city and state from station table.&lt;/p&gt;

&lt;p&gt;SELECT CITY, STATE&lt;br&gt;
FROM STATION;&lt;/p&gt;

&lt;p&gt;Here just selecting two columns.&lt;/p&gt;

&lt;p&gt;Next was Revising the Select Query. We need all columns where population &amp;gt; 100000.&lt;/p&gt;

&lt;p&gt;SELECT *&lt;br&gt;
FROM CITY&lt;br&gt;
WHERE POPULATION &amp;gt; 100000;&lt;/p&gt;

&lt;p&gt;Used WHERE to filter population.&lt;/p&gt;

&lt;p&gt;Next was Weather Observation Station 4. Count number of duplicate city entries.&lt;/p&gt;

&lt;p&gt;SELECT COUNT(CITY) - COUNT(DISTINCT CITY)&lt;br&gt;
FROM STATION;&lt;/p&gt;

&lt;p&gt;This was interesting. Total cities minus unique cities gives duplicate count.&lt;/p&gt;

&lt;p&gt;Next was Japanese Cities Name. We need names of cities in Japan.&lt;/p&gt;

&lt;p&gt;SELECT NAME&lt;br&gt;
FROM CITY&lt;br&gt;
WHERE COUNTRYCODE = 'JPN';&lt;/p&gt;

&lt;p&gt;Same logic as earlier but only NAME column.&lt;/p&gt;

&lt;p&gt;Last was Select All SQL. Display all columns from CITY.&lt;/p&gt;

&lt;p&gt;SELECT *&lt;br&gt;
FROM CITY;&lt;/p&gt;

&lt;p&gt;This is the most basic SELECT query.&lt;/p&gt;

&lt;p&gt;After doing these problems I understood basic SELECT, WHERE, DISTINCT, COUNT, LIKE, and filtering. These are very basic SQL but very important because almost every query uses these concepts.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>database</category>
      <category>sql</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>CA 28 – Create a simple EC2 instance and run a webserver</title>
      <dc:creator>Mohammed Azim J</dc:creator>
      <pubDate>Sun, 29 Mar 2026 13:44:16 +0000</pubDate>
      <link>https://dev.to/mohammed_azim_j/ca-28-create-a-simple-ec2-instance-and-run-a-webserver-2a8g</link>
      <guid>https://dev.to/mohammed_azim_j/ca-28-create-a-simple-ec2-instance-and-run-a-webserver-2a8g</guid>
      <description>&lt;p&gt;This task was about creating a simple EC2 instance in AWS and running a web server and accessing it from the internet.&lt;/p&gt;

&lt;p&gt;First i went to AWS EC2 dashboard and launched a new instance. I selected Amazon Linux and a small instance type . Then i created a key pair and downloaded it so i can connect to the server using SSH.&lt;/p&gt;

&lt;p&gt;One important step here was security group , I allowed port 22 for SSH and port 80 for HTTP otherwise the website will not open from browser.&lt;/p&gt;

&lt;p&gt;After the instance started I connected to it using SSH and installed a web server (apache/httpd). Then I started the web server service and created a simple HTML file in the web server folder.&lt;/p&gt;

&lt;p&gt;After that I copied the public IP address of the EC2 instance and opened it in the browser. The webpage loaded, so that means the web server is accessible from outside.&lt;/p&gt;

&lt;p&gt;So overall steps were: create EC2 -&amp;gt; allow ports -&amp;gt; connect using SSH -&amp;gt; install web server -&amp;gt; start service -&amp;gt; open public IP in browser.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>beginners</category>
      <category>cloud</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>CA 29 – Setup a DNS Hosted Zone in Route53 (AWS)</title>
      <dc:creator>Mohammed Azim J</dc:creator>
      <pubDate>Sun, 29 Mar 2026 13:41:51 +0000</pubDate>
      <link>https://dev.to/mohammed_azim_j/ca-29-setup-a-dns-hosted-zone-in-route53-aws-2557</link>
      <guid>https://dev.to/mohammed_azim_j/ca-29-setup-a-dns-hosted-zone-in-route53-aws-2557</guid>
      <description>&lt;p&gt;This task was about setting up a DNS hosted zone in AWS Route53. Before doing this, I only knew that DNS converts domain name into IP address, but I did not know how we actually configure DNS in real systems. This exercise helped me understand that part a little better.&lt;/p&gt;

&lt;p&gt;First I logged into AWS console and searched for Route53. Inside Route53 there is something called Hosted Zones. Hosted zone is basically a place where we store DNS records for a domain. So if we own a domain like example.com, we create a hosted zone for that domain and then add records like A record, CNAME etc.&lt;/p&gt;

&lt;p&gt;So I created a hosted zone by giving the domain name and selecting public hosted zone. After creating it, AWS automatically created some default records like NS and SOA records. The NS records are important because they tell the internet that AWS Route53 is handling DNS for this domain.&lt;/p&gt;

&lt;p&gt;Then the next step was to add records. I added an A record which maps a domain name to an IP address. For example, I mapped my domain to a server IP so that when someone types the domain name in the browser, it will go to that server.&lt;/p&gt;

&lt;p&gt;One thing I understood here is DNS is not instant. After changing records, it takes some time to propagate. Sometimes a few minutes, sometimes longer.&lt;/p&gt;

&lt;p&gt;So overall the steps I did were:&lt;br&gt;
First create hosted zone&lt;br&gt;
Then note the name servers&lt;br&gt;
Then add DNS records like A record or CNAME&lt;br&gt;
Then wait for DNS propagation&lt;/p&gt;

&lt;p&gt;This exercise helped me understand that DNS is like a phonebook of the internet. Route53 is basically AWS service that manages that phonebook.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>beginners</category>
      <category>networking</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>CA 40 – Alter Tables</title>
      <dc:creator>Mohammed Azim J</dc:creator>
      <pubDate>Sun, 29 Mar 2026 13:37:39 +0000</pubDate>
      <link>https://dev.to/mohammed_azim_j/ca-40-alter-tables-bma</link>
      <guid>https://dev.to/mohammed_azim_j/ca-40-alter-tables-bma</guid>
      <description>&lt;p&gt;This exercise was about ALTER TABLE. Instead of creating table again, we modify existing table like adding constraints, defaults, columns etc.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make email NOT NULL in customers table&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;sql &lt;br&gt;
id="h4r9b2"&lt;br&gt;
ALTER TABLE customers&lt;br&gt;
ALTER COLUMN email SET NOT NULL;&lt;/p&gt;

&lt;p&gt;This makes sure future rows must have email.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make username unique in users table&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;sql &lt;br&gt;
id="9zv1qx"&lt;br&gt;
ALTER TABLE users&lt;br&gt;
ADD CONSTRAINT unique_username UNIQUE (username);&lt;/p&gt;

&lt;p&gt;This prevents duplicate usernames.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add check constraint price &amp;gt; 0 in products table&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;sql &lt;br&gt;
id="g6p8la"&lt;br&gt;
ALTER TABLE products&lt;br&gt;
ADD CONSTRAINT price_check CHECK (price &amp;gt; 0);&lt;/p&gt;

&lt;p&gt;Now price cannot be zero or negative.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set default status 'pending' in orders table&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;sql &lt;br&gt;
id="s8k3po"&lt;br&gt;
ALTER TABLE orders&lt;br&gt;
ALTER COLUMN status SET DEFAULT 'pending';&lt;/p&gt;

&lt;p&gt;If status not given, it will automatically become pending.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add salary column in employees table with conditions&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;sql &lt;br&gt;
id="x2w7mn"&lt;br&gt;
ALTER TABLE employees&lt;br&gt;
ADD COLUMN salary INT NOT NULL;&lt;/p&gt;

&lt;p&gt;ALTER TABLE employees&lt;br&gt;
ADD CONSTRAINT salary_check CHECK (salary &amp;gt; 10000);&lt;/p&gt;

&lt;p&gt;Salary cannot be null and must be &amp;gt; 10000.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Modify foreign key so delete department deletes employees&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;sql &lt;br&gt;
id="f5t9yr"&lt;br&gt;
ALTER TABLE employees&lt;br&gt;
DROP CONSTRAINT employees_department_id_fkey;&lt;/p&gt;

&lt;p&gt;ALTER TABLE employees&lt;br&gt;
ADD CONSTRAINT employees_department_id_fkey&lt;br&gt;
FOREIGN KEY (department_id)&lt;br&gt;
REFERENCES departments(id)&lt;br&gt;
ON DELETE CASCADE;&lt;/p&gt;

&lt;p&gt;Now deleting department deletes employees automatically.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Remove check constraint balance &amp;gt;= 0 from accounts table&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;sql &lt;br&gt;
id="k7d3qp"&lt;br&gt;
ALTER TABLE accounts&lt;br&gt;
DROP CONSTRAINT accounts_balance_check;&lt;/p&gt;

&lt;p&gt;This removes the check constraint.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make combination of user_id and transaction_id unique in payments table&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;sql &lt;br&gt;
id="m1c8zs"&lt;br&gt;
ALTER TABLE payments&lt;br&gt;
ADD CONSTRAINT unique_payment UNIQUE (user_id, transaction_id);&lt;/p&gt;

&lt;p&gt;This prevents duplicate transaction per user.&lt;/p&gt;

&lt;p&gt;From this exercise I learned ALTER TABLE is used to modify table structure without deleting table. Very useful when database already has data.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>database</category>
      <category>sql</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>CA 39 – Create Tables</title>
      <dc:creator>Mohammed Azim J</dc:creator>
      <pubDate>Sun, 29 Mar 2026 11:27:05 +0000</pubDate>
      <link>https://dev.to/mohammed_azim_j/ca-39-create-tables-1043</link>
      <guid>https://dev.to/mohammed_azim_j/ca-39-create-tables-1043</guid>
      <description>&lt;p&gt;This exercise was about creating tables with different constraints like primary key, unique, not null, check, default and foreign key. I wrote the queries and tried to understand why we use each constraint.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create students table with id unique
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;students&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;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here id is primary key so it will be unique automatically and identify each student.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create employees where name and email cannot be empty
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;employees&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;TEXT&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;TEXT&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;phone_number&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;phone_number is optional so no NOT NULL.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Users table where username and email must be unique
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;users&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;username&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&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;TEXT&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;UNIQUE makes sure no duplicate username or email.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Products table where price &amp;gt; 0 and stock not negative
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;products&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;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;CHECK&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;stock&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;CHECK&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stock&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CHECK constraint used for conditions.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Orders table with default status and timestamp
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;orders&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;status&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="s1"&gt;'pending'&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;DEFAULT automatically inserts value.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Accounts table
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;accounts&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;account_number&lt;/span&gt; &lt;span class="nb"&gt;TEXT&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;balance&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;CHECK&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Enrollments table unique combination
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;enrollments&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;student_id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;course_id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;UNIQUE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;student_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;course_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prevents same student enrolling same course twice.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Departments and Employees with foreign key
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;departments&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;TEXT&lt;/span&gt;
&lt;span class="p"&gt;);&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;employees&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;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;department_id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;FOREIGN&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;department_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;departments&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Foreign key ensures department must exist.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Foreign key with delete and update cascade
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;departments&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;TEXT&lt;/span&gt;
&lt;span class="p"&gt;);&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;employees&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;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;department_id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;FOREIGN&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;department_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;departments&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;DELETE&lt;/span&gt; &lt;span class="k"&gt;CASCADE&lt;/span&gt;
    &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="k"&gt;CASCADE&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If department deleted, employees also deleted. If department id updated, it updates here also.&lt;/p&gt;

&lt;p&gt;From this exercise I understood constraints are very important because they prevent wrong data from entering into database and maintain consistency.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>CA 38 – Idempotency Situation</title>
      <dc:creator>Mohammed Azim J</dc:creator>
      <pubDate>Sun, 29 Mar 2026 11:24:00 +0000</pubDate>
      <link>https://dev.to/mohammed_azim_j/ca-38-idempotency-situation-3hdf</link>
      <guid>https://dev.to/mohammed_azim_j/ca-38-idempotency-situation-3hdf</guid>
      <description>&lt;p&gt;This task was about what happens if same transaction runs multiple times, like due to network retry or user clicking twice.&lt;/p&gt;

&lt;p&gt;First I checked initial data:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```sql id="t9z4an"&lt;br&gt;
SELECT * FROM accounts;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Alice -&amp;gt; 1000
Bob -&amp;gt; 500

Then I did a transfer (Alice → Bob 200):



```sql id="u2x9pl"
BEGIN;

UPDATE accounts
SET balance = balance - 200
WHERE name = 'Alice';

UPDATE accounts
SET balance = balance + 200
WHERE name = 'Bob';

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

&lt;/div&gt;


&lt;p&gt;Now balances:&lt;/p&gt;

&lt;p&gt;Alice -&amp;gt; 800&lt;br&gt;
Bob -&amp;gt; 700&lt;/p&gt;

&lt;p&gt;Then I ran same transaction again (same query again):&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```sql id="l8k2ws"&lt;br&gt;
BEGIN;&lt;/p&gt;

&lt;p&gt;UPDATE accounts&lt;br&gt;
SET balance = balance - 200&lt;br&gt;
WHERE name = 'Alice';&lt;/p&gt;

&lt;p&gt;UPDATE accounts&lt;br&gt;
SET balance = balance + 200&lt;br&gt;
WHERE name = 'Bob';&lt;/p&gt;

&lt;p&gt;COMMIT;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Now balances became:

Alice -&amp;gt; 600
Bob -&amp;gt; 900

So same request executed twice and money got transferred twice.
Database did not stop it.

So I understood this point:
DB alone will not prevent duplicate transactions.

Then I thought how real systems solve this.

One idea is using transaction_id:



```sql id="p7n3ye"
CREATE TABLE transactions (
    id SERIAL PRIMARY KEY,
    txn_id TEXT UNIQUE,
    sender TEXT,
    receiver TEXT,
    amount INT
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then before inserting:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```sql id="q3m8hv"&lt;br&gt;
INSERT INTO transactions (txn_id, sender, receiver, amount)&lt;br&gt;
VALUES ('TXN123', 'Alice', 'Bob', 200);&lt;/p&gt;

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


If same txn_id comes again, it will fail because of UNIQUE constraint.

So same transaction will not run again.

So what I understood:

Running same query again = duplicate money transfer
Database allows it
Idempotency must be handled using unique request id or logic

So idempotency means even if same request comes multiple times, result should happen only once.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
    </item>
    <item>
      <title>CA 37 – Durability (ACID)</title>
      <dc:creator>Mohammed Azim J</dc:creator>
      <pubDate>Sun, 29 Mar 2026 11:06:36 +0000</pubDate>
      <link>https://dev.to/mohammed_azim_j/ca-37-durability-acid-n7e</link>
      <guid>https://dev.to/mohammed_azim_j/ca-37-durability-acid-n7e</guid>
      <description>&lt;p&gt;This one is about Durability, means once data is saved (commit), it should not disappear even if system crashes.&lt;/p&gt;

&lt;p&gt;First I checked initial data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="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;accounts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alice -&amp;gt; 1000&lt;br&gt;
Bob -&amp;gt; 500&lt;/p&gt;

&lt;p&gt;Then I did a transfer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;accounts&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Alice'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;accounts&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Bob'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;COMMIT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After commit I checked again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="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;accounts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alice -&amp;gt; 700&lt;br&gt;
Bob -&amp;gt; 800&lt;/p&gt;

&lt;p&gt;So transfer done.&lt;/p&gt;

&lt;p&gt;Now imagine system crash or restart. After reconnecting I ran same query again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="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;accounts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Still:&lt;br&gt;
Alice -&amp;gt; 700&lt;br&gt;
Bob -&amp;gt; 800&lt;/p&gt;

&lt;p&gt;So data is not lost. That is durability.&lt;/p&gt;

&lt;p&gt;Then I thought what if crash happens before commit → changes not saved.&lt;br&gt;
If crash happens after commit → data stays safe.&lt;/p&gt;

&lt;p&gt;So database makes sure once COMMIT happens, data is stored properly (in disk/logs).&lt;/p&gt;

&lt;p&gt;So simple idea:&lt;/p&gt;

&lt;p&gt;Before commit → not permanent&lt;br&gt;
After commit → permanent&lt;/p&gt;

&lt;p&gt;That is durability, even crash also cannot remove committed data.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>computerscience</category>
      <category>database</category>
      <category>sql</category>
    </item>
    <item>
      <title>CA 36 – Isolation (ACID)</title>
      <dc:creator>Mohammed Azim J</dc:creator>
      <pubDate>Sun, 29 Mar 2026 10:36:07 +0000</pubDate>
      <link>https://dev.to/mohammed_azim_j/ca-36-isolation-acid-3bn</link>
      <guid>https://dev.to/mohammed_azim_j/ca-36-isolation-acid-3bn</guid>
      <description>&lt;p&gt;This one was about Isolation, basically what happens when two people try to use the same account at the same time.&lt;/p&gt;

&lt;p&gt;I used two sessions (like opening two terminals).&lt;/p&gt;

&lt;p&gt;First I checked data:&lt;/p&gt;

&lt;p&gt;SELECT * FROM accounts;&lt;/p&gt;

&lt;p&gt;Alice -&amp;gt; 1000&lt;br&gt;
Bob -&amp;gt; 500&lt;/p&gt;

&lt;p&gt;Now in Session 1:&lt;/p&gt;

&lt;p&gt;BEGIN;&lt;/p&gt;

&lt;p&gt;UPDATE accounts&lt;br&gt;
SET balance = balance - 800&lt;br&gt;
WHERE name = 'Alice';&lt;/p&gt;

&lt;p&gt;I did not commit yet.&lt;/p&gt;

&lt;p&gt;Now in Session 2, I tried:&lt;/p&gt;

&lt;p&gt;SELECT * FROM accounts WHERE name = 'Alice';&lt;/p&gt;

&lt;p&gt;It still shows 1000, not 200.&lt;br&gt;
So uncommitted change is not visible → no dirty read.&lt;/p&gt;

&lt;p&gt;Then in Session 2 I tried to update:&lt;/p&gt;

&lt;p&gt;UPDATE accounts&lt;br&gt;
SET balance = balance - 300&lt;br&gt;
WHERE name = 'Alice';&lt;/p&gt;

&lt;p&gt;This got stuck (waiting).&lt;br&gt;
Because Session 1 is still holding the lock.&lt;/p&gt;

&lt;p&gt;Then I commit in Session 1:&lt;/p&gt;

&lt;p&gt;COMMIT;&lt;/p&gt;

&lt;p&gt;Now Session 2 continues and updates based on new value.&lt;/p&gt;

&lt;p&gt;So final balance becomes:&lt;br&gt;
1000 - 800 - 300 = -100 (but this fails due to CHECK constraint)&lt;/p&gt;

&lt;p&gt;So transaction fails and rollback happens.&lt;/p&gt;

&lt;p&gt;Then I tried changing isolation level:&lt;/p&gt;

&lt;p&gt;SET TRANSACTION ISOLATION LEVEL READ COMMITTED;&lt;/p&gt;

&lt;p&gt;Default level, works like above (no dirty reads).&lt;/p&gt;

&lt;p&gt;Then tried:&lt;/p&gt;

&lt;p&gt;SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;&lt;/p&gt;

&lt;p&gt;Now if two transactions conflict, one will fail with error instead of waiting silently.&lt;/p&gt;

&lt;p&gt;So what I understood:&lt;/p&gt;

&lt;p&gt;Isolation makes sure one transaction does not mess with another&lt;br&gt;
Uncommitted data is not visible&lt;br&gt;
Database uses locks to control access&lt;br&gt;
Prevents issues like dirty read and lost update&lt;/p&gt;

&lt;p&gt;So even if two users try to send money at same time, DB keeps things safe.&lt;/p&gt;

</description>
      <category>computerscience</category>
      <category>database</category>
      <category>devjournal</category>
      <category>sql</category>
    </item>
    <item>
      <title>CA 35 – Consistency (ACID)</title>
      <dc:creator>Mohammed Azim J</dc:creator>
      <pubDate>Sun, 29 Mar 2026 10:24:50 +0000</pubDate>
      <link>https://dev.to/mohammed_azim_j/ca-35-consistency-acid-5da</link>
      <guid>https://dev.to/mohammed_azim_j/ca-35-consistency-acid-5da</guid>
      <description>&lt;p&gt;This exercise was about Consistency in databases using the same wallet system accounts table. Atomicity was about all or nothing transactions, but Consistency is about making sure the data always follows the rules defined in the database. The database should never go into an invalid state.&lt;/p&gt;

&lt;p&gt;In our accounts table we already have a constraint:&lt;/p&gt;

&lt;p&gt;balance INT NOT NULL CHECK (balance &amp;gt;= 0)&lt;/p&gt;

&lt;p&gt;This means balance should never become negative. So the database itself is enforcing a rule.&lt;/p&gt;

&lt;p&gt;First I checked the initial data.&lt;/p&gt;

&lt;p&gt;SELECT * FROM accounts;&lt;/p&gt;

&lt;p&gt;Alice -&amp;gt; 1000&lt;br&gt;
Bob -&amp;gt; 500&lt;/p&gt;

&lt;p&gt;Everything is valid.&lt;/p&gt;

&lt;p&gt;Then I tried to deduct more money than Alice has.&lt;/p&gt;

&lt;p&gt;BEGIN;&lt;/p&gt;

&lt;p&gt;UPDATE accounts&lt;br&gt;
SET balance = balance - 1500&lt;br&gt;
WHERE name = 'Alice';&lt;/p&gt;

&lt;p&gt;COMMIT;&lt;/p&gt;

&lt;p&gt;This failed and PostgreSQL showed an error saying the check constraint failed because balance cannot be negative. So the database did not allow the update. This shows consistency is maintained by constraints.&lt;/p&gt;

&lt;p&gt;Then I tried directly setting a negative balance.&lt;/p&gt;

&lt;p&gt;UPDATE accounts&lt;br&gt;
SET balance = -200&lt;br&gt;
WHERE name = 'Bob';&lt;/p&gt;

&lt;p&gt;Again this failed because of the CHECK constraint. So we cannot manually put invalid data also.&lt;/p&gt;

&lt;p&gt;Then I tested inside a transaction.&lt;/p&gt;

&lt;p&gt;BEGIN;&lt;/p&gt;

&lt;p&gt;UPDATE accounts&lt;br&gt;
SET balance = balance - 200&lt;br&gt;
WHERE name = 'Alice';&lt;/p&gt;

&lt;p&gt;UPDATE accounts&lt;br&gt;
SET balance = balance + 200&lt;br&gt;
WHERE name = 'Bob';&lt;/p&gt;

&lt;p&gt;COMMIT;&lt;/p&gt;

&lt;p&gt;This worked because no rule was broken and balances were still valid.&lt;/p&gt;

&lt;p&gt;Then I understood something important. Consistency is maintained in two ways:&lt;/p&gt;

&lt;p&gt;Database level (constraints like CHECK, NOT NULL, PRIMARY KEY)&lt;br&gt;
Application level (logic like cannot transfer if balance is low)&lt;/p&gt;

&lt;p&gt;For example database prevents negative balance using CHECK constraint. But database will not automatically check if Alice has enough balance before transfer unless we write logic for that in transaction or application code.&lt;/p&gt;

&lt;p&gt;So consistency means before transaction and after transaction, the database must be in a valid state and all rules must be satisfied.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>CA 34 – Atomicity – Reliable Wallet Transfer System (ACID)</title>
      <dc:creator>Mohammed Azim J</dc:creator>
      <pubDate>Sun, 29 Mar 2026 10:21:57 +0000</pubDate>
      <link>https://dev.to/mohammed_azim_j/ca-34-atomicity-reliable-wallet-transfer-system-acid-24am</link>
      <guid>https://dev.to/mohammed_azim_j/ca-34-atomicity-reliable-wallet-transfer-system-acid-24am</guid>
      <description>&lt;p&gt;This exercise was about understanding Atomicity in databases using a wallet transfer system like PhonePe or GPay. The main idea is when money is transferred from one account to another, both debit and credit must happen together. If one fails, everything should rollback. That is what Atomicity means either everything happens or nothing happens.&lt;/p&gt;

&lt;p&gt;First we created the accounts table and inserted dummy data like Alice and Bob with balances.&lt;/p&gt;

&lt;p&gt;Before doing any transfer, I checked the balances.&lt;/p&gt;

&lt;p&gt;SELECT * FROM accounts;&lt;/p&gt;

&lt;p&gt;Suppose Alice sends 200 to Bob. We must do this inside a transaction block.&lt;/p&gt;

&lt;p&gt;Correct Transaction (Atomic Transfer):&lt;/p&gt;

&lt;p&gt;BEGIN;&lt;/p&gt;

&lt;p&gt;UPDATE accounts&lt;br&gt;
SET balance = balance - 200&lt;br&gt;
WHERE name = 'Alice';&lt;/p&gt;

&lt;p&gt;UPDATE accounts&lt;br&gt;
SET balance = balance + 200&lt;br&gt;
WHERE name = 'Bob';&lt;/p&gt;

&lt;p&gt;COMMIT;&lt;/p&gt;

&lt;p&gt;Here what happens is first Alice balance reduces, then Bob balance increases, and finally COMMIT saves the changes permanently.&lt;/p&gt;

&lt;p&gt;If we check balances after commit:&lt;br&gt;
Alice = 800&lt;br&gt;
Bob = 700&lt;/p&gt;

&lt;p&gt;So transfer successful.&lt;/p&gt;

&lt;p&gt;Then we tested Atomicity by introducing an error after the debit step.&lt;/p&gt;

&lt;p&gt;Transaction With Error (Testing Atomicity):&lt;/p&gt;

&lt;p&gt;BEGIN;&lt;/p&gt;

&lt;p&gt;UPDATE accounts&lt;br&gt;
SET balance = balance - 200&lt;br&gt;
WHERE name = 'Alice';&lt;/p&gt;

&lt;p&gt;-- Intentional error&lt;br&gt;
UPDATE accounts&lt;br&gt;
SET balance = balance + 200&lt;br&gt;
WHERE name = 'NonExistingUser';&lt;/p&gt;

&lt;p&gt;COMMIT;&lt;/p&gt;

&lt;p&gt;This will cause an error because the user does not exist or the query fails. When error happens, PostgreSQL will not complete the transaction.&lt;/p&gt;

&lt;p&gt;Then we run:&lt;/p&gt;

&lt;p&gt;ROLLBACK;&lt;/p&gt;

&lt;p&gt;After rollback, if we check balances again:&lt;/p&gt;

&lt;p&gt;SELECT * FROM accounts;&lt;/p&gt;

&lt;p&gt;We will see:&lt;br&gt;
Alice = 1000&lt;br&gt;
Bob  =500&lt;/p&gt;

&lt;p&gt;So even though we deducted money from Alice in the first query, because the second query failed, the whole transaction was cancelled. This proves Atomicity – partial update did not happen.&lt;/p&gt;

&lt;p&gt;Then we tested another failure case where we forced an error after debit.&lt;/p&gt;

&lt;p&gt;BEGIN;&lt;/p&gt;

&lt;p&gt;UPDATE accounts&lt;br&gt;
SET balance = balance - 300&lt;br&gt;
WHERE name = 'Alice';&lt;/p&gt;

&lt;p&gt;Force error&lt;br&gt;
SELECT 1/0;&lt;/p&gt;

&lt;p&gt;UPDATE accounts&lt;br&gt;
SET balance = balance + 300&lt;br&gt;
WHERE name = 'Bob';&lt;/p&gt;

&lt;p&gt;COMMIT;&lt;/p&gt;

&lt;p&gt;This gives divide by zero error. Because of that error, the transaction fails and we rollback.&lt;/p&gt;

&lt;p&gt;Again checking balances shows no change. So money was not lost from Alice even though debit query ran earlier. That means database protected the data using Atomicity.&lt;/p&gt;

&lt;p&gt;So finally what I understood from this exercise is, transactions are very important in banking or wallet systems. Without transactions, money may get deducted but not added to the other person, which is very dangerous. Atomicity ensures that both debit and credit happen together, otherwise nothing happens.&lt;/p&gt;

&lt;p&gt;So the main commands used in this exercise are:&lt;br&gt;
BEGIN – start transaction&lt;br&gt;
UPDATE – modify balance&lt;br&gt;
COMMIT – save changes&lt;br&gt;
ROLLBACK – undo changes&lt;/p&gt;

&lt;p&gt;This experiment clearly showed that PostgreSQL follows ACID properties and prevents partial updates in money transfer systems.&lt;/p&gt;

</description>
      <category>computerscience</category>
      <category>database</category>
      <category>sql</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Users, Roles, Groups</title>
      <dc:creator>Mohammed Azim J</dc:creator>
      <pubDate>Sun, 29 Mar 2026 10:13:37 +0000</pubDate>
      <link>https://dev.to/mohammed_azim_j/users-roles-groups-3076</link>
      <guid>https://dev.to/mohammed_azim_j/users-roles-groups-3076</guid>
      <description>&lt;p&gt;Task 1: Create a login role report_user that can only read from the film table&lt;br&gt;
CREATE ROLE report_user WITH LOGIN PASSWORD 'report123';&lt;/p&gt;

&lt;p&gt;GRANT SELECT ON film TO report_user;&lt;/p&gt;

&lt;p&gt;This creates a login user and gives only SELECT permission on film table.&lt;/p&gt;

&lt;p&gt;Task 2: report_user cannot access customer table – Fix it&lt;br&gt;
GRANT SELECT ON customer TO report_user;&lt;/p&gt;

&lt;p&gt;This gives read access to customer table.&lt;/p&gt;

&lt;p&gt;Task 3: Allow report_user to see only customer_id, first_name, last_name&lt;/p&gt;

&lt;p&gt;First remove full access:&lt;/p&gt;

&lt;p&gt;REVOKE SELECT ON customer FROM report_user;&lt;/p&gt;

&lt;p&gt;Then give column level access:&lt;/p&gt;

&lt;p&gt;GRANT SELECT (customer_id, first_name, last_name)&lt;br&gt;
ON customer TO report_user;&lt;br&gt;
Task 4: Create support_user who can SELECT from customer, UPDATE only email column, Cannot DELETE&lt;br&gt;
CREATE ROLE support_user WITH LOGIN PASSWORD 'support123';&lt;/p&gt;

&lt;p&gt;GRANT SELECT ON customer TO support_user;&lt;/p&gt;

&lt;p&gt;GRANT UPDATE (email) ON customer TO support_user;&lt;/p&gt;

&lt;p&gt;We did not give DELETE permission, so they cannot delete.&lt;/p&gt;

&lt;p&gt;Task 5: Remove SELECT access on film from report_user&lt;br&gt;
REVOKE SELECT ON film FROM report_user;&lt;br&gt;
Task 6: Create readonly_group that has SELECT on all tables&lt;br&gt;
CREATE ROLE readonly_group;&lt;/p&gt;

&lt;p&gt;GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly_group;&lt;br&gt;
Task 7: Create analyst1 and analyst2 and add them to readonly_group&lt;br&gt;
CREATE ROLE analyst1 WITH LOGIN PASSWORD 'analyst123';&lt;br&gt;
CREATE ROLE analyst2 WITH LOGIN PASSWORD 'analyst123';&lt;/p&gt;

&lt;p&gt;GRANT readonly_group TO analyst1;&lt;br&gt;
GRANT readonly_group TO analyst2;&lt;/p&gt;

</description>
      <category>database</category>
      <category>postgres</category>
      <category>sql</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>DB-TASK-002</title>
      <dc:creator>Mohammed Azim J</dc:creator>
      <pubDate>Wed, 25 Mar 2026 17:15:01 +0000</pubDate>
      <link>https://dev.to/mohammed_azim_j/db-task-002-4mg8</link>
      <guid>https://dev.to/mohammed_azim_j/db-task-002-4mg8</guid>
      <description>&lt;p&gt;Get all movies that have rental rate greater than 3&lt;br&gt;
SELECT * FROM film&lt;br&gt;
WHERE rental_rate &amp;gt; 3;&lt;/p&gt;

&lt;p&gt;I used this to filter movies which are costly rental movies.&lt;/p&gt;

&lt;p&gt;Movies rental rate &amp;gt; 3 and replacement cost &amp;lt; 20&lt;br&gt;
SELECT * FROM film&lt;br&gt;
WHERE rental_rate &amp;gt; 3 AND replacement_cost &amp;lt; 20;&lt;/p&gt;

&lt;p&gt;Here I used AND because both condition must be true.&lt;/p&gt;

&lt;p&gt;Movies rated PG or rental rate 0.99&lt;br&gt;
SELECT * FROM film&lt;br&gt;
WHERE rating = 'PG' OR rental_rate = 0.99;&lt;/p&gt;

&lt;p&gt;I used OR because any one condition is enough.&lt;/p&gt;

&lt;p&gt;First 10 movies sorted by rental rate highest first&lt;br&gt;
SELECT title, rental_rate&lt;br&gt;
FROM film&lt;br&gt;
ORDER BY rental_rate DESC&lt;br&gt;
LIMIT 10;&lt;/p&gt;

&lt;p&gt;I sorted high price first then limited to 10.&lt;/p&gt;

&lt;p&gt;Skip first 5 movies and get next 3 sorted by rental rate ascending&lt;br&gt;
SELECT title, rental_rate&lt;br&gt;
FROM film&lt;br&gt;
ORDER BY rental_rate ASC&lt;br&gt;
OFFSET 5&lt;br&gt;
LIMIT 3;&lt;/p&gt;

&lt;p&gt;OFFSET used to skip rows.&lt;/p&gt;

&lt;p&gt;(same question again so same query)&lt;br&gt;
SELECT title, rental_rate&lt;br&gt;
FROM film&lt;br&gt;
ORDER BY rental_rate ASC&lt;br&gt;
OFFSET 5&lt;br&gt;
LIMIT 3;&lt;br&gt;
Movies with rental duration between 3 and 7&lt;br&gt;
SELECT title, rental_duration&lt;br&gt;
FROM film&lt;br&gt;
WHERE rental_duration BETWEEN 3 AND 7;&lt;/p&gt;

&lt;p&gt;BETWEEN is easier than writing &amp;gt;= and &amp;lt;=.&lt;/p&gt;

&lt;p&gt;Movies title starts with A and ends with e&lt;br&gt;
SELECT title&lt;br&gt;
FROM film&lt;br&gt;
WHERE title LIKE 'A%e';&lt;/p&gt;

&lt;p&gt;LIKE used for pattern search.&lt;/p&gt;

&lt;p&gt;Customers who do not have email&lt;br&gt;
SELECT first_name, last_name&lt;br&gt;
FROM customer&lt;br&gt;
WHERE email IS NULL;&lt;/p&gt;

&lt;p&gt;IS NULL used because = NULL will not work.&lt;/p&gt;

&lt;p&gt;Movies released in 2006, rental rate 2.99 or 3.99 and title starts with S, top 5&lt;br&gt;
SELECT title, rental_rate, release_year&lt;br&gt;
FROM film&lt;br&gt;
WHERE release_year = 2006&lt;br&gt;
AND rental_rate IN (2.99, 3.99)&lt;br&gt;
AND title LIKE 'S%'&lt;br&gt;
LIMIT 5;&lt;/p&gt;

&lt;p&gt;IN used instead of multiple OR.&lt;/p&gt;

&lt;p&gt;Display 10 customers after skipping first 20 sorted by last name&lt;br&gt;
SELECT first_name, last_name&lt;br&gt;
FROM customer&lt;br&gt;
ORDER BY last_name&lt;br&gt;
OFFSET 20&lt;br&gt;
LIMIT 10;&lt;/p&gt;

&lt;p&gt;Used for pagination type query.&lt;/p&gt;

&lt;p&gt;Top 5 movies highest replacement cost skipping most expensive one&lt;br&gt;
SELECT title, replacement_cost&lt;br&gt;
FROM film&lt;br&gt;
ORDER BY replacement_cost DESC&lt;br&gt;
OFFSET 1&lt;br&gt;
LIMIT 5;&lt;/p&gt;

&lt;p&gt;Offset 1 skips most expensive movie.&lt;/p&gt;

&lt;p&gt;Rentals between two dates&lt;br&gt;
SELECT *&lt;br&gt;
FROM rental&lt;br&gt;
WHERE rental_date BETWEEN '2005-05-01' AND '2005-06-01';&lt;/p&gt;

&lt;p&gt;Used BETWEEN for date range.&lt;/p&gt;

&lt;p&gt;Actors last name contain "man"&lt;br&gt;
SELECT first_name, last_name&lt;br&gt;
FROM actor&lt;br&gt;
WHERE last_name LIKE '%man%';&lt;/p&gt;

&lt;p&gt;%man% means contains man anywhere.&lt;/p&gt;

&lt;p&gt;Movies where special features is NULL&lt;br&gt;
SELECT title&lt;br&gt;
FROM film&lt;br&gt;
WHERE special_features IS NULL;&lt;br&gt;
Movies where rental duration more than 7&lt;br&gt;
SELECT title, rental_duration&lt;br&gt;
FROM film&lt;br&gt;
WHERE rental_duration &amp;gt; 7;&lt;br&gt;
First 10 movies rental rate 2.99 or 4.99, rating R and title contains L&lt;br&gt;
SELECT title, rental_rate, rating&lt;br&gt;
FROM film&lt;br&gt;
WHERE rental_rate IN (2.99, 4.99)&lt;br&gt;
AND rating = 'R'&lt;br&gt;
AND title LIKE '%L%'&lt;br&gt;
LIMIT 10;&lt;br&gt;
Movies title starts with A or B and ends with s&lt;br&gt;
SELECT title&lt;br&gt;
FROM film&lt;br&gt;
WHERE (title LIKE 'A%s' OR title LIKE 'B%s');&lt;br&gt;
Movies title contains Man, Men or Woman&lt;br&gt;
SELECT title&lt;br&gt;
FROM film&lt;br&gt;
WHERE title LIKE '%Man%'&lt;br&gt;
OR title LIKE '%Men%'&lt;br&gt;
OR title LIKE '%Woman%';&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>database</category>
      <category>sql</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
