PostgreSQL অটোয়েনক্রিমেন্ট


578

আমি মাইএসকিউএল থেকে পোস্টগ্রেএসকিউএল এ স্যুইচ করছি এবং ভাবছিলাম যে কীভাবে আমি স্বতঃআগ্রহ মান করতে পারি। আমি পোস্টগ্রাইএসকিউএল ডক্সে একটি ডেটাটাইপ "সিরিয়াল" দেখেছি, তবে এটি ব্যবহার করার সময় আমি সিনট্যাক্স ত্রুটি পেয়েছি (v8.0 এ)।


9
যদি আপনি কোয়েরিটি সরবরাহ করেন এবং আপনি যে ত্রুটিটি পেয়ে যাচ্ছেন - সম্ভবত কেউ আপনাকে জিজ্ঞাসাটির মধ্যে কী ভুল তা বলতে পারে।

2
আমার প্রথম আঘাত হ'ল মিচ 'এবং এটি একটি প্রশ্ন যা প্রাসঙ্গিক হওয়ার পক্ষে যথেষ্ট মতামত পেয়েছে কেন এটি কেন ভোট দেবেন না। PS এটি তুচ্ছ নয় যদি আপনি এটি কীভাবে করতে জানেন না।
baash05

1
সিরিয়ালটি পছন্দসই পছন্দ যদি আপনার ক্লায়েন্ট ড্রাইভার Npgsql হয়। সরবরাহকারী অভ্যন্তরীণভাবে একটি নির্বাচনী কার্ভাল (pg_get_serial_sequence ('টেবিল', 'কলাম')) ব্যবহার করে INSERT এর পরে নতুন মানগুলি নির্বাচন করছেন। অন্তর্নিহিত কলামটি সিরিয়াল প্রকারের না হলে এটি ব্যর্থ হবে (উদাহরণস্বরূপ সংখ্যার টাইপ + স্পষ্টত ক্রম)
অলিভিয়ার ম্যাট্রোট

কেবল কৌতূহলের জন্য ... কেন কাউকে মাইএসকিউএল থেকে খুব ভাল পোস্টগ্রেএসকিউএল এ স্থানান্তর করতে হবে?
ভিলমেজিয়া

17
... যা আরও ভাল।
রোহমার

উত্তর:


701

হ্যাঁ, সিরিয়াল সমতুল্য ফাংশন।

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

সিরিয়ালটি সিকোয়েন্সগুলির চারপাশে কেবল তৈরি টেবিল টাইম ম্যাক্রো। আপনি বিদ্যমান কলামে সিরিয়াল পরিবর্তন করতে পারবেন না।


19
টেবিলের নামটি উদ্ধৃত করা সত্যিই খারাপ অভ্যাস
ইভান ক্যারল

71
টেবিলের নামগুলি উদ্ধৃত করা একটি অভ্যাস, যেহেতু আমি এমন একটি ডিবি উত্তরাধিকার সূত্রে পেয়েছি যার মিশ্র মামলার নাম ছিল এবং টেবিলের নাম উদ্ধৃত করা প্রয়োজন।
ট্রে

26
@ ইভান ক্যারল - এটি কেন খারাপ অভ্যাস (কেবল জিজ্ঞাসা করা)?
খ্রিস্টান

27
কারণ আপনার যদি কোনও টেবিল না থাকে "Table"এবং "table"তারপরে এটিকে কেবল অকেজো রেখে দিন এবং এটিতে ক্যানোনিকালাইজ করা যায় না table। সম্মেলনে পিজিতে কখনই উদ্ধৃতি ব্যবহার করা যায় না। আপনি, যদি আপনি চান তবে উপস্থিতির জন্য মিশ্র মামলার নামগুলি ব্যবহার করতে পারেন, কেবল এটির দরকার নেই: CREATE TABLE fooBar ( .. ); SELECT * FROM fooBar;কাজ করবে, ইচ্ছামতো করবে SELECT * FROM foobar
ইভান ক্যারল

26
: প্রতি postgres ডক, হয় ধারাবাহিকভাবে উদ্ধৃত করুন অথবা উদ্ধতি postgresql.org/docs/current/interactive/...
Καrτhικ

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-createsequence.html পড়ার পরে ) । তবুও, কেন আপনি মালিককে পরিবর্তন করেছেন তা আমি নিশ্চিত নই।
জয়সি

12
@ জাএসি: ডকুমেন্টেশন থেকে : সর্বশেষে, ক্রমটি কলামটির "মালিকানাধীন" হিসাবে চিহ্নিত হয়েছে, যাতে কলাম বা টেবিল বাদ দিলে এটি বাদ দেওয়া হবে।
user272735

8
কেন পোস্টগ্রিস সম্প্রদায়টি কেবল স্ব-সংযোজন মূলশব্দটি পুনরুদ্ধার করে না?
ড। ডিও

2
@ ডিআর দেও: তারা স্বতঃআগ্রহ কীওয়ার্ডের পরিবর্তে সিরিয়াল ব্যবহার করে, কেন জানি না :)
আহমদ

4
আপনি যদি কেবল একটি ছোট ডেটা টাইপ চান তবে সেখানে ছোট্ট সিরিয়ালও রয়েছে।
বেলডাজ

110

আপনি যদি ইতিমধ্যে বিদ্যমান সারণীতে আইডিতে ক্রম যুক্ত করতে চান তবে আপনি এটি ব্যবহার করতে পারেন:

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

ক্রম কি? অটোপ্রেমিক কোথায়?
সবুজ

23
@ গ্রীন: আউটপুট ক্রিমেন্ট এসকিউএল স্ট্যান্ডার্ডের অংশ নয়, এটি মাইএসকিউএলের সাথে নির্দিষ্ট specific সিকোয়েন্সগুলি এমন কিছু যা PostgreSQL এ একই কাজ করে।
বেলডাজ

5
আপনি যদি 'আইডি সিরিয়াল' ব্যবহার করেন তবে এটি স্বয়ংক্রিয়ভাবে পোস্টগ্রিজ এসকিউএলে একটি ক্রম তৈরি করবে। এই ক্রমের নামটি হবে <টেবিলের নাম> _ <কলামের নাম> _ সেক
জুড নিরোশন

আপনি ব্যবহার করতে হবে না ALTER COLUMN user_id?
অ্যালেক 23'18

আমি এই পদ্ধতিটি চেষ্টা করেছিলাম কিন্তু আমি একটি ত্রুটি পেয়েছি: ERROR: syntax error at or near "DEFAULT"কোনও পরামর্শ?
এলি ফিয়ালকফ

44

দেখে মনে হচ্ছে ক্রমগুলি মাইএসকিউএল অটো_সামগ্রীর সমতুল্য , কিছু সূক্ষ্ম তবে গুরুত্বপূর্ণ পার্থক্য রয়েছে:

1. ব্যর্থ প্রশ্নসমূহ ক্রম বৃদ্ধি / ক্রমিক বৃদ্ধি

সিরিয়াল কলাম ব্যর্থ প্রশ্নের উপর বর্ধিত হয়। এটি কেবল সারি মুছে ফেলা নয়, ব্যর্থ প্রশ্নগুলি থেকে বিভাজন ঘটায়। উদাহরণস্বরূপ, আপনার পোস্টগ্রিজ এসকিউএল ডাটাবেসে নিম্নলিখিত প্রশ্নগুলি চালান:

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;

আপনি যদি মাইএসকিউএল আলাদা কী তা পরীক্ষা করতে চান তবে মাইএসকিউএল ডাটাবেসে নিম্নলিখিতটি চালান:

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)

২. সিরিয়াল কলাম মানটি ম্যানুয়ালি সেট করা ভবিষ্যতের প্রশ্নের ব্যর্থ হতে পারে।

এটি পূর্ববর্তী উত্তরে @ ট্রেভ দ্বারা চিহ্নিত করা হয়েছিল।

এটিকে ম্যানুয়ালি অনুকরণ করতে uid 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);

এটি নিম্নলিখিত ত্রুটি বার্তার সাথে ব্যর্থ হবে:

ত্রুটি: সদৃশ কী মানটি অনন্য বাধা "টেবিল 1_পকি" বিবরণ লঙ্ঘন করে: কী (uid) = (5) ইতিমধ্যে বিদ্যমান।

বিপরীতে, মাইএসকিউএল নিচে দেখানো হিসাবে এটি করুণভাবে পরিচালনা করবে:

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) এবং পোস্টগ্রিসকিউএল 9.4.9 এর জন্য মাইএসকিউএল 5.6.33 এ পরীক্ষা করা হয়েছিল


10
আপনি তুলনা দিচ্ছেন কিন্তু আমি এখানে কোন সমাধান দেখতে পাচ্ছি না! এটা কি উত্তর?
আনোয়ার

4
@ আনওয়ার এটি বিভিন্ন উত্তরকে কেবল প্রসারিত করে যা জানিয়েছে যে উত্তরটি একটি সিরিয়াল / ক্রম ব্যবহার করা। এটি বিবেচনার জন্য কিছু গুরুত্বপূর্ণ প্রসঙ্গ সরবরাহ করে।
প্রোগ্রামার

38

পোস্টগ্রিস 10 দিয়ে শুরু করে, এসকিউএল স্ট্যান্ডার্ড দ্বারা সংজ্ঞায়িত পরিচয় কলামগুলিও সমর্থিত:

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এটি মূলত বিদ্যমান হিসাবে একই আচরণ behaviorserial বাস্তবায়নের :

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

যখন মানটি ম্যানুয়ালি সরবরাহ করা হয়, অন্তর্নিহিত ক্রমটি নিজেও পাশাপাশি সামঞ্জস্য করা দরকার - একটির সাথে একই serial কলামের ।


একটি পরিচয় কলাম ডিফল্টরূপে প্রাথমিক কী নয় (ঠিক serialকলামের মতো )। যদি এটি এক হওয়া উচিত তবে একটি প্রাথমিক কী বাধাটি ম্যানুয়ালি সংজ্ঞায়িত করা দরকার।


26

দুঃখিত, একটি পুরানো প্রশ্ন পুনঃভাগ করতে, তবে এটিই প্রথম স্ট্যাক ওভারফ্লো প্রশ্ন / উত্তর যা গুগলে আপ আপ হয়েছে।

এই পোস্টটি (যা গুগলে প্রথমে উঠে এসেছে) পোস্টগ্রিসএসকিউএল 10: https://blog.2ndquadrant.com/postgresql-10- ঘটনাস্থল-কলামগুলি /

যা হ'ল:

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

আশা করি এইটি কাজ করবে :)


1
এটি পোস্টগ্র্রেএসকিউএল 10 এ যাওয়ার উপায় এবং এটি অন্যান্য ডাটাবেস সফ্টওয়্যার যেমন ডিবি 2 বা ওরাকল এর মতো একই বাক্য গঠন।
অ্যাডরিয়ান

1
@ অ্যাড্রিয়ান আসলে GENERATED … AS IDENTITYকমান্ডগুলি স্ট্যান্ডার্ড এসকিউএল। প্রথমে এসকিউএল: 2003 এ যুক্ত হয়েছে , তারপরে এসকিউএল: ২০০৮- তে স্পষ্ট করা হয়েছে । বৈশিষ্ট্যগুলি দেখুন # T174 এবং F386 এবং T178।
তুলসী বাউর্কে

16

আপনার সিরিয়াল বা সিকোয়েন্স ফিল্ডে সরাসরি notোকানোর জন্য আপনাকে সতর্কতা অবলম্বন করতে হবে, অন্যথায় আপনার ক্রমটি সন্নিবেশকৃত মানটিতে পৌঁছে গেলে ব্যর্থ হবে:

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


আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.