Postgres unsigned integer primary key maximum - postgresql

Postgres integer range is from -2147483648 to +2147483647. In mysql as i know you can use unsigned integer as primary key and get twice values for pk when it starts from 1 (2147483647*2).
I'm not sure is there a way to increase postgres integer range pk sequence from 2147483647 to 2147483647*2 if i don't need negative values? Can i just change maximum to 2147483647*2?

Postgres doesn't have unsinged int. For a primary key with more than 2147483647, consider using bigserial.

You can simply set a large number for MAXIMUM and Postgresql will use the relevant numeric type for the counter. Here is an example:
CREATE SEQUENCE the_long_road
MINVALUE 1
MAXVALUE 123456789012345
START WITH 123456789000000;
-- try it several times
SELECT nextval('the_long_road');

Well if you really want an integer you can get the range of values you want. You just have the keep in mind that the only purpose of a generated key is making the row unique in the table - nothing else. In that view negative values work perfectly well. So
create sequence long_wrap_seq as integer
minvalue -2147483648
maxvalue +2147483647
start with 1
cycle;
create table long_wrap_seq(id integer default nextval('long_wrap_seq')
, ...
);
You now have a the sequence range 2147483647*2 (actually +1).

Related

How do i pass a big int while creating the sequence in postgresql?

I am trying to create a sequence
CREATE SEQUENCE seq_id MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NO CYCLE
It throws an ERROR: value "9999999999999999999999999999" is out of range for type bigint. I am trying to convert oracle queries to postgreSQL.
An eight-byte integer cannot contain this number, but then you don't need such a big number anyway.
Use
CREATE SEQUENCE seq_id CACHE 20;
I usually just use bigserial when creating a table.
CREATE TABLE table_name (
seq_column bigserial,
some_column text,
)
This creates a sequence automatically for you.
See https://www.postgresql.org/docs/current/datatype-numeric.html#DATATYPE-SERIAL
Also possible:
CREATE SEQUENCE tablename_colname_seq AS bigint;

setting the length of an integer column in Postgres

I have a table called "User_details" in my Postgres database with a column as "Mobile_no" with data type as Integer.
Now when I try inserting an integer value of length 10, I get the following error
ERROR: integer out of range
I know this can be resolved if i set the data type to bigint or may be even numeric(10,0) but i want to use Int as the data type.
Any possible solution to set the length of an Integer column in Postgres?
On PostgreSQL an integer type can hold values between -2147483648 and +2147483647 so if the value to insert is "greater than" there is no way to store it on database, only by modifying the data type for example to bigint you will be able to store greater values (bigint can hold values between -9223372036854775808 to +9223372036854775807).
Please check https://www.postgresql.org/docs/current/static/datatype-numeric.html

Which data type to use to reference SERIAL data type in PostgreSQL?

I have two tables in PostgreSQL. The first one should have an auto-incrementing ID field that the second one references:
CREATE TABLE tableA (id SERIAL NOT NULL PRIMARY KEY, ...)
CREATE TABLE tableB (parent INTEGER NOT NULL REFERENCES tableA(id), ...)
According to documentation, SERIAL acts as unsigned 4-byte integer while INTEGER is signed:
serial 4 bytes autoincrementing integer 1 to 2147483647
integer 4 bytes typical choice for integer -2147483648 to +2147483647
If I understand correctly, the data types that I have used are not compatible, but PostgreSQL apparently lacks unsigned integers. I know I probably won't use more than 2*10^9 IDs (and if I did, I could always use BIGSERIAL), and it's not all that important, but it seems a bit unclean to me to have signed integer reference an unsigned one. I am sure there must be a better way - am I missing something?
A serial is an integer and it's not "unsigned". The sequence that is created automatically just happens to start at 1 - that's all. The column's data type is still an integer (you could make the sequence start at -2147483648 if you wanted to).
Quote from the manual
CREATE TABLE tablename (
colname SERIAL
);
is equivalent to
CREATE SEQUENCE tablename_colname_seq;
CREATE TABLE tablename (
colname integer NOT NULL DEFAULT nextval('tablename_colname_seq')
);
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;
(emphasis mine)

Why does creating a table with a serial column create a sequence with a max val of a bigint?

I am a little confused and new to PostgreSql , I thought that serial = integer and bigserial = bigint, so I am confused why I see a sequence with a max val of 9223372036854775807 instead of 2147483647, when I create a table with a PK that is serial.
As stated in the PostgreSQL 9.4 docs for Data Type SERIAL a sequence is implicitly created using CREATE SEQUENCE tablename_colname_seq without any additional parameters.
The documentation for CREATE SEQUENCE says:
The optional clause MAXVALUE maxvalue determines the maximum value for the sequence. If this clause is not supplied or NO MAXVALUE is specified, then default values will be used. The defaults are 2^63-1 and -1 for ascending and descending sequences, respectively.
So it is documented behaviour that the sequence is created with the max value you are seing.
The sequence and the column are two separate things. A sequence could return an integer larger than an int4 column could store. When you specify SERIAL or BIGSERIAL, PostgreSQL roughly translates that into:
create an int4 or int8 column
create a sequence
make the sequence owned by the column
make the column default value the next value from the sequence
SERIAL is a convenience, but there is not an actual column type SERIAL.

serial type produce only even or odd numbers in postgresql

I want set some constraint to the serial type,it only produce even or odd numbers.
SERIAL is a syntax sugar around creating and using sequences.
So you could do it all manually and create a special type of sequence that suits your needs:
CREATE SEQUENCE tablename_colname_seq INCREMENT BY 2 START WITH 2;
CREATE TABLE tablename (
colname integer NOT NULL DEFAULT nextval('tablename_colname_seq');
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;
Or if you already have a table and a SERIAL column you could change the underlying sequence:
ALTER SEQUENCE tablename_colname_seq INCREMENT BY 2;
The name of the underlying sequence could be retrieved by "describing" the table using psql:
\d tablename
Simply, set your serial to increment by 2, and to start on either 1 or 2 for producing either odd or even number:
Odd
CREATE SEQUENCE odd_seq INCREMENT BY 2 START WITH 1;
Even
CREATE SEQUENCE even_seq INCREMENT BY 2 START WITH 2;