Data Types
This section covers the data types supported in YSQL, from the basic data types to the SERIAL
pseudo-type (for implementing an auto-incrementing primary key column in a table), arrays and composite types. The JSONB document data type is covered in a separate section.
Strings
The following character types are supported.
varchar(n)
: variable-length stringchar(n)
: fixed-length, blank paddedtext
,varchar
: 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
);
Insert some rows:
INSERT INTO char_types (a, b, c) VALUES (
'foo', 'bar', 'Data for the text column'
);
Numeric Types
The following numeric types are supported
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.float(n)
: is a floating-point number whose precision is at least, n, up to a maximum of 8 bytesreal
: is a 4-byte floating-point numbernumeric
ornumeric(p,s)
: is a real number with p digits with s number after the decimal point. The numeric(p,s) is the exact number
Below is an example of creating a table with integer type columns and inserting rows into it:
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);
Similarly, the example below shows how to create a table with floating-point typed columns and how to insert a row into that table.
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);
SERIAL
pseudo-type
In YugabyteDB, just as with PostgreSQL, a sequence is a special kind of database object that generates a sequence of integers. A sequence is often used as the primary key column in a table.
By assigning the SERIAL pseudo-type to a column, the following occurs behind the scenes:
- The database creates a sequence object and sets the next value generated by the sequence as the default value for the column.
- The database adds a NOT NULL constraint to that column because a sequence always generates an integer, which is a non-null value.
- The
SERIAL
column is assigned as the owner of the sequence. This results in the sequence object being deleted when theSERIAL
column or table is dropped.
YSQL supports the following pseudo-types:
SMALLSERIAL
: 2 bytes (1 to 32,767)SERIAL
: 4 bytes (1 to 2,147,483,647)BIGSERIAL
: 8 bytes (1 to 9,223,372,036,854,775,807)
Date and time
Temporal data types allow us to store date and/or time data. There are five main types in PostgreSQL, all of which are supported in YugabyteDB.
DATE
: stores the dates onlyTIME
: stores the time of day valuesTIMESTAMP
: stores both date and time valuesTIMESTAMPTZ
: is a timezone-aware timestamp data typeINTERVAL
: stores intervals of time
Let's create a table with these temporal types as shown below.
CREATE TABLE temporal_types (
date_type DATE,
time_type TIME,
timestamp_type TIMESTAMP,
timestampz_type TIMESTAMPTZ,
interval_type INTERVAL
);
Next, let's insert a row into this table.
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');
You can check the data inserted as shown below.
yugabyte=# select * from temporal_types;
date_type | time_type | timestamp_type | timestampz_type | interval_type
------------+-----------+---------------------+------------------------+------------------------
2010-06-28 | 12:32:12 | 2016-06-22 19:10:25 | 2016-06-22 19:10:25-07 | 10 years 3 mons 5 days
2000-06-28 | 06:23:00 | 2016-06-22 19:10:25 | 2016-06-22 19:10:25-07 | 1 year
(2 rows)
Arrays
YSQL supports arrays to hold data of variable length. The type of the data stored in an array can be an inbuilt type, a user-defined type or an enumerated type. The examples below are adapted from here.
1. Create a table with an array type
CREATE TABLE rock_band (
name text,
members text[]
);
2. Insert rows
You can insert a row into this table as shown below. Note that the array literals must be double-quoted.
INSERT INTO rock_band VALUES (
'Led Zeppelin', '{"Page", "Plant", "Jones", "Bonham"}'
);
An alternate syntax using the array constructor is shown below. When using the ARRAY
constructor, the values must be single-quoted.
INSERT INTO rock_band VALUES (
'Pink Floyd', ARRAY['Barrett', 'Gilmour']
);
3. Accessing arrays
You can query the table as shown below.
select * from rock_band;
Output:
name | members
--------------+---------------------------
Pink Floyd | {Barrett,Gilmour}
Led Zeppelin | {Page,Plant,Jones,Bonham}
(2 rows)
Array values can be accessed using subscripts.
select name from rock_band where members[2] = 'Plant';
Output:
name
--------------
Led Zeppelin
(1 row)
They can also be accessed using slices as shown below.
select members[1:2] from rock_band;
Output:
members
-------------------
{Barrett,Gilmour}
{Page,Plant}
(2 rows)
4. Updating a single element
UPDATE rock_band set members[2] = 'Waters' where name = 'Pink Floyd';
Output:
yugabyte=# select * from rock_band where name = 'Pink Floyd';
name | members
------------+------------------
Pink Floyd | {Barrett,Waters}
(1 row)
5. Updating entire array
UPDATE rock_band set members = '{"Mason", "Wright", "Gilmour"}' where name = 'Pink Floyd';
Output:
yugabyte=# select * from rock_band where name = 'Pink Floyd';
name | members
------------+------------------------
Pink Floyd | {Mason,Wright,Gilmour}
(1 row)
6. Searching in arrays
Use the ANY
keyword to search for a particular value in an array as shown below.
select name from rock_band where 'Mason' = ANY(members);
Output:
name
------------
Pink Floyd
(1 row)
Enumerations - ENUM
type
YugabyteDB supports the ENUM
type in PostgreSQL. Below is an example (adapted from here).
1. Create ENUM
CREATE TYPE e_contact_method AS ENUM (
'Email',
'Sms',
'Phone');
2. Viewing the ENUM
To view the list of values across all ENUM
types, run:
select t.typname, e.enumlabel
from pg_type t, pg_enum e
where t.oid = e.enumtypid;
The output should be as follows:
typname | enumlabel
------------------+-----------
e_contact_method | Email
e_contact_method | Sms
e_contact_method | Phone
2. Create table with ENUM
column
CREATE TABLE contact_method_info (
contact_name text,
contact_method e_contact_method,
value text
);
3. Insert row with ENUM
Inserting a row with a valid value for the ENUM
should succeed.
INSERT INTO contact_method_info VALUES ('Jeff', 'Email', '[email protected]')
You can verify as shown below:
yugabyte=# select * from contact_method_info;
contact_name | contact_method | value
--------------+----------------+---------------
Jeff | Email | [email protected]
(1 row)
Inserting an invalid ENUM
value would fail.
yugabyte=# INSERT INTO contact_method_info VALUES ('Jeff', 'Fax', '4563456');
You should see the following error (note error message is compatible with that of PostgreSQL).
ERROR: 22P02: invalid input value for enum e_contact_method: "Fax"
LINE 1: INSERT INTO contact_method_info VALUES ('Jeff', 'Fax', '4563...
Composite types
A composite type (also known as a user defined type) is a collection of data types similar to a struct
in a programming language. The examples in this section are adapted from here.
1. Create a composite type
CREATE TYPE inventory_item AS (
name text,
supplier_id integer,
price numeric
);
2. Create table with composite type
This can be done as shown below.
CREATE TABLE on_hand (
item inventory_item,
count integer
);
3. Insert a row
To insert a row, use the RUN
keyword, as shown below.
INSERT INTO on_hand VALUES (ROW('fuzzy dice', 42, 1.99), 1000);
4. Selecting data
To select some subfields from our on_hand
example table, run the query shown below.
SELECT (item).name FROM on_hand WHERE (item).price > 0.99;
You can also use the table names as shown below.
SELECT (on_hand.item).name FROM on_hand WHERE (on_hand.item).price > 0.99;
Output:
yugabyte=# SELECT (item).name FROM on_hand WHERE (item).price > 0.99;
name
------------
fuzzy dice
(1 row)