PostgreSQL automatically increment

I'm switching from MySQL to PostgreSQL , and want to know how to do automatic incremental value. I saw a data type "serial" in the PostgreSQL document, but when you use it a syntax error (in v8.0,) appears.


#1st Floor

In the context of the question and reply to comments @ sereja1c, create SERIALimplicit sequence created, so for the above example -

CREATE TABLE foo (id SERIAL,bar varchar);

CREATE TABLEThe implicit sequence created foo_id_seqserial column foo.id. Therefore, unless you need a specific data type id, or SERIAL[4 Bytes] ease of use is very good.


#2nd Floor

If you want to add to the sequence id in the table already exists, you can use:

CREATE SEQUENCE user_id_seq;
ALTER TABLE user ALTER user_id SET DEFAULT NEXTVAL('user_id_seq');

#3rd floor

You must be careful not to directly insert SERIAL or sequence field, or when the sequence reaches insert values, write will fail:

-- Table: "test"

-- DROP TABLE test;

CREATE TABLE test
(
  "ID" SERIAL,
  "Rank" integer NOT NULL,
  "GermanHeadword" "text" [] NOT NULL,
  "PartOfSpeech" "text" NOT NULL,
  "ExampleSentence" "text" NOT NULL,
  "EnglishGloss" "text"[] NOT NULL,
  CONSTRAINT "PKey" PRIMARY KEY ("ID", "Rank")
)
WITH (
  OIDS=FALSE
);
-- ALTER TABLE test OWNER TO postgres;
 INSERT INTO test("Rank", "GermanHeadword", "PartOfSpeech", "ExampleSentence", "EnglishGloss")
           VALUES (1, '{"der", "die", "das", "den", "dem", "des"}', 'art', 'Der Mann küsst die Frau und das Kind schaut zu', '{"the", "of the" }');


 INSERT INTO test("ID", "Rank", "GermanHeadword", "PartOfSpeech", "ExampleSentence", "EnglishGloss")
           VALUES (2, 1, '{"der", "die", "das"}', 'pron', 'Das ist mein Fahrrad', '{"that", "those"}');

 INSERT INTO test("Rank", "GermanHeadword", "PartOfSpeech", "ExampleSentence", "EnglishGloss")
           VALUES (1, '{"der", "die", "das"}', 'pron', 'Die Frau, die nebenen wohnt, heißt Renate', '{"that", "who"}');

SELECT * from test; 

#4th floor

Although it looks a sequence identical to MySQL auto_increment, but there are some subtle but important differences:

1. The failure of the query increasing sequence / sequence

Serial column increment in the failure of the query. This causes the query to fail, not just delete the line. For example, the PostgreSQL database, run the following query:

CREATE TABLE table1 (
  uid serial NOT NULL PRIMARY KEY,
  col_b integer NOT NULL,
  CHECK (col_b>=0)
);

INSERT INTO table1 (col_b) VALUES(1);
INSERT INTO table1 (col_b) VALUES(-1);
INSERT INTO table1 (col_b) VALUES(2);

SELECT * FROM table1;

You should get the following output:

 uid | col_b 
-----+-------
   1 |     1
   3 |     2
(2 rows)

Note how the change from 1 to 3 uid instead of 1-2.

If you create your own sequence manually using the following method, it will still happen

CREATE SEQUENCE table1_seq;
CREATE TABLE table1 (
    col_a smallint NOT NULL DEFAULT nextval('table1_seq'),
    col_b integer NOT NULL,
    CHECK (col_b>=0)
);
ALTER SEQUENCE table1_seq OWNED BY table1.col_a;

If you want to test differences between MySQL, run the following command on the MySQL database:

CREATE TABLE table1 (
  uid int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
  col_b int unsigned NOT NULL
);

INSERT INTO table1 (col_b) VALUES(1);
INSERT INTO table1 (col_b) VALUES(-1);
INSERT INTO table1 (col_b) VALUES(2);

You should get the following no fragementation :

+-----+-------+
| uid | col_b |
+-----+-------+
|   1 |     1 |
|   2 |     2 |
+-----+-------+
2 rows in set (0.00 sec)

2. manually set the serial column values ​​may lead to future queries fail.

@trev pointed this out in the previous answer.

To simulate this, manually set uid to 4, in order to later "conflict."

INSERT INTO table1 (uid, col_b) VALUES(5, 5);

Table data:

 uid | col_b 
-----+-------
   1 |     1
   3 |     2
   5 |     5
(3 rows)

Run another insert:

INSERT INTO table1 (col_b) VALUES(6);

Table data:

 uid | col_b 
-----+-------
   1 |     1
   3 |     2
   5 |     5
   4 |     6

Now, if you run another insert:

INSERT INTO table1 (col_b) VALUES(7);

It fails with the following error message:

Error: duplicate key violation "table1_pkey" DETAIL unique constraint: key (uid) = (5) already exists.

In contrast, MySQL will gracefully deal with this, as follows:

INSERT INTO table1 (uid, col_b) VALUES(4, 4);

Now insert another row without providing uid

INSERT INTO table1 (col_b) VALUES(3);

Query did not fail, uid just jump 5:

+-----+-------+
| uid | col_b |
+-----+-------+
|   1 |     1 |
|   2 |     2 |
|   4 |     4 |
|   5 |     3 |
+-----+-------+

Testing is performed on MySQL 5.6.33, applies to Linux (x86_64) and PostgreSQL 9.4.9


#5th Floor

From the beginning of Postgres 10, also supports identity columns SQL standard defines:

create table foo 
(
  id integer generated always as identity
);

Unless explicitly requested, otherwise it will create a identity column can not be covered. The insertion fails, and a column is defined as generated always:

insert into foo (id) 
values (1);

However, this can be overridden:

insert into foo (id) overriding system value 
values (1);

Use generated by defaultwhen options generated by defaultwhich existing serialbasically the same realization:

create table foo 
(
  id integer generated by default as identity
);

Providing values manually, need to manually adjust the base sequence - the serialcolumn same.


By default, the identity column is not the primary key (like the serialcolumns, like). If it should be 1, it is necessary to manually define the primary key constraint.


#6th floor

Sorry, we reintroduced an old question, but this is the first issue appearing on Stack Overflow Google / answer.

This article (first published on Google) discussed how to use the update syntax PostgreSQL 10: HTTPS : //blog.2ndquadrant.com/postgresql-10-identity-columns/

happens to be:

CREATE TABLE test_new (
    id int GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
);

Hope that helps :)


#7th floor

This way will certainly play a role, and I hope it helps:

CREATE TABLE fruits(
   id SERIAL PRIMARY KEY,
   name VARCHAR NOT NULL
);

INSERT INTO fruits(id,name) VALUES(DEFAULT,'apple');

or

INSERT INTO fruits VALUES(DEFAULT,'apple');

You can view details of a link to the next: HTTP : //www.postgresqltutorial.com/postgresql-serial/


Building # 8

Since PostgreSQL 10

CREATE TABLE test_new (
    id int GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    payload text
);

House # 9

You can use any other integer data types , for example smallint.

Example:

CREATE SEQUENCE user_id_seq;
CREATE TABLE user (
    user_id smallint NOT NULL DEFAULT nextval('user_id_seq')
);
ALTER SEQUENCE user_id_seq OWNED BY user.user_id;

Best to use your own data types, rather than the user serial data type .


#10th floor

Yes, SERIAL is equivalent function.

CREATE TABLE foo (
id SERIAL,
bar varchar);

INSERT INTO foo (bar) values ('blah');
INSERT INTO foo (bar) values ('blah');

SELECT * FROM foo;

1,blah
2,blah

SERIAL just create a table around the time sequence macros. You can not change the existing SERIAL column.

Original articles published 0 · won praise 0 · Views 2205

Guess you like

Origin blog.csdn.net/p15097962069/article/details/103934310