<?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: Chiazam Ochiegbu</title>
    <description>The latest articles on DEV Community by Chiazam Ochiegbu (@tekhunt).</description>
    <link>https://dev.to/tekhunt</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%2F1121106%2F69cc70ce-1d74-4b19-8c5e-62dea5d67be3.jpeg</url>
      <title>DEV Community: Chiazam Ochiegbu</title>
      <link>https://dev.to/tekhunt</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tekhunt"/>
    <language>en</language>
    <item>
      <title>Communicating with PostgreSQL Using LibPQ</title>
      <dc:creator>Chiazam Ochiegbu</dc:creator>
      <pubDate>Thu, 26 Oct 2023 01:30:33 +0000</pubDate>
      <link>https://dev.to/tekhunt/communicating-with-postgresql-using-libpq-5cn2</link>
      <guid>https://dev.to/tekhunt/communicating-with-postgresql-using-libpq-5cn2</guid>
      <description>&lt;p&gt;The libpq library is a PostgreSQL client library to communicate with the PostgreSQL server. The purpose of this chapter is to write the C program to connect to the PostgreSQL server and execute queries in the C programming language. In this chapter, we will explore communication with PostgreSQL using libpq, which includes learning about all the library functions and their utilization with sufficient C code examples. We will also discuss the blocking and nonblocking behavior of libpq functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting and disconnecting to PostgreSQL
&lt;/h2&gt;

&lt;p&gt;The libpq library provides multiple functions and mechanisms to connect to the PostgreSQL server. We will discuss each and every function that is involved in establishing a connection to the backend. An application can have multiple connections with the PostgreSQL database, but needs to maintain the PGconn pointer for each and every connection. The PGconn pointer is a connection object and a function used to establish a connection. It returns the pointer that the application needs to store and use for subsequent functions to query the database. This object must be closed when the connection to the server is no longer needed because the code must release resources that the PostgreSQL runtime allocates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using PQconnectdb
&lt;/h2&gt;

&lt;p&gt;The PQconnectdb function is the most basic function to connect to the PostgreSQL backend. This function takes only one parameter: the conninfo string. The syntax for PQconnectdb is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PGconn *PQconnectdb (const char *conninfo);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The conninfo string is a space-delimited string that contains the keyword value pairs, for&lt;br&gt;
example,&lt;code&gt;keyword = 'foo'&lt;/code&gt;.Hereisthelistofallconninfokeywords:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;hostaddr: This is the IP address of the PostgreSQL server&lt;/li&gt;
&lt;li&gt;host: This is the hostname of the PostgreSQL server; it can be the name of the path of the Unix domain socket. The default value is the /tmp directory&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Note
&lt;/h2&gt;

&lt;p&gt;If the operating system does not support Unix domain sockets, the default value is localhost.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;port: This is the port number of the PostgreSQL server; the - default port is 5432 dbname: This is the name of the database we need to connect to; the default value for this is the username&lt;/li&gt;
&lt;li&gt;user: This is the username to connect as; the default is the - operating system user password: This is the password used during authentication&lt;/li&gt;
&lt;li&gt;connect_timeout: The connect_timeout keyword shows how long the PQconnectdb function waits before giving up&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here are some more options that are not commonly used:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- client_encoding
- options
- application_name
- fallback_application_name
- keepalives
- keepalives_idle
- keepalives_interval
- keepalives_count
- tty
- sslmode
- disable
- allow
- verify-ca
- verify-full
- requiressl
- sslcert
- sslkey
- sslrootcert
- sslcrl
- requirepeer
- krbsrvname
- gsslib
- service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The details of these values can be found at &lt;code&gt;http://www.postgresql.org/docs/9.4/static/libpq- connect.html#LIBPQ-PARAMKEYWORDS&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Note
&lt;/h2&gt;

&lt;p&gt;If you see the following kind of error, then it is due to an error in the conninfo string: missing "=" after "port" in connection info string.&lt;/p&gt;

&lt;p&gt;We'll explore other connection methods in the next article.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>apacheage</category>
    </item>
    <item>
      <title>Dealing with Large Objects in Postgresql</title>
      <dc:creator>Chiazam Ochiegbu</dc:creator>
      <pubDate>Thu, 26 Oct 2023 00:52:58 +0000</pubDate>
      <link>https://dev.to/tekhunt/dealing-with-large-objects-in-postgresql-47fd</link>
      <guid>https://dev.to/tekhunt/dealing-with-large-objects-in-postgresql-47fd</guid>
      <description>&lt;p&gt;Databases provide data types as suitable containers to store values accordingly. You use the int data type to store numeric values and char and varchar data types for string values. Each data type has its own limitations with respect to the size and type of data it can store. A database solution model will be based on real-life problems, therefore these are not the only types of data that you will always confront. We do not live in the ice age anymore; we have to store large-sized images, audio, and video files and varchar is certainly not the answer to this. Objects that require huge storage sizes and can’t be entertained with simple available data types are usually referred to as Large Objects (LOs) or Binary Large Objects (BLOBs). To handle these LOs, you need a LO storage mechanism that can store them easily and access them efficiently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's discuss the following&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why large objects?&lt;/li&gt;
&lt;li&gt;PostgreSQL large objects&lt;/li&gt;
&lt;li&gt;Large objects in action&lt;/li&gt;
&lt;li&gt;Manipulating large objects through the libpq client interface library&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why large objects?
&lt;/h2&gt;

&lt;p&gt;We will see in a more comparative mode why and where we need large objects.&lt;br&gt;
You can categorize large objects in general, based on the structure or type of data. The types you usually come across are as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple &lt;/li&gt;
&lt;li&gt;Complex &lt;/li&gt;
&lt;li&gt;Semi-structured &lt;/li&gt;
&lt;li&gt;Unstructured&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Among the first two, simple-structured data is related to data that can be organized in simple tables and data types and complex-structured data is the one that deals with requirements such as that of user-defined data types.&lt;br&gt;
In the age of the Internet, the types mentioned previously are not the only forms of data that you have to handle; you have XML and JSON as well. It’s not interpreted by a relational database in a general way. This type of data can be categorized as semi- structured. Again, referring to storage of images, audio, and videos that are used massively today and can’t be stored in the same way as the first three types of data because they can’t be broken down into smaller logical structures for interpretation by standard means. It is hence unstructured data and needs a different mechanism to handle them.&lt;br&gt;
PostgreSQL answers your problems with the feature of large objects that store objects of considerably huge size, and it’s been there since the release of the PostgreSQL. Good things happened and over the time it’s got even better.&lt;/p&gt;

&lt;h2&gt;
  
  
  PostgreSQL large objects
&lt;/h2&gt;

&lt;p&gt;Interestingly, PostgreSQL provides two ways to store large objects with respect to each requirement you have to meet. They are as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implementation of the BYTEA data type &lt;/li&gt;
&lt;li&gt;Implementation of large object storage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Though our area of interest here has been large objects, yet we will skim through some characteristics of BYTEA. It is similar to VARCHAR and text character strings, yet it has a few distinctive features as well. It can store raw or unstructured data, but character strings do not. It also allows storing of null values. VARCHAR does not permit storing zero octets, other octets, or sequences of octet values that are not valid as per database character set encoding. While using BYTEA, you can manipulate actual raw bytes, but in the case of character strings, processing is dependent on locale setting.&lt;/p&gt;

&lt;p&gt;BYTEA when compared with large object storage comes with a big difference of storage size; each BYTEA entry permits storage of 1 GB whereas large objects allow up to 4 TB. The large object feature provides functions that help you manipulate external data in a much easier way that could be quite complex when doing the same for BYTEA.&lt;/p&gt;

&lt;p&gt;The preceding discussion was a small comparison and analysis to show you the available choices in PostgreSQL to store binary data using BYTEA or large object storage. A requirement is the best judge to opt any of these.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing large objects
&lt;/h2&gt;

&lt;p&gt;Things are well remembered when they are listed and this is how we will remember PostgreSQL large objects implementation in our memory:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Large objects, unlike BYTEA, are not a data type but an entry in a system table.&lt;/li&gt;
&lt;li&gt;All large objects are stored in the pg_largeobject system table.&lt;/li&gt;
&lt;li&gt;Each large object also has a corresponding entry in the pg_largeobject_metadata system table.&lt;/li&gt;
&lt;li&gt;Large objects are broken up into chunks of default size and further stored as rows in the database.&lt;/li&gt;
&lt;li&gt;These chunks in rows are B-tree indexed; hence, this ensures fast searches during read/write operations.&lt;/li&gt;
&lt;li&gt;From PostgreSQL 9.3 onwards, the maximum size of a large object in a table can be 4 TB.&lt;/li&gt;
&lt;li&gt;Large objects are not stored in user tables; rather, a value of the Object Identifier (OID) type is stored. You will use this OID value to access the large object. So, when you have to access a large object, you will reference the OID value that points to a large object present on the pg_largeobject system table.&lt;/li&gt;
&lt;li&gt;PostgreSQL provides the read/write Application Program Interface (API) that offers client- and server-side functions. Using this API, you can perform operations such as create, modifying, and delete on large objects. OIDs are used in this function as a reference to access large objects, for example, to transfer the contents of any file to the database or to extract an object from the database into a file.&lt;/li&gt;
&lt;li&gt;From PostgreSQL 9.0 onwards, large objects now have an associated owner and a set of access permissions. Retrieving data using these functions gives you the same binary data you added. Examples of the functions are &lt;code&gt;lo_create()&lt;/code&gt;, &lt;code&gt;lo_unlink()&lt;/code&gt;, &lt;code&gt;lo_import()&lt;/code&gt;, and &lt;code&gt;lo_export()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;PostgreSQL provides the &lt;code&gt;ALTER LARGE TABLE&lt;/code&gt; feature to change the definition of a large object. Remember that its only functionality is to assign a new owner.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;br&gt;
Functions for large objects must be called in a transaction block, so when auto-commit is off, make sure that you issue the &lt;code&gt;BEGIN&lt;/code&gt; command explicitly.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>apacheage</category>
    </item>
    <item>
      <title>List Partition in Postgresql</title>
      <dc:creator>Chiazam Ochiegbu</dc:creator>
      <pubDate>Sun, 15 Oct 2023 08:12:33 +0000</pubDate>
      <link>https://dev.to/tekhunt/list-partition-in-postgresql-3bgi</link>
      <guid>https://dev.to/tekhunt/list-partition-in-postgresql-3bgi</guid>
      <description>&lt;p&gt;&lt;code&gt;List partition&lt;/code&gt; is very much similar to range partition. The table is partitioned by explicitly listing which key values appear in each partition. In list partition, each partition is defined and designated based on a column value in one set of value lists, instead of one set of adjoining ranges of values. This will be done by defining each partition by means of the values &lt;code&gt;IN (value_list)&lt;/code&gt; syntax, where &lt;code&gt;value_list&lt;/code&gt; is a comma-separated list of values.&lt;br&gt;
In the preceding article, we have successfully created the range partition. Now for the purpose of list partition, we have to do the same task again. We will create a master table that will have a sales record along with the city information. The list partition will use the city column as a base to create the child partitions.&lt;br&gt;
Let’s create a master table first in the following manner:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE TABLE sales_record_listpart
  (
  id NUMERIC primary key,
  sales_date date,
  sales_amount NUMERIC,
  city text
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s create the child tables, but this time on the basis of the &lt;code&gt;city list&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Create the &lt;code&gt;sales_record_list1&lt;/code&gt; table in the following manner:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; CREATE TABLE sales_record_list1
  (
  PRIMARY KEY (id, city),
  CHECK (city IN ('new york', 'sydney'))
  )
  INHERITS (sales_record_listpart);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, create the &lt;code&gt;sales_record_list2&lt;/code&gt; table in the following manner:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE TABLE sales_record_list2
  (
  PRIMARY KEY (id, city),
  CHECK (city IN ('Islamabad', 'Boston', 'London'))
  )
  INHERITS (sales_record_listpart);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s create the index for the &lt;code&gt;sales_record_list1&lt;/code&gt; table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE INDEX list1_index ON sales_record_list1(city);
Let’s create the index for the sales_record_list2 table:
warehouse_db=# CREATE INDEX list2_index ON sales_record_list2 (city);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, create the trigger function in the following manner:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE OR REPLACE FUNCTION sales_record_list_insert()
RETURNS TRIGGER AS $$
BEGIN
  IF (NEW.city IN ('new york', 'sydney')) THEN
    INSERT INTO sales_record_list1 VALUES (NEW.*);
  ELSEIF (NEW.city IN ('Islamabad', 'Boston', 'London')) THEN
    INSERT INTO sales_record_list2 VALUES (NEW.*);
  ELSE
    RAISE EXCEPTION 'CITY not present in this lists';
  END IF;
  RETURN NULL;
END;
$$
LANGUAGE plpgsql;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the end, we need to create the supporting trigger in the following manner:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE TRIGGER sales_day_trigger
  BEFORE INSERT ON sales_record_listpart
  FOR EACH ROW
  EXECUTE PROCEDURE sales_record_list_insert();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can verify that the partition is linked with the master table using the following command:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Column&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Modifiers&lt;/th&gt;
&lt;th&gt;Storage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;id&lt;/td&gt;
&lt;td&gt;numeric&lt;/td&gt;
&lt;td&gt;not null&lt;/td&gt;
&lt;td&gt;main&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sales_date&lt;/td&gt;
&lt;td&gt;date&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sales_amount&lt;/td&gt;
&lt;td&gt;numeric&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;city&lt;/td&gt;
&lt;td&gt;text&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Indexes:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    "sales_record_listpart_pkey" PRIMARY KEY, btree (id)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Triggers:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;```Sales_day_trigger BEFORE INSERT ON sales_record_listpart FOR EACH ROW
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;EXECUTE PROCEDURE sales_record_list_insert()&lt;/p&gt;

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

**Child tables:** `sales_record_list1, sales_record_list2`
**Has OIDs:** `no`


The preceding output is a partial output of the \d+ command
Now, let’s do some quick inserts and verify that our list partition is also working how we expect it do so:



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

&lt;/div&gt;

&lt;p&gt;INSERT INTO sales_record_listpart&lt;br&gt;
  (id, sales_date, sales_amount, city)&lt;br&gt;
VALUES&lt;br&gt;
  (1,'15-APR-2008',1200,'sydney');&lt;/p&gt;

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




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

&lt;/div&gt;

&lt;p&gt;INSERT INTO sales_record_listpart&lt;br&gt;
  (id, sales_date, sales_amount, city)&lt;br&gt;
VALUES (2,'15-APR-2008',1500,'Boston');&lt;/p&gt;

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




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

&lt;/div&gt;

&lt;p&gt;INSERT INTO sales_record_listpart&lt;br&gt;
(id, sales_date, sales_amount, city)&lt;br&gt;
VALUES (3,'16-APR-2008',1800,'Islamabad');&lt;/p&gt;

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




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

&lt;/div&gt;

&lt;p&gt;INSERT INTO sales_record_listpart&lt;br&gt;
  (id, sales_date, sales_amount, city)&lt;br&gt;
VALUES&lt;br&gt;
  (4,'20-APR-2008',1300,'new york');&lt;/p&gt;

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


&amp;gt;&amp;gt; When you perform the preceding INSERT statements, you will observe that the INSERT query returns the `INSERT 0 0 message;` this is because the record is inserted in the child tables instead of the master tables.

Perform `SELECT` on `select_record_list1` to verify that the record is inserted as expected in the following manner:



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

&lt;/div&gt;

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

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



 id | sales_date | sales_amount |   city
----+------------+--------------+----------
  1 | 2008-04-15 |         1200 |  sydney
  4 | 2008-04-20 |         1300 | new york
(2 rows)


Perform `SELECT` on `select_record_list2` to verify that the record is inserted as expected in the following manner:



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

&lt;/div&gt;

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

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


 id | sales_date | sales_amount |   city
----+------------+--------------+-----------
  2 | 2008-04-15 |         1500 | Boston
  3 | 2008-04-16 |         1800 | Islamabad
(2 rows)


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

&lt;/div&gt;

</description>
      <category>postgres</category>
      <category>apacheage</category>
    </item>
    <item>
      <title>Partitioning in PostgreSQL</title>
      <dc:creator>Chiazam Ochiegbu</dc:creator>
      <pubDate>Fri, 13 Oct 2023 05:11:18 +0000</pubDate>
      <link>https://dev.to/tekhunt/partitioning-in-postgresql-1775</link>
      <guid>https://dev.to/tekhunt/partitioning-in-postgresql-1775</guid>
      <description>&lt;h2&gt;
  
  
  What is Partitioning?
&lt;/h2&gt;

&lt;p&gt;The process of dividing the tables into smaller manageable parts is called partitioning, and these smaller manageable parts are called &lt;code&gt;partitions&lt;/code&gt;.&lt;br&gt;
In the process of partitioning, we divide one logical big table into multiple physical smaller parts.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why do we partition?
&lt;/h2&gt;

&lt;p&gt;Before actually creating the partitions, let’s understand why we need partitions. The first and most demanding reason to use partitions in a database is to increase the performance of the database. This is achieved by &lt;code&gt;partition-wise joins&lt;/code&gt;; if a user’s queries perform a lot of full-table scans, partitioning will help vastly, because partitions will limit the scope of this search. The second important reason to partition is ease of managing large tables.&lt;br&gt;
Partitioning always helps manage large objects. Although it is applicable to objects of any size, the advantages are more apparent in large tables. When a user recreates an index on a nonpartitioned table, the only option is to build the entire index in one statement. On the other hand, if the table is partitioned, the user can rebuild partitions of the local indexes one at a time.&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating a table partition
&lt;/h2&gt;

&lt;p&gt;PostgreSQL supports table partitioning through table inheritance, which means every partition will be created as a child table of a single parent table. Partitioning is performed in such a way that every child table inherits a single parent table. The parent table will be empty; it exists just to describe the whole dataset. Currently in PostgreSQL, partitioning can be implemented in &lt;code&gt;range partitioning&lt;/code&gt; or &lt;code&gt;list partitioning&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Steps to create partition in Postgrsql
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Createthemastertable
2.Create multiple child tables without having an overlapped table constraint&lt;/li&gt;
&lt;li&gt;Create indexes&lt;/li&gt;
&lt;li&gt;Create a trigger function to insert data into childtables&lt;/li&gt;
&lt;li&gt;Enable the constraint exclusion&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;We will focus on creating a &lt;code&gt;range partition&lt;/code&gt; in this article.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Range partition
&lt;/h2&gt;

&lt;p&gt;The range partition is the partition in which we partition a table into ranges defined by a single column or multiple columns. When defining the ranges, the user will have to take care that ranges should be connected and not overlap with each other; moreover, ranges must be defined using the &amp;lt; value operator. For instance, one can partition by date ranges or ranges of identifiers for specific business objects. &lt;/p&gt;

&lt;p&gt;While working with &lt;code&gt;Range Partitioning&lt;/code&gt;, it is important to note the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In PostgreSQL, range partitioning is a method of dividing a table into multiple partitions based on a specified range of values in one or more columns. &lt;/li&gt;
&lt;li&gt;Each partition holds a subset of the data based on the range values, making it an efficient way to manage and query large datasets. &lt;/li&gt;
&lt;li&gt;Range partitioning is particularly useful when your data can be logically divided into non-overlapping ranges, such as date ranges or numerical ranges.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Creating the master table
&lt;/h2&gt;

&lt;p&gt;So, let’s start by creating a simple master table. This table will contain data on sales stored on a daily basis. This will be done in the following manner:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE TABLE sales_record
  (
  id NUMERIC PRIMARY KEY,
  sales_amount NUMERIC,
  sales_date DATE NOT NULL DEFAULT CURRENT_DATE
  );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the parent table; all the records that a user inserts in this table will move to the child table based on the criteria of sales_date that we are going to create in the following section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a range partition table
&lt;/h2&gt;

&lt;p&gt;To implement the partition, we will create child tables. All child tables will inherit the master table. We will add the &lt;code&gt;CHECK&lt;/code&gt; constraint for dates because we want to make sure that we have only the correct data on each partition. Partitions starts from the date &lt;code&gt;2014-01-01&lt;/code&gt; and end on the date &lt;code&gt;2014-12-31&lt;/code&gt;. Each partition will have two months data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE TABLE sales_record_m1_to_m2
  (
  PRIMARY KEY (id, sales_date),
  CHECK (sales_date &amp;gt;= DATE '2014-01-01'
  AND sales_date &amp;lt; DATE '2014-03-01')
  )
  INHERITS (sales_record);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This child table will contain data of January and February.&lt;br&gt;
Now, create the &lt;code&gt;sales_record_m3_to_m4&lt;/code&gt; child table as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE TABLE sales_record_m3_to_m4
  (
  PRIMARY KEY (id, sales_date),
  CHECK (sales_date &amp;gt;= DATE '2014-03-01'
  AND sales_date &amp;lt; DATE '2014-05-01')
  )
  INHERITS (sales_record);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This child table will contain data of March and April.&lt;/p&gt;

&lt;p&gt;Create the &lt;code&gt;sales_record_m5_to_m6&lt;/code&gt; child table as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE TABLE sales_record_m5_to_m6
  (
  PRIMARY KEY (id, sales_date),
  CHECK (sales_date &amp;gt;= DATE '2014-05-01'
  AND sales_date &amp;lt; DATE '2014-07-01')
  )
  INHERITS (sales_record);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This child table will contain data of May and June.&lt;/p&gt;

&lt;p&gt;Create the &lt;code&gt;sales_record_m7_to_m8&lt;/code&gt; child table as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE TABLE sales_record_m7_to_m8
  (
  PRIMARY KEY (id, sales_date),
  CHECK (sales_date &amp;gt;= DATE '2014-07-01'
  AND sales_date &amp;lt; DATE '2014-09-01')
  )
  INHERITS (sales_record);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This child table will contain data of July and August.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE TABLE sales_record_m9_to_m10
  (
  PRIMARY KEY (id, sales_date),
  CHECK (sales_date &amp;gt;= DATE '2014-09-01'
  AND sales_date &amp;lt; DATE '2014-11-01')
  )
  INHERITS (sales_record);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This child table will contain data of September and October.&lt;/p&gt;

&lt;p&gt;Now, create the &lt;code&gt;sales_record_m11_to_m12&lt;/code&gt; child table as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE TABLE sales_record_m11_to_m12
  (
  PRIMARY KEY (id, sales_date),
  CHECK (sales_date &amp;gt;= DATE '2014-11-01'
  AND sales_date &amp;lt; DATE '2015-01-01')
  )
  INHERITS (sales_record);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This child table will contain data of November and December.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can verify that the tables are linked and the partition is successfully created using the following query:&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DB_name=# \d+ sales_record
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the next article, we'll dive into operations we can perform in a partitioned table.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>apacheage</category>
    </item>
    <item>
      <title>Types of Indexes in Postgresql</title>
      <dc:creator>Chiazam Ochiegbu</dc:creator>
      <pubDate>Wed, 13 Sep 2023 22:47:40 +0000</pubDate>
      <link>https://dev.to/tekhunt/types-of-indexes-in-postgresql-44g2</link>
      <guid>https://dev.to/tekhunt/types-of-indexes-in-postgresql-44g2</guid>
      <description>&lt;p&gt;A PostgreSQL database supports the following index types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;single-column index&lt;/li&gt;
&lt;li&gt;multicolumn index&lt;/li&gt;
&lt;li&gt;partial index&lt;/li&gt;
&lt;li&gt;unique index&lt;/li&gt;
&lt;li&gt;expression index&lt;/li&gt;
&lt;li&gt;implicit index and &lt;/li&gt;
&lt;li&gt;concurrent index.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The single-column index
&lt;/h2&gt;

&lt;p&gt;The single-column index is utilized when a table represents mostly a single category of data, or queries span around only a single category in the table. Normally, in a database design, tables represent a single category of data, so generally a single-column (category) index is utilized. &lt;br&gt;
Its syntax is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE INDEX index_name ON table_name (column);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's consider the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;warehouse_db=# SELECT COUNT(*) FROM item WHERE item_id = 100;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the rows are required where item_id is 100. If there is no index defined, then the whole table will be scanned to find the rows where item_id is 100, which is an expensive operation. If you look closely, only a single column is utilized in the WHERE clause, thereby creating an index on a single column, which is item_id in the case of the preceding query. This optimizes that query.&lt;br&gt;
Now, consider the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;warehouse_db=# CREATE INDEX item_index ON item (item_id);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result can be seen using the following statement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;warehouse_db=# \d item;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Column&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Modifiers&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;item_id&lt;/td&gt;
&lt;td&gt;integer&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;item_name&lt;/td&gt;
&lt;td&gt;text&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;item_price&lt;/td&gt;
&lt;td&gt;numeric&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;item_data&lt;/td&gt;
&lt;td&gt;text&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Indexes:
&lt;/h3&gt;

&lt;h3&gt;
  
  
  "item_index" btree (item_id)
&lt;/h3&gt;

&lt;p&gt;Now, we have created a B-tree index, item_index, on a table item’s item_id column, so now we try the same SELECT query again and see how much time it takes after index creation.&lt;br&gt;
Creating an index on a table reduces the SELECT query time drastically, as shown in the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;warehouse_db=# SELECT COUNT(*) FROM item WHERE item_id = 100;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is an obvious timing difference with and without the index. The same query without the index took significantly longer time to execute.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>apacheage</category>
    </item>
    <item>
      <title>Understanding Indexes in Postgresql</title>
      <dc:creator>Chiazam Ochiegbu</dc:creator>
      <pubDate>Fri, 08 Sep 2023 21:22:31 +0000</pubDate>
      <link>https://dev.to/tekhunt/understanding-indexes-in-postgresql-265b</link>
      <guid>https://dev.to/tekhunt/understanding-indexes-in-postgresql-265b</guid>
      <description>&lt;h2&gt;
  
  
  What is an index?
&lt;/h2&gt;

&lt;p&gt;An index is a structure utilized for quick data retrieval operations. In the database world, an index is associated with a table and used to efficiently locate data without having to investigate every row in a database table. If a table does not have an index, then a full table scan is needed to find a record, which is very costly in terms of disk I/O and CPU utilization. &lt;br&gt;
A full table scan is the process of sequentially reading every record from disk, checking against search criteria, and building a result set.&lt;/p&gt;

&lt;p&gt;It is good to note that an index amends the performance of database operations at the cost of extra replicas of data. As an index stores the extra copy of data for more speedy access, an index is the routine way to amend the performance of the database. &lt;br&gt;
In a nutshell, an index is a quick access path to a single row of a table in the database. A database index is similar to a book index where any specific information can be located by looking at the index page to avoid the full search of the book, which is an exhaustive operation. Similarly, a database index is created to minimize table traversal and maximize performance.&lt;br&gt;
An index can be created utilizing a single column or multiple columns of a table. Once the index is created, then there is no further intervention needed; the index will be automatically updated on each DML operation on the table. After creating the index, it is the planner’s decision to utilize the index in lieu of sequential scans based on cost.&lt;/p&gt;
&lt;h3&gt;
  
  
  How to create an index
&lt;/h3&gt;

&lt;p&gt;The CREATE INDEX command is used to create an index the basic syntax of creating an index on a table is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE INDEX index_name ON table_name (column_name);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is an example of creating an index on the item_id column of the item table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;warehouse_db=# CREATE INDEX item_idx ON item (item_id);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result can be seen using the following statement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;warehouse_db=# \di item_idx;
               List of relations
 Schema |   Name   | Type  | Owner    | Table
--------+----------+-------+----------+-------
 public | item_idx | index | postgres | item
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The index name is optional; if the index name is not specified, PostgreSQL generates the index name using the table name and the column name. In the preceding example, we have specified the index name. In the following example, PostgreSQL generates the index name using the table name and column name, which is item_item_id_idx:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;warehouse_db=# CREATE INDEX ON item (item_id);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  CREATE INDEX
&lt;/h3&gt;

&lt;p&gt;The result can be seen using the following statement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;warehouse_db=# \di item_item_id_idx;
                 List of relations
 Schema |       Name       | Type  | Owner    | Table
--------+------------------+-------+----------+-------
 public | item_item_id_idx | index | postgres | item
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Creating an index on a large table can take a long time; for example, in the preceding example, the query has to scan all the records and generate the index data. On a larger table, this process can take time.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>apacheage</category>
    </item>
    <item>
      <title>Privileges in PostgreSQL</title>
      <dc:creator>Chiazam Ochiegbu</dc:creator>
      <pubDate>Thu, 07 Sep 2023 07:43:20 +0000</pubDate>
      <link>https://dev.to/tekhunt/privileges-in-postgresql-1k2k</link>
      <guid>https://dev.to/tekhunt/privileges-in-postgresql-1k2k</guid>
      <description>&lt;h2&gt;
  
  
  What are privileges in Postgresql?
&lt;/h2&gt;

&lt;p&gt;Privileges refer to the permissions and rights granted to database objects, such as tables, views, schemas, and functions, allowing users and roles to perform various actions on these objects&lt;br&gt;
In PostgreSQL, multiple privileges are present for every object that is created. By default, the owner (or a superuser) of an object has all the privileges on it. In PostgreSQL, the following types of privileges are present:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SELECT&lt;/li&gt;
&lt;li&gt;INSERT &lt;/li&gt;
&lt;li&gt;UPDATE &lt;/li&gt;
&lt;li&gt;DELETE &lt;/li&gt;
&lt;li&gt;TRUNCATE &lt;/li&gt;
&lt;li&gt;REFERENCES &lt;/li&gt;
&lt;li&gt;TRIGGER &lt;/li&gt;
&lt;li&gt;CREATE &lt;/li&gt;
&lt;li&gt;CONNECT &lt;/li&gt;
&lt;li&gt;TEMPORARY &lt;/li&gt;
&lt;li&gt;EXECUTE &lt;/li&gt;
&lt;li&gt;USAGE&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are different privileges associated with different objects. For instance, the EXECUTE privilege is associated with procedure. The &lt;code&gt;GRANT&lt;/code&gt; command is used to grant any privilege to any user. It allows you to control what actions users can perform on the object. The syntax for granting privileges is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GRANT privilege_name(s) ON object_name TO user_name_or_role;

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

&lt;/div&gt;



&lt;p&gt;To grant the &lt;code&gt;EXECUTE&lt;/code&gt; privilege on a procedure named "my_function" to a user "my_user," you would use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GRANT EXECUTE ON FUNCTION my_function TO my_user;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly, to take back privileges, the &lt;code&gt;REVOKE&lt;/code&gt; command is used. The REVOKE command is used to revoke previously granted privileges from a user or role. It allows you to take back specific privileges that were previously assigned. The syntax for revoking privileges is shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;REVOKE privilege_name(s) ON object_name FROM user_name_or_role;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To revoke the previously granted EXECUTE privilege on the "my_function" procedure from the "my_user," you would use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;REVOKE EXECUTE ON FUNCTION my_function FROM my_user;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is important to note that managing privileges in PostgreSQL is crucial for access control in your data and ensuring the security and integrity of your database is intact.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>apecheage</category>
    </item>
    <item>
      <title>Exclusion Constraints in Postgresql</title>
      <dc:creator>Chiazam Ochiegbu</dc:creator>
      <pubDate>Mon, 21 Aug 2023 17:59:09 +0000</pubDate>
      <link>https://dev.to/tekhunt/exclusion-constraints-in-postgresql-3pk2</link>
      <guid>https://dev.to/tekhunt/exclusion-constraints-in-postgresql-3pk2</guid>
      <description>&lt;h2&gt;
  
  
  Exclusion constraints
&lt;/h2&gt;

&lt;p&gt;An &lt;code&gt;exclusion constraint&lt;/code&gt; is used when comparing two rows on nominative columns or expressions using the nominative operators. The result of the comparison will be false or null.&lt;/p&gt;

&lt;p&gt;Consider the following example in which the conflicting tuple is given the AND operation together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;warehouse_db=# CREATE TABLE movies
  (
  Title TEXT,
  Copies INTEGER
  );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using the &lt;code&gt;ALTER TABLE&lt;/code&gt; command,we get the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;warehouse_db=# ALTER TABLE movies
  ADD EXCLUDE (title WITH=, copies WITH=);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will create an exclusion constraint above the &lt;code&gt;ALTER TABLE&lt;/code&gt; command. The conditions for a conflicting tuple are &lt;code&gt;AND&lt;/code&gt; together. Now, in order for two records to conflict, we’ll use the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;record1.title = record2.title AND record1.copies = record2.copies.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next article, we'll consider &lt;code&gt;primary and secondary key&lt;/code&gt; constraints.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>apacheage</category>
    </item>
    <item>
      <title>not-null constraint in Postgresql</title>
      <dc:creator>Chiazam Ochiegbu</dc:creator>
      <pubDate>Mon, 21 Aug 2023 17:50:45 +0000</pubDate>
      <link>https://dev.to/tekhunt/not-null-constraint-in-postgresql-46if</link>
      <guid>https://dev.to/tekhunt/not-null-constraint-in-postgresql-46if</guid>
      <description>&lt;p&gt;A &lt;code&gt;not-null constraint&lt;/code&gt; makes sure that a column must have some values and a value is not left as null. Drop the previously created tools table and create the tools table again using this constraint using the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;warehouse_db=# CREATE TABLE tools
  (
  tool_id INTEGER NOT NULL,
  tool_name TEXT,
  tool_class NUMERIC
  );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The preceding query will create a table with a not-null constraint on the tool_id column. We can apply the not-null constraint on as many columns as we can. Consider the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;warehouse_db=# CREATE TABLE tools
  (
  tool_id INTEGER NOT NULL,
  tool_name TEXT NOT NULL,
  tool_class NUMERIC
  );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The preceding query will create the tools table with not-null constraints on tool_id and tool_name.&lt;/p&gt;

&lt;p&gt;In the next article, we'll discuss &lt;code&gt;Exclusion constraints&lt;/code&gt; in postgresql.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>apacheage</category>
    </item>
    <item>
      <title>Constraints in Postgresql</title>
      <dc:creator>Chiazam Ochiegbu</dc:creator>
      <pubDate>Mon, 21 Aug 2023 17:46:42 +0000</pubDate>
      <link>https://dev.to/tekhunt/constraints-in-postgresql-23dm</link>
      <guid>https://dev.to/tekhunt/constraints-in-postgresql-23dm</guid>
      <description>&lt;p&gt;PostgreSQL offers support for constraints and has coverage of multiple-level constraints. Constraints are used to enforce rules on data insertion in tables. Only data that complies with the constraint rules is allowed to be added to the table.&lt;/p&gt;

&lt;p&gt;The constraints present in PostgreSQL are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unique constraints &lt;/li&gt;
&lt;li&gt;Not-null constraints &lt;/li&gt;
&lt;li&gt;Exclusion constrains &lt;/li&gt;
&lt;li&gt;Primary key constraints &lt;/li&gt;
&lt;li&gt;Foreign key constraints &lt;/li&gt;
&lt;li&gt;Check constraints&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We will explain all of these constraints one by one with supportive examples. Let’s start with the unique constraints.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unique constraints
&lt;/h2&gt;

&lt;p&gt;A unique constraint is a constraint that at the time of an insertion operation makes sure that data present in a column (or a group of columns) is unique with regard to all rows already present in the table. Let’s create a few tables using unique constraints in the following manner:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;warehouse_db=# CREATE TABLE tools
  (
  tool_id INTEGER UNIQUE,
  tool_name TEXT,
  tool_class NUMERIC
  );

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

&lt;/div&gt;



&lt;p&gt;Alternatively, the same constraint can be declared at the end of all columns. For instance, this can look like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;warehouse_db=# CREATE TABLE tools
  (
  tool_id INTEGER,
  tool_name TEXT,
  tool_class NUMERIC,
  UNIQUE (tool_id)
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When defining the unique constraints for a group of columns, all columns must be listed separately using commas. Consider the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;warehouse_db=# CREATE TABLE cards
  (
  card_id INTEGER,
  owner_number INTEGER,
  owner_name TEXT,
  UNIQUE (card_id, owner_number)
  );

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

&lt;/div&gt;



&lt;p&gt;The preceding query will create the cards table with a unique constraint implemented on the card_id and owner_number columns. Note that the unique constraint is not applicable on null values. This means that in the cards table, two records can have the same record if they have card_id and owner_number as null.&lt;/p&gt;

&lt;h3&gt;
  
  
  not-null constraint in Postgresql
&lt;/h3&gt;

&lt;p&gt;A &lt;code&gt;not-null constraint&lt;/code&gt; makes sure that a column must have some values and a value is not left as null. Drop the previously created tools table and create the tools table again using this constraint using the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;warehouse_db=# CREATE TABLE tools
  (
  tool_id INTEGER NOT NULL,
  tool_name TEXT,
  tool_class NUMERIC
  );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The preceding query will create a table with a not-null constraint on the tool_id column. We can apply the not-null constraint on as many columns as we can. Consider the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;warehouse_db=# CREATE TABLE tools
  (
  tool_id INTEGER NOT NULL,
  tool_name TEXT NOT NULL,
  tool_class NUMERIC
  );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The preceding query will create the tools table with not-null constraints on tool_id and tool_name.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exclusion Constraints in Postgresql
&lt;/h3&gt;

&lt;p&gt;An &lt;code&gt;exclusion constraint&lt;/code&gt; is used when comparing two rows on nominative columns or expressions using the nominative operators. The result of the comparison will be false or null.&lt;/p&gt;

&lt;p&gt;Consider the following example in which the conflicting tuple is given the AND operation together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;warehouse_db=# CREATE TABLE movies
  (
  Title TEXT,
  Copies INTEGER
  );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using the &lt;code&gt;ALTER TABLE&lt;/code&gt; command,we get the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;warehouse_db=# ALTER TABLE movies
  ADD EXCLUDE (title WITH=, copies WITH=);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will create an exclusion constraint above the &lt;code&gt;ALTER TABLE&lt;/code&gt; command. The conditions for a conflicting tuple are &lt;code&gt;AND&lt;/code&gt; together. Now, in order for two records to conflict, we’ll use the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;record1.title = record2.title AND record1.copies = record2.copies.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next article, we'll consider &lt;code&gt;primary and secondary key&lt;/code&gt; constraints.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>apacheage</category>
    </item>
    <item>
      <title>Short and Long Queries in PQSL</title>
      <dc:creator>Chiazam Ochiegbu</dc:creator>
      <pubDate>Mon, 21 Aug 2023 17:30:47 +0000</pubDate>
      <link>https://dev.to/tekhunt/short-and-long-queries-in-pqsl-3klp</link>
      <guid>https://dev.to/tekhunt/short-and-long-queries-in-pqsl-3klp</guid>
      <description>&lt;p&gt;Let us identify whether a query is a &lt;code&gt;short query&lt;/code&gt; or a &lt;code&gt;long query&lt;/code&gt;. You will learn how to identify short queries.&lt;/p&gt;

&lt;p&gt;What is a short query? First, it has nothing to do with the length of the SQL query.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;code&gt;A query is short when the number of rows needed to compute its output is small, no matter how large the involved tables are. Short queries may read every row from small tables but read only a small percentage of rows from large tables.&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
Let's consider a scenario where you have two tables: a small table named &lt;code&gt;small_table&lt;/code&gt; and a large table named &lt;code&gt;large_table.&lt;/code&gt; The goal is to identify whether a query is a &lt;code&gt;short query&lt;/code&gt; based on the criteria you provided.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE TABLE small_table (
    id SERIAL PRIMARY KEY,
    name VARCHAR(50)
);

CREATE TABLE large_table (
    id SERIAL PRIMARY KEY,
    data VARCHAR(100)
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's an example of a query that reads from both tables and follows the criteria for a &lt;code&gt;short query&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-- Short query example
SELECT *
FROM small_table
UNION ALL
SELECT *
FROM large_table
WHERE id &amp;lt;= 100;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the query is considered "short" because even though it involves both tables, it reads every row from the small_table and only a small percentage of rows (those with id values less than or equal to 100) from the large_table.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT *
FROM large_table
WHERE data LIKE '%something%';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, the query involves only the large_table, but it reads potentially a large number of rows based on the LIKE condition, so it would not meet the criteria for a "short query."&lt;/p&gt;

</description>
      <category>apacheage</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Unique Indexes and Constraints in Postgresql</title>
      <dc:creator>Chiazam Ochiegbu</dc:creator>
      <pubDate>Mon, 21 Aug 2023 17:06:20 +0000</pubDate>
      <link>https://dev.to/tekhunt/unique-indexes-and-constraints-in-postgresql-5f4k</link>
      <guid>https://dev.to/tekhunt/unique-indexes-and-constraints-in-postgresql-5f4k</guid>
      <description>&lt;h1&gt;
  
  
  What is an Index in &lt;code&gt;PSQL&lt;/code&gt;?
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;An index is unique if for each indexed value there is exactly one matching row in the table.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;/blockquote&gt;

&lt;p&gt;There are several different ways to create a unique index. First, PostgreSQL automatically creates a unique index to support any primary key or unique constraint on a table.&lt;/p&gt;

&lt;p&gt;What is the difference between a primary key and a unique constraint? A common misconception among SQL developers is that a primary key has to be an incrementing numeric value and that each table “has” to have a primary key. Although it often helps to have a numeric incremental primary key (called a surrogate key), a primary key does not have to be numeric, and moreover, it does not have to be a &lt;code&gt;single-attribute constraint&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It is possible to define a primary key as a combination of several attributes; it just has to satisfy two conditions: the combination must be &lt;code&gt;UNIQUE&lt;/code&gt; and &lt;code&gt;NOT NULL&lt;/code&gt; for all of the participating attributes. &lt;br&gt;
In contrast, unique constraints in PostgreSQL allow for &lt;code&gt;NULL values&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;table&lt;/code&gt; can have a single primary key (though a primary key is not required) and multiple unique constraints. Any non-null unique constraint can be chosen to be&lt;br&gt;
a primary key for a table; thus, there is no programmatic way to determine the best candidate for a table’s primary key&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>apacheage</category>
    </item>
  </channel>
</rss>
