PostgreSQL ऑटोइन्क्रिमेंट


578

मैं MySQL से PostgreSQL पर स्विच कर रहा हूं और सोच रहा था कि मैं ऑटोइन्क्रिमेंट वैल्यू कैसे कर सकता हूं। मैंने PostgreSQL डॉक्सटाइप "धारावाहिक" में देखा था, लेकिन इसका उपयोग करते समय मुझे वाक्यविन्यास त्रुटियां मिलती हैं (v.0.0 में)।


9
यदि आप वह क्वेरी और त्रुटि प्रदान कर रहे हैं जो आपको मिल रही है - शायद कोई आपको बता सकता है कि क्वेरी में क्या गलत है।

2
मेरा पहला हिट भी 'माइक और जैसा कि यह एक सवाल है कि प्रासंगिक होने के लिए पर्याप्त विचार मिलते हैं, इसे वोट क्यों नहीं देते। PS यह तुच्छ नहीं है यदि आप नहीं जानते कि यह कैसे करना है।
baash05

1
यदि आपका क्लाइंट ड्राइवर Npgsql है तो SERIAL पसंदीदा विकल्प है। प्रदाता आंतरिक रूप से चयन वक्र (pg_get_serial_fterence ('तालिका', 'स्तंभ')) का उपयोग कर INSERT के बाद नए मूल्यों का चयन कर रहा है। यह विफल हो जाएगा यदि अंतर्निहित कॉलम टाइप सीरियल (संख्यात्मक प्रकार + उदाहरण के लिए स्पष्ट अनुक्रम) का नहीं है
ओलिवियर मैट्रो

बस जिज्ञासा के लिए ... क्यों किसी को MySQL से माइग्रेट करना पड़ता है जो बहुत अच्छा है, PostgreSql को?
खलनायकिया 19

17
... जो और भी बेहतर है।
रोहड़ू

जवाबों:


701

हां, SERIAL समतुल्य फ़ंक्शन है।

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 को बदल नहीं सकते।


19
तालिका नाम को उद्धृत करना एक बहुत बुरा अभ्यास है
इवान कैरोल

71
तालिका नामों का उद्धरण देना एक आदत है क्योंकि मुझे एक डीबी विरासत में मिला है जिसमें मिश्रित नाम थे और तालिका नामों को उद्धृत करना उपयोग की आवश्यकता है।
ट्रे

26
@ इवान कैरोल - यह एक बुरी आदत (सिर्फ पूछ) क्यों है?
ईसाई

27
क्योंकि जब तक आपके पास कोई टेबल नहीं है "Table"और "table"तब तक आप उसे बिना किसी सूचना के छोड़ दें और उसे रद्द कर दें table। सम्मेलन बस Pg में उद्धरण का उपयोग करने के लिए कभी नहीं है। यदि आप चाहें, तो उपस्थिति के लिए मिश्रित मामले के नामों का उपयोग कर सकते हैं, बस इसकी आवश्यकता नहीं है: CREATE TABLE fooBar ( .. ); SELECT * FROM fooBar;काम करेगा, जैसा भी होगा SELECT * FROM foobar
इवान कैरोल

26
प्रति पोस्टग्रेज डॉक, या तो लगातार उद्धरण या
अयोग्य

226

आप किसी अन्य पूर्णांक डेटा प्रकार का उपयोग कर सकते हैं , जैसे कि smallint

उदाहरण :

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;

उपयोगकर्ता सीरियल डेटा प्रकार के बजाय अपने स्वयं के डेटा प्रकार का उपयोग करना बेहतर है ।


11
मैं कहूंगा कि यह वास्तव में बेहतर उत्तर है क्योंकि इसने मुझे एक तालिका को संशोधित करने की अनुमति दी थी जो मैंने कॉलम डिफ़ॉल्ट सेट करके ( CREATE SEQUENCE Postgresql.org/docs/8.1/interactive/sql-cadesequence.html पर पढ़ने के बाद ) पोस्टग्रेक्यूक्यू में बनाई थी। । फिर भी, मुझे पूरा यकीन नहीं है कि आपने स्वामी को क्यों बदला है।
JayC

12
@JCC: प्रलेखन से : अंतिम रूप से, अनुक्रम को कॉलम के "स्वामित्व" के रूप में चिह्नित किया गया है, ताकि स्तंभ या तालिका गिराए जाने पर इसे गिरा दिया जाए।
user272735

8
क्यों समुदाय को केवल ऑटिऑनमेंट कीवर्ड को पुन: प्रतिबंधित नहीं करता है?
डॉ। देव

2
@ श्री देव: वे धारावाहिक के बजाय स्वदेशी कीवर्ड का उपयोग करते हैं, मुझे पता नहीं क्यों :)
अहमद

4
यदि आप केवल एक छोटा डेटा प्रकार चाहते हैं तो भी छोटा है।
बेलाडज

110

यदि आप तालिका में आईडी में अनुक्रम जोड़ना चाहते हैं जो पहले से मौजूद है तो आप इसका उपयोग कर सकते हैं:

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

अनुक्रम क्या है? AUTO_INCREMENT कहाँ है?
ग्रीन

23
@Green: AUTO_INCREMENT SQL मानक का हिस्सा नहीं है, यह MySQL के लिए विशिष्ट है। अनुक्रम कुछ ऐसा है जो PostgreSQL में एक समान काम करते हैं।
बेलाडज

5
यदि आप 'id SERIAL' का उपयोग करते हैं, तो यह स्वतः ही PostgreSQL में एक अनुक्रम बना देगा। उस अनुक्रम का नाम <तालिका नाम> _ <कॉलम नाम> _seq
जूड

क्या आपको उपयोग नहीं करना है ALTER COLUMN user_id?
एलेक

मैंने इस विधि की कोशिश की, लेकिन मुझे एक त्रुटि मिली: ERROR: syntax error at or near "DEFAULT"कोई सुझाव?
एली फियाल्कोफ

44

जब भी ऐसा लगता है कि अनुक्रम MySQL auto_increment के बराबर हैं, कुछ सूक्ष्म लेकिन महत्वपूर्ण अंतर हैं:

1. असफल प्रश्न वृद्धि क्रम / सीरियल

सीरियल कॉलम विफल प्रश्नों पर बढ़ जाता है। यह विफल प्रश्नों से विखंडन की ओर जाता है, न कि केवल पंक्ति विलोपन से। उदाहरण के लिए, अपने 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;

आपको निम्न आउटपुट प्राप्त करना चाहिए:

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

ध्यान दें कि 1 से 2 के बजाय uid 1 से 3 तक कैसे जाता है।

यह तब भी होता है जब आप मैन्युअल रूप से अपना स्वयं का अनुक्रम बनाते थे:

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 अलग कैसे है, तो 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);

आपको बिना किसी हिचकिचाहट के साथ निम्नलिखित मिलना चाहिए :

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

2. मैन्युअल रूप से सीरियल कॉलम के मूल्य को निर्धारित करने में विफलता के कारण भविष्य की क्वेरी हो सकती है।

यह पिछले उत्तर में @trev द्वारा इंगित किया गया था।

इसे मैन्युअल रूप से अनुकरण करने के लिए यूआईडी को 4 पर सेट करें जो बाद में "क्लैश" करेगा।

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

तालिका डेटा:

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

एक और प्रविष्टि चलाएँ:

INSERT INTO table1 (col_b) VALUES(6);

तालिका डेटा:

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

अब अगर आप दूसरा इन्सर्ट चलाते हैं:

INSERT INTO table1 (col_b) VALUES(7);

यह निम्न त्रुटि संदेश के साथ विफल हो जाएगा:

त्रुटि: डुप्लिकेट कुंजी मान अद्वितीय बाधा का उल्लंघन करता है "table1_pkey" विवरण: कुंजी (uid) = (5) पहले से मौजूद है।

इसके विपरीत, MySQL नीचे दिखाए गए अनुसार इस इनायत को संभाल लेगा:

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

अब uid सेट किए बिना दूसरी पंक्ति डालें

INSERT INTO table1 (col_b) VALUES(3);

क्वेरी विफल नहीं होती, यूआईडी सिर्फ 5 पर कूदता है:

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

लिनक्स (x86_64) और PostgreSQL 9.4.9 के लिए MySQL 5.6.33 पर परीक्षण किया गया था


10
आप तुलना कर रहे हैं, लेकिन मुझे यहाँ कोई समाधान नहीं दिख रहा है! इसका जवाब है?
अनवर

4
@ अनवर यह बस उन विभिन्न उत्तरों का विस्तार करता है जो बताता है कि उत्तर किसी धारावाहिक / अनुक्रम का उपयोग करना है। यह विचार करने के लिए कुछ महत्वपूर्ण संदर्भ प्रदान करता है।
प्रोग्रामर

38

10 Postgres के साथ शुरू, SQL मानक द्वारा परिभाषित पहचान कॉलम भी समर्थित हैं:

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

एक पहचान स्तंभ बनाता है जिसे ओवरराइड नहीं किया जा सकता है जब तक कि स्पष्ट रूप से नहीं पूछा जाता है। निम्न सम्मिलित रूप से परिभाषित कॉलम के साथ विफल हो जाएगा generated always:

insert into foo (id) 
values (1);

हालाँकि यह ओवरराइड किया जा सकता है:

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

विकल्प का उपयोग करते समय generated by defaultयह अनिवार्य रूप से मौजूदा serialकार्यान्वयन के समान व्यवहार है:

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

जब कोई मान मैन्युअल रूप से प्रदान किया जाता है, तो अंतर्निहित अनुक्रम को मैन्युअल रूप से समायोजित करने की आवश्यकता होती है - एक serialकॉलम के साथ भी ।


एक पहचान स्तंभ डिफ़ॉल्ट रूप से (एक serialस्तंभ की तरह ) प्राथमिक कुंजी नहीं है । यदि यह एक होना चाहिए, तो एक प्राथमिक कुंजी बाधा को मैन्युअल रूप से परिभाषित करने की आवश्यकता है।


26

क्षमा करें, एक पुराने प्रश्न को पुनः प्राप्त करने के लिए, लेकिन यह पहला स्टैक ओवरफ्लो प्रश्न / उत्तर था जो Google पर पॉप अप हुआ था।

यह पोस्ट (जो Google पर पहली बार आई थी) PostgreSQL 10 के लिए अधिक अपडेटेड सिंटैक्स का उपयोग करने की बात करती है: https://blog.2ndquadrant.com/postgresql-10-identity-columns/

जो होता है:

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

उम्मीद है की वो मदद करदे :)


1
यह वास्तव में PostgreSQL 10 में जाने का तरीका है और यह DB2 या Oracle जैसे अन्य डेटाबेस सॉफ़्टवेयर के समान सिंटैक्स है।
adriaan

1
@adriaan वास्तव में GENERATED … AS IDENTITYआदेश मानक SQL हैं। पहले SQL: 2003 में जोड़ा गया , फिर SQL: 2008 में स्पष्ट किया गया । # T174 और F386 और T178 सुविधाएँ देखें।
बेसिल बोर्के

16

आपको सावधान रहना होगा कि आप सीधे अपने SERIAL या अनुक्रम क्षेत्र में सम्मिलित न हों, अन्यथा जब अनुक्रम सम्मिलित मूल्य तक पहुँच जाता है, तो आपका लेखन विफल हो जाएगा:

-- 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; 

15

पूछे गए प्रश्न के संदर्भ में और @ sereja1c द्वारा टिप्पणी के उत्तर में, SERIALअंतर्निहित रूप से दृश्यों का निर्माण होता है, इसलिए उपरोक्त उदाहरण के लिए-

CREATE TABLE foo (id SERIAL,bar varchar);

CREATE TABLEसंक्षेप में foo_id_seqधारावाहिक कॉलम के लिए अनुक्रम बनाएगा foo.id। इसलिए, SERIAL[4 बाइट्स] इसके उपयोग में आसानी के लिए अच्छा है जब तक आपको अपनी आईडी के लिए विशिष्ट डेटाटाइप की आवश्यकता न हो।


3

यह तरीका निश्चित रूप से काम करेगा, मुझे आशा है कि यह मदद करेगा:

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');

आप इस विवरण को अगले लिंक में देख सकते हैं: http://www.postgresqltutorial.com/postgresql-serial/


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.