PostgreSQL Autoincrement




auto-increment (6)

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


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

उदाहरण :

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;

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


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

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

जबकि ऐसा लगता है कि अनुक्रम 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 के बजाय यूआईडी 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);

अब यूआईडी सेट किए बिना एक और पंक्ति डालें

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 पर किया गया था


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

CREATE TABLE foo (id SERIAL,bar varchar);

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


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

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

हां, सीरियल समकक्ष कार्य है।

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







auto-increment