MySQL'den PostgreSQL'e geçiyorum ve nasıl autoincrement değerleri yapabileceğimi merak ediyordum. PostgreSQL dokümanı bir veri türü "seri" gördüm, ancak (v8.0) sözdizimi hataları alıyorum.
MySQL'den PostgreSQL'e geçiyorum ve nasıl autoincrement değerleri yapabileceğimi merak ediyordum. PostgreSQL dokümanı bir veri türü "seri" gördüm, ancak (v8.0) sözdizimi hataları alıyorum.
Yanıtlar:
Evet, SERİAL eşdeğer işlevdir.
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
SERİ, sadece diziler etrafında bir tablo zamanı oluştur makrosu. SERİ'yi mevcut bir sütuna değiştiremezsiniz.
"Table"
ve "table"
daha sonra sadece alıntı yapmadan bırakınız ve standartlaştırınız table
. Konvansiyon asla Pg. İsterseniz, görünüm için karışık vaka adlarını kullanabilirsiniz, sadece gerekli değildir: CREATE TABLE fooBar ( .. ); SELECT * FROM fooBar;
çalışacağı gibi SELECT * FROM foobar
.
Başka kullanabilirsiniz tamsayı veri türü gibi smallint
.
Misal :
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;
Kullanıcı seri veri türünden ziyade kendi veri türünüzü kullanmak daha iyidir .
CREATE SEQUENCE
postgresql.org/docs/8.1/interactive/sql-createsequence.html üzerinde okuduktan sonra ) . ANCAK, sahibini neden değiştirdiğinizden emin değilim.
Halihazırda var olan tabloda kimliğe sıra eklemek isterseniz şunları kullanabilirsiniz:
CREATE SEQUENCE user_id_seq;
ALTER TABLE user ALTER user_id SET DEFAULT NEXTVAL('user_id_seq');
ALTER COLUMN user_id
mu?
ERROR: syntax error at or near "DEFAULT"
Herhangi bir öneriniz var mı?
Diziler MySQL auto_increment'e eşdeğer gibi görünse de, bazı ince ama önemli farklılıklar vardır:
Seri sütun başarısız sorgularda artar. Bu, yalnızca satır silme işlemlerinin değil, başarısız sorguların parçalanmasına yol açar. Örneğin, PostgreSQL veritabanınızda aşağıdaki sorguları çalıştırın:
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;
Aşağıdaki çıktıyı almalısınız:
uid | col_b
-----+-------
1 | 1
3 | 2
(2 rows)
Uid'in 1 ila 2 yerine 1'den 3'e nasıl gittiğine dikkat edin.
Bu, aşağıdakilerle manuel olarak kendi dizinizi oluşturursanız gerçekleşir:
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;
MySQL'in nasıl farklı olduğunu test etmek isterseniz, MySQL veritabanında aşağıdakileri çalıştırın:
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);
Parçalanma olmadan aşağıdakileri almalısınız :
+-----+-------+
| uid | col_b |
+-----+-------+
| 1 | 1 |
| 2 | 2 |
+-----+-------+
2 rows in set (0.00 sec)
Bu önceki cevapta @trev tarafından belirtilmişti.
Bunu simüle etmek için uid değerini daha sonra "çakışma" yapacak olan 4'e ayarlayın.
INSERT INTO table1 (uid, col_b) VALUES(5, 5);
Tablo verileri:
uid | col_b
-----+-------
1 | 1
3 | 2
5 | 5
(3 rows)
Başka bir kesici uç çalıştırın:
INSERT INTO table1 (col_b) VALUES(6);
Tablo verileri:
uid | col_b
-----+-------
1 | 1
3 | 2
5 | 5
4 | 6
Şimdi başka bir kesici uç çalıştırırsanız:
INSERT INTO table1 (col_b) VALUES(7);
Aşağıdaki hata iletisiyle başarısız olur:
HATA: yinelenen anahtar değeri benzersiz kısıtlamayı ihlal ediyor "table1_pkey" DETAY: Anahtar (uid) = (5) zaten var.
Bunun aksine, MySQL bunu aşağıda gösterildiği gibi incelikle işleyecektir:
INSERT INTO table1 (uid, col_b) VALUES(4, 4);
Şimdi uid ayarlamadan başka bir satır ekleyin
INSERT INTO table1 (col_b) VALUES(3);
Sorgu başarısız olmaz, uid sadece 5'e atlar:
+-----+-------+
| uid | col_b |
+-----+-------+
| 1 | 1 |
| 2 | 2 |
| 4 | 4 |
| 5 | 3 |
+-----+-------+
Test, Linux (x86_64) ve PostgreSQL 9.4.9 için MySQL 5.6.33 üzerinde gerçekleştirildi
Postgres 10'dan başlayarak, SQL standardı tarafından tanımlanan kimlik sütunları da desteklenir:
create table foo
(
id integer generated always as identity
);
açıkça istenmedikçe geçersiz kılınamayan bir kimlik sütunu oluşturur. Aşağıdaki ekleme, şu şekilde tanımlanan bir sütunla başarısız olacaktır generated always
:
insert into foo (id)
values (1);
Ancak bu geçersiz kılınabilir:
insert into foo (id) overriding system value
values (1);
Seçeneği kullanırken, generated by default
bu aslında mevcut serial
uygulama ile aynı davranıştır :
create table foo
(
id integer generated by default as identity
);
Bir değer manuel olarak sağlandığında, temel sıralamanın serial
sütunla olduğu gibi manuel olarak da ayarlanması gerekir .
Kimlik sütunu varsayılan olarak birincil bir anahtar değildir (tıpkı bir serial
sütun gibi ). Bir tane olması gerekiyorsa, birincil anahtar kısıtlamasının manuel olarak tanımlanması gerekir.
Maalesef eski bir soruyu yeniden düzenlemek için, ancak bu Google'da açılan ilk Yığın Taşması sorusu / cevabı idi.
Bu yazı (Google'da ilk kez geldi) PostgreSQL 10 için daha güncel sözdizimini kullanma hakkında konuşuyor: https://blog.2ndquadrant.com/postgresql-10-identity-columns/
hangi olur:
CREATE TABLE test_new (
id int GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
);
Umarım yardımcı olur :)
GENERATED … AS IDENTITY
komutlar standart SQL'dir . İlk önce SQL: 2003'te eklendi , sonra SQL: 2008'de netleştirildi . Bkz. # T174 ve F386 ve T178 özellikleri.
Doğrudan SERİ veya dizi alanınıza eklememeye dikkat etmelisiniz, aksi takdirde dizi girilen değere ulaştığında yazma işleminiz başarısız olur:
-- 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;
Sorulan soru bağlamında ve @ sereja1c tarafından yapılan yoruma yanıt olarak, SERIAL
örtük olarak diziler oluşturur, bu nedenle yukarıdaki örnek için-
CREATE TABLE foo (id SERIAL,bar varchar);
CREATE TABLE
dolaylı foo_id_seq
olarak seri sütun için sıra oluşturur foo.id
. Bu nedenle, SERIAL
[4 Bayt] kimliğiniz için belirli bir veri tipine ihtiyacınız olmadığı sürece kullanım kolaylığı açısından iyidir.
Bu şekilde çalışacak, umarım yardımcı olur:
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');
Ayrıntıları bir sonraki bağlantıda kontrol edebilirsiniz: http://www.postgresqltutorial.com/postgresql-serial/
PostgreSQL 10'dan beri
CREATE TABLE test_new (
id int GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
payload text
);