{{announcement.body}}
{{announcement.title}}

Working With PostgreSQL Data Types in a Distributed SQL Database

DZone 's Guide to

Working With PostgreSQL Data Types in a Distributed SQL Database

Make your Postgres to Yugabyte transition completely seamless.

· Database Zone ·
Free Resource

floating-vr-boxes-with-lights

In the world of databases, data types restrict what can be considered as valid values in a table’s column. For example, if we want a column to store only integer values, we can specify that the column be an int column. Enforcing what type of data can get into a column has the added benefit of helping with storage and in some cases, query performance.

Generically, SQL data types can be broadly divided into the following categories.

  • Numeric data types such as int, tinyint, bigint, float, and real.

  • Date and Time data types such as date, time, and datetime.

  • Character and String data types such as char, varchar, and text.

  • Unicode character string data types such as nchar, nvarchar, and ntext

  • Binary data types such as binary and varbinary.

  • Miscellaneous data types such as clob, blob, xml, cursor, and table

However, not all data types are supported by every relational database vendor, so your mileage may vary depending on the RDBMS you use. In this blog, we’ll be focusing on PostgreSQL datatypes, and test their compatibility against YugabyteDB. You can find a quick list of supported data types on our docs here.

What’s Yugabyte DB? It is an open source, high-performance distributed SQL database built on a scalable and fault-tolerant design inspired by Google Spanner. Yugabyte’s SQL API (YSQL) and drivers are PostgreSQL wire compatible.

You may also like: Spring Boot and PostgreSQL.

Boolean

The boolean data type is what PostgreSQL uses to store true, false, and null values. Here’s the accepted boolean values in PostgreSQL:

  • True: true, ‘t’, ‘true’, ‘y’, ‘yes’, ‘1.’

  • False: false, ‘f’, ‘false’, ‘n’, ‘no’, ‘0.’

Let’s test boolean compatibility in Yugabyte DB by first creating a table with a boolean column.

CREATE TABLE ticket_sales (
 concert_id INT NOT NULL PRIMARY KEY,
 available BOOLEAN NOT NULL
);


Next, let’s insert into the table all the acceptable boolean values.

INSERT INTO ticket_sales (concert_id, available)
VALUES
(100, TRUE),
(101, FALSE),
(102, 't'),
(103, 'f'),
(104, 'true'),
(105, 'false'),
(106, 'y'),
(107, 'n'),
(108, 'yes'),
(109, 'no'),
(110, '1'),
(111, '0');


Finally, let’s select just the values that are TRUE to verify it works as expected.

SELECT
     *
FROM
     ticket_sales
WHERE
     available = 'yes';


Selecting only concerts that are available

CHAR, VARCHAR and TEXT

In PostgreSQL, there are three primary character types (where n is a positive integer).

  • char(n): variable-length with limit.

  • varchar(n): fixed-length, blank padded.

  • text: variable unlimited length.

To test YugabyteDB’s support for character types, let’s create a table that has columns with these types specified:

CREATE TABLE char_types (
     id serial PRIMARY KEY,
     a CHAR (4),
     b VARCHAR (16),
     c TEXT
);


Next, let’s load data into the table:

INSERT INTO char_types (a, b, c)
VALUES
(
     'four',
     'Test varchar',
     'This is a test data for the text column'
);


The insert above should succeed. However, if we run the insert below, it will fail because the first two values are too big for the columns.

INSERT INTO char_types (a, b, c)
VALUES
   (
      'This char test data',
      'This is varchar test data ',
      'This is a test data for the text column'
   );
SQL Error [22001]: ERROR: value too long for type character(4)


and

SQL Error [22001]: ERROR: value too long for type character varying(16)


Integers

There are three kinds of integers in PostgreSQL:

  • SMALLINT: a 2-byte signed integer that has a range from -32,768 to 32,767.

  • INT: a 4-byte integer that has a range from -2,147,483,648 to 2,147,483,647.

  • SERIAL: Same as an integer except that PostgreSQL will automatically generate and populate values similar to AUTO_INCREMENT in MySQL.

In this example, we’ll create a table that makes use of these three integer data types and insert some values to make sure they work as expected.

CREATE TABLE albums (
    album_id SERIAL PRIMARY KEY,
    title VARCHAR (255) NOT NULL,
    play_time SMALLINT NOT NULL,
    library_record INT NOT NULL
);
INSERT INTO albums
values 
     (default,'Funhouse', 3600,2146483645 ),
     (default,'Darkside of the Moon', 4200, 214648348);


When we view the data in the table, we can see that the album_id column has been correctly incremented.

Inserting data into album table

Floating-Point Numbers

In PostgreSQL, there are three main types of floating-point numbers:

  • float(n): is a floating-point number whose precision is at least, n, up to a maximum of 8 bytes.

  • real: is a 4-byte floating-point number.

  • numeric or numeric(p,s): is a real number with p digits with s number after the decimal point. The numeric(p,s) is the exact number.

In this example, we’ll create a table that makes use of these three floating-point data types and insert some values to make sure they work as expected.

CREATE TABLE floating_point_test (
    floatn_test float8 not NULL,
    real_test real NOT NULL,
    numeric_test NUMERIC (3, 2)
);
INSERT INTO floating_point_test (floatn_test, real_test, numeric_test)
VALUES
    (9223372036854775807, 2147483647, 5.36), 
    (9223372036854775800, 2147483640, 9.99);


When we view the data in the table, we can see that the data has been correctly inserted.

Testing adding types of floating-point numbers

Temporal Data Types

Temporal data types allow us to store date and /or time data. There are five main types in PostgreSQL.

  • DATE: stores the dates only.

  • TIME: stores the time of day values.

  • TIMESTAMP: stores both date and time values.

  • TIMESTAMPTZ: is a timezone-aware timestamp data type.

  • INTERVAL: stores intervals of time.

Let’s take a look and see how these data types work in YugabyteDB:

CREATE TABLE temporal_types (
    date_type DATE,
    time_type TIME,
    timestamp_type TIMESTAMP,
    timestampz_type TIMESTAMPTZ,
    interval_type INTERVAL
);
INSERT INTO temporal_types (
    date_type,
    time_type,
    timestamp_type,
    timestampz_type,
    interval_type)
VALUES
    ('2000-06-28', '06:23:00', '2016-06-22 19:10:25-07', '2016-06-22 19:10:25-07', '1 year'),
    ('2010-06-28', '12:32:12','2016-06-22 19:10:25-07', '2016-06-22 19:10:25-07', '10 years 3 months 5 days');


When we view the data in the table, we can see that the data has been correctly inserted.

Testing inserting temporal types

Array

Every data type in PostgreSQL has a companion array type, for example, integer has integer[ ].

Let’s look to see if the examples from the PostgreSQL documentation will work as advertised in Yugabyte DB.

CREATE TABLE sal_emp (
    name            text,
    pay_by_quarter  integer[],
    schedule        text[][]
);
INSERT INTO sal_emp
    VALUES ('Bill',
    '{10000, 10000, 10000, 10000}',
    '{{"meeting", "lunch"}, {"training", "presentation"}}');
INSERT INTO sal_emp
    VALUES ('Carol',
    '{20000, 25000, 25000, 25000}',
    '{{"breakfast", "consulting"}, {"meeting", "lunch"}}');


Now, let’s select the data out from the sal_emp table.

Testing inserting arrays into table

JSON

PostgreSQL provides two JSON data types: JSON and JSONB for storing JSON data. The JSON data type stores plain JSON data that requires reparsing for each processing, while JSONB data type stores JSON data in a binary format which is faster to process but slower to insert.

In addition, JSONB supports indexing. Let’s create a table with JSON types in YugabyteDB and insert some JSON data.

CREATE TABLE json_table (
  json_type JSON,
  jsonb_type JSONB
);
INSERT INTO json_table
VALUES
     ('{"title": "Influence","genres": ["Marketing & Sales","Self-Help","Psychology"],"published": true}', '{"title": "Sleeping Beauties","genres": ["Fiction","Thriller","Horror"],"published": false}');


Now, let’s select the data out.
Testing inserting JSON data

UUID

The UUID (Universally Unique Identifier) data type guarantees better uniqueness than SERIAL and can also be used to hide sensitive data. There are two ways to get started with PostgreSQL UUIDs in YugabyteDB.

Pgcrypto

The pgcrypto module provides cryptographic functions for PostgreSQL, including the ability to create UUIDs. First, we’ll need to create the extension:

SELECT gen_random_uuid();


We are now ready to generate UUIDs using the following command:

SELECT gen_random_uuid();

Generating uuid

UUID-OSSP

The second option is to utilize the uuid-ossp extension. Getting this extension working requires the following steps:

  • Create an alias.
  • Copy the required files from a default PostgreSQL install over to the appropriate Yugabyte DB directory.
  • Issue a CREATE EXTENSION command.
  • Generate the UUIDs.

For detailed instructions on installing extensions check this doc section and for UUID specifically, check out this doc section.

SELECT uuid_generate_v1(), uuid_generate_v4(), uuid_nil();


Generating uuids

Special Data Types

PostgreSQL provides several special data types useful when working with geometric and networking data.

  • Box: a rectangular box.

  • Line: a set of points.

  • Point: a geometric pair of numbers.

  • Lseg: a line segment.

  • Polygon: a closed geometric.

  • Inet: an IP4 address.

  • Macaddr: a MAC address.

You can specify these each data types in YugabyteDB using an example like the one shown below:

CREATE table special_types (
     point_type POINT,
     line_type LINE,
     lseg_type Lseg,
     box_type BOX,
     path_type PATH,
     polygon_type polygon,
     circle CIRCLE,
     inet_type INET,
     macaddr_type MACADDR);


Stay tuned for a detailed blog post that explores these special data types.

User Defined Data Types

PostgreSQL also permits the creation of user defined data types. These data types are created using the CREATE DOMAIN and CREATE TYPE commands. The CREATE DOMAIN statement creates a user-defined data type with constraints such as NOT NULL and CHECK. In the example below we use a CHECK constraint to ensure values are not null and also do not contain a space.

CREATE DOMAIN customer_name AS 
    VARCHAR NOT NULL CHECK (value !~ '\s');
CREATE TABLE customer_list (
    id serial PRIMARY KEY,
    first_name contact_name,
    last_name contact_name,
    email VARCHAR NOT NULL
);


Meanwhile The CREATE TYPE statement allows you to create a composite type, which can be used as the return type of a function. For example:

CREATE TYPE book_summary AS (
    book_id INT,
    title VARCHAR,
    publish_year DATE
);


Next, we create a book table, insert some data, and use the book_summary data type as a return type of a function.

CREATE TABLE book(
     book_id INT,
     title VARCHAR,
     publish_year DATE
);
INSERT into book
values (
     2, 'Infinite Jest', '1998-06-06'
);
CREATE OR REPLACE FUNCTION get_book_summary (f_id INT)
RETURNS book_summary AS
$
SELECT
     book_id,
     title,
     publish_year
FROM
     book
WHERE
     book_id = f_id ;
$
LANGUAGE SQL;

Finally, we call the function:

SELECT * FROM
get_book_summary (2);


Getting book summary with id of 2

What’s Next?

Get started with Yugabyte DB on macOS, Linux, Docker, and Kubernetes.


Further Reading

Topics:
postgres database ,postgresql ,database ,oracle ,tutorial ,data types

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}