ฟิลด์ที่เพิ่มขึ้นอัตโนมัติซึ่งขึ้นอยู่กับฟิลด์อื่น [ซ้ำกัน]

ฉันมีสองรุ่น A และ B โดย A มี B จำนวนมาก เดิมทีทั้ง A และ B มีช่องคีย์หลักแบบเพิ่มค่าอัตโนมัติที่เรียกว่า id และ B มีช่อง a_id ตอนนี้ฉันพบว่าตัวเองต้องการลำดับตัวเลขที่ไม่ซ้ำกันสำหรับ B แต่ละตัวภายใน A ฉันกำลังติดตามสิ่งนี้ภายในแอปพลิเคชันของฉัน แต่แล้วฉันก็คิดว่ามันอาจสมเหตุสมผลกว่าถ้าปล่อยให้ฐานข้อมูลจัดการมัน ฉันคิดว่าฉันสามารถให้คีย์ผสมแก่ B โดยที่องค์ประกอบแรกคือ a_id และองค์ประกอบที่สองเพิ่มขึ้นอัตโนมัติ โดยคำนึงถึง a_id ดังนั้นหากฉันแทรกสองระเบียนด้วย a_id 1 และอีกระเบียนหนึ่งด้วย a_id 2 ฉันจะได้ดังนี้:

a_id | other_id
   1 |        1
   1 |        2
   2 |        1

หากลบรหัสที่มีตัวเลขต่ำกว่า ลำดับไม่ควรนำตัวเลขเหล่านี้กลับมาใช้ใหม่ ดังนั้นหาก (1, 2) ถูกลบ:

a_id | other_id
   1 |        1
   2 |        1

เมื่อเพิ่มระเบียนถัดไปด้วย a_id 1 ตารางจะมีลักษณะดังนี้:

a_id | other_id
   1 |        1
   2 |        1
   1 |        3

ฉันจะทำสิ่งนี้ใน SQL ได้อย่างไร มีเหตุผลไหมที่จะไม่ทำอะไรแบบนี้?

ฉันกำลังใช้ H2 ในหน่วยความจำ (การทดสอบและพัฒนา) และ PostgreSQL 9.3 (เวอร์ชันที่ใช้งานจริง)


person mushroom    schedule 27.12.2013    source แหล่งที่มา
comment
SQL เป็นเพียง Structured Query Language ซึ่งเป็นภาษาที่ใช้โดยระบบฐานข้อมูลจำนวนมาก แต่ไม่ใช่ผลิตภัณฑ์ฐานข้อมูล... มีหลายสิ่งหลายอย่างที่เป็นผู้จำหน่าย- เฉพาะเจาะจง - ดังนั้นเราจึงจำเป็นต้องทราบว่าคุณใช้ ระบบฐานข้อมูล ใด (และเวอร์ชันใด) (โปรดอัปเดตแท็กตามนั้น)....   -  person marc_s    schedule 27.12.2013
comment
ทำไมคุณถึงต้องการสิ่งนี้?   -  person T McKeown    schedule 27.12.2013
comment
@marc_s ดูการอัปเดต ฉันพยายามที่จะเป็นผู้ขายที่ไม่เฉพาะเจาะจงเท่าที่จะเป็นไปได้   -  person mushroom    schedule 28.12.2013
comment
other_id ควรจะเป็น id จริงๆ หรือ? ถ้าแถวที่มี other_id ต่ำกว่าสำหรับ a_id เดียวกันกำลังถูกลบ other_id ควรได้รับการอัปเดตหรือไม่ ถ้าแถวที่มี other_id สูงสุดกำลังถูกลบ และแถวอื่นกำลังถูกแทรก other_id ของแถวนั้นควรจะเป็น +1 หรือไม่   -  person Max♦    schedule 28.12.2013
comment
@Max other_id ไม่ควรอัปเดตหากลบตัวเลขที่ต่ำกว่า ขอบคุณสำหรับการชี้ให้เห็นสิ่งนี้ ฉันจะอัปเดตคำถาม   -  person mushroom    schedule 28.12.2013


คำตอบ (1)


คำตอบสำหรับคำถามของคุณคือ คุณจะต้องมีทริกเกอร์จึงจะใช้งานฟังก์ชันนี้ได้ อย่างไรก็ตาม คุณสามารถสร้างมุมมองที่ใช้ฟังก์ชัน row_number() ได้:

create view v_table as
    select t.*,
           row_number() over (partition by a order by id) as seqnum
    from table t;

โดยที่ฉันกำลังเรียกคีย์หลักสำหรับตาราง id

person Gordon Linoff    schedule 27.12.2013
comment
ใช้งานได้ตราบใดที่ตัวเลขที่ต่ำกว่าไม่ถูกลบ ดูความคิดเห็นด้านบน หากหมายเลขที่ต่ำกว่ากำลังถูกลบ row_number จะได้รับการอัปเดตด้วยซึ่งไม่น่าจะเกิดขึ้น - person Max♦; 28.12.2013
comment
โปรดดูการอัปเดตเกี่ยวกับการลบ as seqnumทำอะไร? ฉันพยายามค้นหาแต่ไม่พบอะไรเลย - person mushroom; 28.12.2013
comment
เนื่องจาก seqnum เพิ่งกำหนดชื่อให้กับคอลัมน์ - person Max♦; 28.12.2013
comment
@เห็ด. . . หากคุณต้องการให้ค่าคงอยู่หลังจากการลบ ฉันคิดว่าคุณต้องใช้ทริกเกอร์ - person Gordon Linoff; 28.12.2013