Am'm trecerea de la MySQL, PostgreSQL și mă întrebam cum pot face autoincrement valori. Am văzut în PostgreSQL docs un tip de date "seria", dar nu obține erori de sintaxă atunci când se utilizează (în v8.0).
Da, SERIAL este o funcție echivalentă.
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 este doar de a crea masă timp macro jurul secvențe. Nu puteți modifica în SERIE pe o coloană existente.
Puteți folosi orice alt integer tip de date, cum ar fi smallint
.
Exemplu :
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;
Mai bine să-ți folosești propriul tip de date, mai degrabă decât de utilizator serial tip de date.
În timp se pare că secvențele sunt echivalent pentru MySQL auto_increment, există unele subtile, dar importante diferențe:
Serial coloana devine incrementat pe reușit interogări. Acest lucru duce la fragmentarea nu a reușit din interogări, nu doar în rândul eliminări. De exemplu, executați următoarele interogări pe baza de date PostgreSQL:
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;
Ar trebui obține următorul rezultat:
uid | col_b
-----+-------
1 | 1
3 | 2
(2 rows)
Observați cum uid merge de la 1 la 3 în loc de 1 la 2.
Acest lucru încă se întâmplă dacă ați fost de a crea manual propriile secvență cu:
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;
Dacă doriți pentru a testa cât de MySQL este diferit, executați următoarea pe o bază de date MySQL:
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);
Tu ar trebui să ia următoarele cu nu fragementation:
+-----+-------+
| uid | col_b |
+-----+-------+
| 1 | 1 |
| 2 | 2 |
+-----+-------+
2 rows in set (0.00 sec)
Acest lucru a fost subliniat de către @trev în răspunsul anterior.
Pentru a simula acest manual set uid la 4 care va "meciul" mai târziu.
INSERT INTO table1 (uid, col_b) VALUES(5, 5);
Datele din tabel:
uid | col_b
-----+-------
1 | 1
3 | 2
5 | 5
(3 rows)
Rula un alt introduce:
INSERT INTO table1 (col_b) VALUES(6);
Datele din tabel:
uid | col_b
-----+-------
1 | 1
3 | 2
5 | 5
4 | 6
Acum, dacă tu a alerga un alt introduce:
INSERT INTO table1 (col_b) VALUES(7);
Acesta va eșua, cu următorul mesaj de eroare:
EROARE: cheie duplicat valoarea încalcă constrângere unică "table1_pkey" DETALII: - Cheie (uid)=(5) există deja.
În contrast, MySQL va ocupa de acest lucru cu grație, așa cum se arată mai jos:
INSERT INTO table1 (uid, col_b) VALUES(4, 4);
Acum introduce un alt rând fără stabilirea uid
INSERT INTO table1 (col_b) VALUES(3);
Interogarea nu't eșua, uid doar sare la 5:
+-----+-------+
| uid | col_b |
+-----+-------+
| 1 | 1 |
| 2 | 2 |
| 4 | 4 |
| 5 | 3 |
+-----+-------+
Testarea a fost efectuată pe MySQL 5.6.33, pentru Linux (x86_64) și PostgreSQL 9.4.9
Începând cu Postgres 10, coloanele de identitate definită de SQL standard sunt de asemenea suportate:
create table foo
(
id integer generated always as identity
);
creează o coloană de identitate, care poate't fi înlocuite cu excepția cazului în mod explicit cerut. Următoarele insert va eșua, cu o coloană definită ca generat întotdeauna
:
insert into foo (id)
values (1);
Totuși, acest lucru poate fi respinsă:
insert into foo (id) overriding system value
values (1);
Atunci când se utilizează opțiunea generat în mod implicit
aceasta este în esență același comportament ca și cele existente în serie de implementare:
create table foo
(
id integer generated by default as identity
);
Atunci când o valoare este furnizată manual, suport de secvență trebuie să fie ajustate manual, precum și - la fel ca cu un serial
coloana.
O coloană de identitate nu este o cheie primară de default (doar ca un serial
coloana). Dacă ar trebui să fie unul, o restricție de cheie primară trebuie să fie definite manual.
Ne pare rău, ca să-l parafrazez o veche întrebare, dar aceasta a fost prima Stack Overflow întrebare/răspuns care a apărut pe Google.
Acest post (care a venit primul pe Google) vorbește despre utilizarea mai actualizat sintaxa pentru PostgreSQL 10: https://blog.2ndquadrant.com/postgresql-10-identity-columns/
care se întâmplă să fie:
CREATE TABLE test_new (
id int GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
);
Sper că vă ajută :)
Trebuie să fii atent să nu pentru a introduce direct în SERIE sau succesiune domeniu, în caz contrar scrie va eșua atunci când secvența ajunge la valoarea introdusă este:
-- 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;
În contextul întrebare și răspuns la comentariul de @sereja1c, crearea de SERIE
, implicit, creează secvențe, deci pentru exemplul de mai sus-
CREATE TABLE foo (id SERIAL,bar varchar);
Pentru a CREA o MASĂ, implicit, ar crea secvența foo_id_seq pentru serial coloana
foo.id. Prin urmare,
SERIAL` [4 Octeți] este bun pentru ușurința de utilizare, cu excepția cazului ai nevoie de un anumit tip de date de id-ul tau.
În acest fel va lucra pentru sigur, sper să te ajute:
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');
Puteți verifica acest lucru în detalii în link-ul următor: http://www.postgresqltutorial.com/postgresql-serial/