Size of a foreign key in bytes? - postgresql

I have two tables where one references the other using a foreign key. I need to know what the size of that foreign key is, not the primary key itself but the entry in the column. So if we have two tables:
tb1
|id SERIAL PRIMARY KEY| name VARCHAR|
tb2
|id SERIAL PRIMARY KEY| info VARCHAR | tb1_id SERIAL REFERENCES tb1|
How big is tb1_id in bytes? Is it 32 bit like an integer? I could not find the answer in the spec or documentation for PostgreSQL.

A foreign key is not a magic "reference", it's a regular column that stores a value. With a foreign key constraint in place, it is simply enforced that the same value must also exists in a different table.
So it takes as much space as the data type for that column requires which should always be the same data type as the column it references.
As serial is a shortcut for an integer column, so tb1_id should be defined as integer as well. So the answer to "how big is tb_id" would be: 4 bytes (the size of an integer).
Postgres doesn't prevent you from using a different (but "compatible") data type though. In theory, tb1_id could (but shouldn't!) be defined as bigint which would then require 8 bytes of storage. But defining the columns referencing other columns with a different data type is a bad idea to begin with, so don't do that.
The foreign key constraint itself does not require any storage space in the involved tables themselves (They only require some the space in the system tables that is required to store the definition).
Note that a column that references a serial should NOT be defined as serial. If should be defined as integer (which is the real data type behind a serial).
This becomes more evident if you use identity columns (which are essentially the ANSI SQL standard syntax for a "serial").
The DDL for first table when used with an identity column would look like this:
create table tb1
(
id integer primary key generated by default as identity
);
And the second table would look like this:
create table tb2
(
id integer primary key generated by default as identity,
tb1_id integer references tb1
);
Would you use tb1_id integer generated by default as identity in the second table? Probably not, but that would be the same as using tb1_id serial

Related

How can I create a sequence in PostgreSQL to add nextval to an id column where the table already exists? [duplicate]

In a Postgres 9.3 table I have an integer as primary key with automatic sequence to increment, but I have reached the maximum for integer. How to convert it from integer to serial?
I tried:
ALTER TABLE my_table ALTER COLUMN id SET DATA TYPE bigint;
But the same does not work with the data type serial instead of bigint. Seems like I cannot convert to serial?
serial is a pseudo data type, not an actual data type. It's an integer underneath with some additional DDL commands executed automatically:
Create a SEQUENCE (with matching name by default).
Set the column NOT NULL and the default to draw from that sequence.
Make the column "own" the sequence.
Details:
Safely rename tables using serial primary key columns
A bigserial is the same, built around a bigint column. You want bigint, but you already achieved that. To transform an existing serial column into a bigserial (or smallserial), all you need to do is ALTER the data type of the column. Sequences are generally based on bigint, so the same sequence can be used for any integer type.
To "change" a bigint into a bigserial or an integer into a serial, you just have to do the rest by hand:
Creating a PostgreSQL sequence to a field (which is not the ID of the record)
The actual data type is still integer / bigint. Some clients like pgAdmin will display the data type serial in the reverse engineered CREATE TABLE script, if all criteria for a serial are met.

Column Data Type wont change to serial [duplicate]

In a Postgres 9.3 table I have an integer as primary key with automatic sequence to increment, but I have reached the maximum for integer. How to convert it from integer to serial?
I tried:
ALTER TABLE my_table ALTER COLUMN id SET DATA TYPE bigint;
But the same does not work with the data type serial instead of bigint. Seems like I cannot convert to serial?
serial is a pseudo data type, not an actual data type. It's an integer underneath with some additional DDL commands executed automatically:
Create a SEQUENCE (with matching name by default).
Set the column NOT NULL and the default to draw from that sequence.
Make the column "own" the sequence.
Details:
Safely rename tables using serial primary key columns
A bigserial is the same, built around a bigint column. You want bigint, but you already achieved that. To transform an existing serial column into a bigserial (or smallserial), all you need to do is ALTER the data type of the column. Sequences are generally based on bigint, so the same sequence can be used for any integer type.
To "change" a bigint into a bigserial or an integer into a serial, you just have to do the rest by hand:
Creating a PostgreSQL sequence to a field (which is not the ID of the record)
The actual data type is still integer / bigint. Some clients like pgAdmin will display the data type serial in the reverse engineered CREATE TABLE script, if all criteria for a serial are met.

How to convert primary key from integer to serial?

In a Postgres 9.3 table I have an integer as primary key with automatic sequence to increment, but I have reached the maximum for integer. How to convert it from integer to serial?
I tried:
ALTER TABLE my_table ALTER COLUMN id SET DATA TYPE bigint;
But the same does not work with the data type serial instead of bigint. Seems like I cannot convert to serial?
serial is a pseudo data type, not an actual data type. It's an integer underneath with some additional DDL commands executed automatically:
Create a SEQUENCE (with matching name by default).
Set the column NOT NULL and the default to draw from that sequence.
Make the column "own" the sequence.
Details:
Safely rename tables using serial primary key columns
A bigserial is the same, built around a bigint column. You want bigint, but you already achieved that. To transform an existing serial column into a bigserial (or smallserial), all you need to do is ALTER the data type of the column. Sequences are generally based on bigint, so the same sequence can be used for any integer type.
To "change" a bigint into a bigserial or an integer into a serial, you just have to do the rest by hand:
Creating a PostgreSQL sequence to a field (which is not the ID of the record)
The actual data type is still integer / bigint. Some clients like pgAdmin will display the data type serial in the reverse engineered CREATE TABLE script, if all criteria for a serial are met.

what is the right data type for unique key in postgresql DB?

which data type should I choose for a unique key (id of a user for example) in postgresql database's table?
does bigint is the one?
thanks
Use the serial type for automatically incrementing unique ids.
If you plan to have more than two billion entries, use bigserial. serial is the PostgresSQL equivalent of MySQL's AUTO_INCREMENT.
PostgresSQL Documentation: Numeric Types
bigint (or bigserial if you need auto-incrementing keys) is just fine.
If know for certain that you are not going to load too many rows, you might consider integer (or a regular serial) and potentially save some harddisk space.
According to this answer the current recommended approach to doing auto-increment unique IDs is to use the generated as identity syntax instead of serial.
Here's an example:
-- the old way
create table t1 (id serial primary key);
-- the new way
create table t2 (id integer primary key generated always as identity);

How can I add a 2nd serial integer key column to a table? (postgresql)

I have a table with 8440 records with a natural (string) primary key. Now I just discovered that to support a legacy client, I need the records to have integer keys as well. what's the easiest way to add a serial INT column to this table with a unique constraint and populate it with integer values from 1 to 8440?
Alter the table, add a new not null column of type serial, with a unique key on it.
In Postgres, the serial type is a mere alias for the int type with a default value of nextval(some_sequence), the latter of which is created on the fly.