วิธีเพิ่มคีย์หลักที่เพิ่มขึ้นอัตโนมัติในตารางที่มีอยู่ใน PostgreSQL


190

ฉันมีตารางที่มีข้อมูลที่มีอยู่ มีวิธีเพิ่มคีย์หลักโดยไม่ต้องลบและสร้างตารางใหม่หรือไม่

คำตอบ:


355

( อัปเดต - ขอบคุณผู้ที่แสดงความคิดเห็น )

รุ่นปัจจุบันของ PostgreSQL

สมมติว่าคุณมีชื่อตารางtest1ซึ่งคุณต้องการเพิ่มidคอลัมน์, คีย์หลัก(ตัวแทน) ที่เพิ่มขึ้นโดยอัตโนมัติ คำสั่งต่อไปนี้ควรเพียงพอใน PostgreSQL รุ่นล่าสุด:

   ALTER TABLE test1 ADD COLUMN id SERIAL PRIMARY KEY;

PostgreSQL เวอร์ชันเก่ากว่า

ในเวอร์ชันเก่าของ PostgreSQL (ก่อนหน้า 8.x?) คุณต้องทำสิ่งที่สกปรกทั้งหมด ลำดับของคำสั่งต่อไปนี้ควรทำเคล็ดลับ:

  ALTER TABLE test1 ADD COLUMN id INTEGER;
  CREATE SEQUENCE test_id_seq OWNED BY test1.id;
  ALTER TABLE test ALTER COLUMN id SET DEFAULT nextval('test_id_seq');
  UPDATE test1 SET id = nextval('test_id_seq');

อีกครั้งใน Postgres เวอร์ชันล่าสุดนี่เทียบเท่ากับคำสั่งเดียวด้านบนโดยประมาณ


3
ฉันใช้ ORACLE ดังนั้นการแบ่งปันอาจมีประโยชน์สำหรับ ORACLE guys ใน ORACLE: แก้ไขตารางทดสอบ 1 เพิ่มหมายเลขประจำตัว อัพเดต TEST1 SET ID = TEST1_SEQ.NEXTVAL; แก้ไขตาราง TEST1 เพิ่มคีย์หลัก (ID); สร้างลำดับ TEST1_SEQ ก่อนที่จะดำเนินการคำสั่ง UPDATE
msbyuva

โปรดทราบว่าADD PRIMARY KEYยังสร้างNOT NULLข้อ จำกัด (ทดสอบใน postgres 9.3) ตามที่คาดหวังและต้องการ
Jared Beck

19
ใน Postgres คุณสามารถใช้คำสั่งเดียวได้เลยALTER TABLE test1 ADD COLUMN id SERIAL PRIMARY KEY;
resnyanskiy

1
นอกจากความคิดเห็นของ @ resnyanskiy สิ่งนี้จะใช้ได้แม้ว่าจะมีข้อมูลในตาราง ID มีการเติมข้อมูลและไม่ได้ตั้งค่าข้อ จำกัด ที่ว่างเปล่า คำตอบทั้งหมดสามารถถูกแทนที่ด้วยบรรทัดในความคิดเห็นนั้น
Synesso

1
@EricWang ขอบคุณ Eric คุณพูดถูก - ฉันเชื่อว่านี่ใช้งานไม่ได้ในบางเวอร์ชั่น (หลายปี) ที่ผ่านมา แต่ฉันไม่แน่ใจ เปลี่ยนคำตอบเป็น community-wiki
leonbloy

57
ALTER TABLE test1 ADD COLUMN id SERIAL PRIMARY KEY;

นี่คือทั้งหมดที่คุณต้อง:

  1. เพิ่มidคอลัมน์
  2. เติมด้วยลำดับจาก 1 ถึงนับ (*)
  3. ตั้งเป็นคีย์หลัก / ไม่เป็นโมฆะ

เครดิตมอบให้แก่ @resnyanskiy ผู้ให้คำตอบนี้ในความคิดเห็น


2
ควรทำเครื่องหมายเป็นคำตอบและคำตอบควรเป็นของ @resnyanskiy
Eric Wang

ฉันต้องวาง pkey ก่อนแล้วจึงรันสิ่งนี้ ALTER TABLE <table> DROP CONSTRAINT <pkey_name>;
Josh Robertson

10

ในการใช้คอลัมน์ข้อมูลประจำตัวใน v10

ALTER TABLE test 
ADD COLUMN id { int | bigint | smallint}
GENERATED { BY DEFAULT | ALWAYS } AS IDENTITY PRIMARY KEY;

สำหรับคำอธิบายของคอลัมน์เอกลักษณ์ดูhttps://blog.2ndquadrant.com/postgresql-10-identity-columns/

สำหรับความแตกต่างระหว่างที่สร้างโดยค่าเริ่มต้นและสร้างรายเสมอให้ดูhttps://www.cybertec-postgresql.com/en/sequences-gains-and-pitfalls/

สำหรับการเปลี่ยนแปลงลำดับดูhttps://popsql.io/learn-sql/postgresql/how-to-alter-sequence-in-postgresql/


ปัญหาของการแก้ปัญหานี้คือถ้าตารางมีแถวอยู่แล้วคุณจะได้รับข้อผิดพลาด:SQL Error [23502]: ERROR: column "id" contains null values
isapir

3
@isapir: มีข้อผิดพลาดในรุ่นเริ่มต้น (pg 10 และ 10.1) ทำให้เกิดข้อผิดพลาดนี้ ได้รับการแก้ไขด้วย pg 10.2 รายละเอียดได้ที่นี่: dba.stackexchange.com/q/200143/3684
Erwin Brandstetter

ขอบคุณ @ erwin-brandstetter
isapir

หนึ่งปีต่อมาฉันพบคำตอบนี้อีกครั้งเห็นได้ชัดว่ามีการแก้ไขข้อผิดพลาด upvoted;)
isapir

2

ฉันลงจอดที่นี่เพราะฉันกำลังมองหาบางสิ่งเช่นนั้นเช่นกัน ในกรณีของฉันฉันกำลังคัดลอกข้อมูลจากชุดของตาราง staging ที่มีหลายคอลัมน์ลงในหนึ่งตารางในขณะเดียวกันก็กำหนดรหัสของแถวไปยังตารางเป้าหมาย นี่คือความแตกต่างของวิธีการข้างต้นที่ฉันใช้ ฉันเพิ่มคอลัมน์อนุกรมที่ท้ายตารางเป้าหมายของฉัน ด้วยวิธีนี้ฉันไม่ต้องมีตัวยึดตำแหน่งไว้ในคำสั่งแทรก จากนั้นให้เลือก * แบบง่ายในตารางเป้าหมายอัตโนมัติที่มีคอลัมน์นี้ นี่คือคำสั่ง SQL สองคำที่ฉันใช้กับ PostgreSQL 9.6.4

ALTER TABLE target ADD COLUMN some_column SERIAL;
INSERT INTO target SELECT * from source;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.