แบ่งปันลำดับคีย์หลักเดียวข้ามฐานข้อมูลหรือไม่


14

เป็นวิธีปฏิบัติที่ยอมรับได้หรือไม่ในการใช้ลำดับเดียวเป็นคีย์หลักในทุกตาราง (แทนที่จะเป็นคีย์หลักที่มีลักษณะเฉพาะสำหรับตารางที่กำหนด ถ้าเป็นเช่นนั้นจะเป็นการดีกว่าการใช้ลำดับคีย์หลักเดียวในตาราง

ฉันเป็นผู้พัฒนาซอฟต์แวร์รุ่นเยาว์ไม่ใช่ DBA ดังนั้นฉันยังคงเรียนรู้พื้นฐานการออกแบบฐานข้อมูลที่ดีมากมาย

แก้ไข: ในกรณีที่มีใครสงสัยฉันเพิ่งอ่านบทวิจารณ์ของการออกแบบฐานข้อมูลโดยหนึ่งใน DBA ของ บริษัท ของเราซึ่งกล่าวว่าเป็นปัญหาที่การออกแบบไม่ได้ใช้คีย์หลักเดียวในฐานข้อมูลทั้งหมดซึ่งฟังดูแตกต่างจากสิ่งที่ ฉันเรียนมาแล้ว

แก้ไข 2: เพื่อตอบคำถามในความคิดเห็นนี่สำหรับ Oracle 11g แต่ฉันสงสัยในระดับที่ไม่ใช่ฐานข้อมูล หากคำถามนี้ขึ้นอยู่กับฐานข้อมูลฉันจะสนใจที่จะรู้ว่าทำไม แต่ในกรณีเช่นนี้ฉันจะหาคำตอบเฉพาะสำหรับ Oracle


2
มันเป็นความคิดที่แย่มาก ๆ ด้วยเหตุผลด้านประสิทธิภาพ
Philᵀᴹ

1
ที่จริงแล้วมีประโยชน์มากขึ้นในการมีแต่ละช่วงของคีย์หลักที่เป็นอิสระ แต่เฉพาะเมื่อคุณดู ID จำนวนมากคุณสามารถพูดได้ว่านี่คือบัญชีผู้ใช้นั่นคือ PurchaseHeader ฯลฯ การทำเช่นนี้ต้องมีการตั้งค่าบางอย่างและ (เช่นสิ่งที่มีวัตถุประสงค์พิเศษ) มีการดูแลและให้อาหารอย่างต่อเนื่อง (ใช่ฉันได้ทำงานกับระบบเช่นนี้เมื่อหลายปีก่อน)
RLF

คุณใช้ DBMS รุ่นใดอยู่ ออราเคิล? Postgres? DB2?
a_horse_with_no_name

1
เป็นไปได้หรือไม่ที่คุณตีความสิ่งที่เขาหมายถึง? บางทีเขาอาจไม่ได้เป็นตัวอักษรที่แท้จริง?
JamesRyan

บริษัท DBA จริง ๆ แล้วหมายความว่าไม่มีเขตข้อมูลคีย์หลักในตารางใด ๆ
Max Vernon

คำตอบ:


13

ได้รับการยอมรับ? แน่ใจ เหมือนกัน? ไม่เป็นประโยชน์ น่าสงสัย

ที่งานเก่าของฉันเราสืบทอดระบบที่พวกเขามีตัวสร้างลำดับกลาง (นี่คือระบบ SQL Server มานานก่อนที่จะSEQUENCEถูกนำมาใช้ใน SQL Server 2012) มันไม่ได้เป็นปัญหาคอขวดของประสิทธิภาพและไม่ควรเกิดขึ้นหากคุณไม่ได้สร้างมูลค่าหลายแสนต่อวินาที แต่มันทำให้รหัสทั้งหมดมีความซับซ้อนมากกว่าที่มันเป็นเพราะไม่มีเหตุผลที่ดี จุดประสงค์ของการออกแบบคือเพื่อให้แน่ใจว่าหากบางสิ่งในระบบได้รับการกำหนดค่า ID เป็น 12 สิ่งเดียวเท่านั้นในระบบที่สามารถมี ID 12 ได้ดูเหมือนว่าฉันและฉันไม่เคยเข้าใจมันเลย หากฉันมีลูกค้าที่มี CustomerID = 12 เหตุใดจึงไม่ทำให้ฉันมีการสั่งซื้อที่มี OrderID = 12

ฉันเห็นประโยชน์ของเครื่องมือสร้างลำดับกลางถ้าคุณมีหลายระบบและคุณกำลังสร้าง ID สำหรับเอนทิตีบางประเภท (เช่นลูกค้าหรือคำสั่งซื้อ) จากหลายระบบ ลำดับกลางสามารถแจกแจงค่าใหม่ให้กับหลาย ๆ ระบบโดยไม่ต้องเป็นคอขวด (เพียงจุดเดียวของความล้มเหลว) และโดยไม่ต้องกลัวว่าระบบทั้งสองจะสร้าง ID เดียวกัน


หากคุณต้องเลือกระหว่างสิ่งนี้และใช้ตัวระบุเฉพาะเป็นคีย์หลักคุณจะชอบไหม (แม้ว่าคำตอบน่าจะเป็น "มันขึ้นอยู่กับ")? ดูเหมือนว่า GUID จะแก้ปัญหาในลักษณะเดียวกันยกเว้นว่าคุณจะได้รับการใช้งานมาตรฐานแทนที่จะต้องหมุนตัวกำเนิดคีย์หลักของตัวเองจากส่วนกลาง เห็นได้ชัดว่าการใช้ลำดับใน SQL 2012 จะทำให้ทั้งสองสิ่งสำเร็จ แต่สมมติว่ามีคนอยู่ในรุ่นที่เก่ากว่าใช่ไหม
SqlRyan

2
@SqlRyan ฉันต้องเข้าใจว่าเหตุใด OrderID จึงต้องแตกต่างจากรหัสลูกค้าอย่างสิ้นเชิง ฉันเกือบจะไม่ใช้ GUID สำหรับสิ่งนี้ การตั้งค่าช่วงข้อมูลประจำตัวอาจดีกว่า (ลูกค้าเริ่มต้นที่ 1 คำสั่งซื้อเริ่มต้นที่ 1000000 ฯลฯ ) พร้อมการแจ้งเตือนเมื่อคุณเข้าใกล้จนหมดช่วงของหลักสูตร
Aaron Bertrand

1
@SqlRyan - การใช้ GUID ที่ใช้งานได้ไม่ดีเนื่องจากคีย์หลักที่เป็นคลัสเตอร์สามารถทำให้เกิดปัญหาได้ทุกประเภท ดังที่แอรอนกล่าวว่าตัวตนเหมาะกับจุดประสงค์ที่ดีกว่า
Max Vernon

ในระบบก่อนหน้านี้ฉันเห็นการใช้ลำดับเดียวทั่วทั้งฐานข้อมูลสิ่งนี้ทำเพื่ออนุญาตให้ foreign key ชี้ไปยังตารางต่าง ๆ มากมายแทนที่จะเป็นตารางเดียวดังนั้นเมื่อคุณบอกว่า foreign key ของแถวที่แตกต่างกันสองแถว อายุ 12 คุณรู้ว่าพวกเขาชี้ไปที่สิ่งเดียวกันโดยไม่จำเป็นต้องตรวจสอบตารางที่เป็นไปได้ที่พวกเขาชี้ไป 13 ในคอลัมน์เดียวกันอาจเป็นคีย์หลักในตารางอื่น โดยส่วนตัวแล้วฉันรู้สึกไม่สบายใจกับสไตล์การออกแบบนั้นมาก
Lawtonfogle

@AaronBertrand หรืออีกวิธีหนึ่งคือใช้ตัวระบุจำนวนเต็มอย่างง่ายและต่อท้ายรหัสบางส่วนเพื่อเริ่มต้นเมื่อสิ่งเหล่านี้หันหน้าไปทางลูกค้า เช่น. I1337, C1337 ชัดเจนใบแจ้งหนี้หรือลูกค้า
JamesRyan

7

แนวคิดมีข้อดีในฐานข้อมูลที่ซับซ้อนมากซึ่งผู้คนสามารถเข้าร่วมตารางโดยใช้คอลัมน์ผิดและบังเอิญได้แถวที่ไม่ถูกต้องเพราะรหัส INT นั้นเหมือนกัน

เราเลือกที่จะมี GUID ตามลำดับเป็นกุญแจหลักของเราเพื่อหลีกเลี่ยงข้อผิดพลาดบางส่วนของการกระจายตัวของดัชนีของ GUID น่าเศร้าที่พวกเขามีขนาดค่อนข้างใหญ่

เซิร์ฟเวอร์ SQL สามารถสร้าง GUID ตามลำดับผ่านการเรียกใช้ฟังก์ชัน newSequentialID () ที่เป็นค่าเริ่มต้นดังนั้นจึงไม่มีตารางของคีย์ที่ออกเพื่อรักษาและไม่มีการปิดกั้นคอขวด

สิ่งนี้ทำให้เรามี ID ที่ไม่ซ้ำกันในฐานข้อมูลทั้งหมดทั่วทั้งองค์กรของเราจริง ๆ เพราะพวกเขามีเอกลักษณ์เฉพาะอย่างแท้จริง

ราคาของหลักสูตรคือพื้นที่และเป็นปัญหาเมื่อคุณพยายามนำข้อมูลข้ามไปยัง Data Warehouse / Cube ซึ่งมีการกำหนดความเร็ว / ขนาดไว้ล่วงหน้าโดยใช้คีย์ Integer ที่มีขนาดเล็กลง

ฉันเชื่อว่าเราได้หลีกเลี่ยงข้อบกพร่องมากมายในแอปของเราอันเป็นผลมาจากการใช้พวกเขา


4

ฉันไม่สามารถจินตนาการได้ว่าอะไรจะเป็นสาเหตุของลำดับเดียวในทุกตาราง ทั้งหมดนี้คือสร้างคอขวดเมื่อสร้างค่าใหม่

ไม่ว่าค่าโสหุ้ยในการสร้างค่าคีย์ลำดับขนาดเล็กเพียงใดเครื่องกำเนิดเป็นทรัพยากรเดียวการเข้าถึงที่ต้องทำข้อมูลให้ตรงกัน ยิ่งมีคำขอมากเท่าไหร่โอกาสที่ผู้ขอบางคนจะต้องรอก็จะยิ่งสูงขึ้น เป็นที่ชัดเจนว่าตัวสร้างลำดับเดียวที่ใช้ร่วมกันระหว่างตารางทั้งหมดจะเข้าถึงได้บ่อยครั้งโดยไคลเอนต์จำนวนมากขึ้นดังนั้นจึงสร้างความขัดแย้งมากขึ้น การโต้แย้งอาจมีความชัดเจนมากขึ้นหากกฎเกณฑ์ทางธุรกิจกำหนดข้อ จำกัด ตามค่าที่สร้างขึ้นเช่นการขาดช่องว่างหรือการสั่งซื้อที่เข้มงวดหรือในฐานข้อมูลคลัสเตอร์

แม้จะมีตัวสร้างลำดับที่มีประสิทธิภาพมากที่สุดก็จะมีเวิร์กโหลดที่ทำให้เกิดข้อขัดแย้งที่ไม่สามารถทนได้


2
คุณอาจต้องการเพิ่มรายละเอียดเกี่ยวกับวิธีการสร้างคอขวดและสาเหตุที่เป็นความคิดที่ไม่ดี
Max Vernon

2

วัตถุประสงค์ของ PrimaryKey ในตารางฐานข้อมูลมีวัตถุประสงค์หลักเพื่อบังคับใช้ความเป็นเอกลักษณ์ของข้อมูลที่ควรจะไม่ซ้ำกันเพราะเวิร์กโฟลว์ทั้งหมดไม่สามารถครอบคลุมและมั่นใจได้ว่าจะไม่ทำให้ข้อมูลซ้ำซ้อน เหตุผลที่สองคือหลาย ๆ ครั้งที่ PK เป็นตัวเลือกหลักสำหรับดัชนีกลุ่มบนตารางดังนั้นจึงเพิ่มการดึงข้อมูลเมื่อ / ที่คอลัมน์เหล่านี้ถูกใช้อย่างถูกต้องในแบบสอบถามแบบใช้เลือกข้อมูล

การใช้หมายเลขลำดับเป็นคีย์หลักเหมือนกับทุกตารางมีคอลัมน์ Identity และมีการใช้คอลัมน์นั้นใน PrimaryKey เท่านั้น มีหมายเลขลำดับเดียวทั่ว DB ต้องมีการใช้งานเฉพาะบางอย่าง แต่จากมุมมองของ PrimaryKey ฉันไม่เข้าใจเหตุผล ตัวอย่างเช่นหนึ่งในโครงการดาต้าแวร์เฮาส์ที่ฉันทำงานเรามีคอลัมน์ชื่อ LoadBatchID และจาก ETL ไปจนถึงการรายงาน 50% ของตารางทั้งหมดมีคอลัมน์นี้ แต่ในบางแห่งมีความหมายแตกต่างกัน เราใช้ proc ที่ไม่ซ้ำกันเป็นตัวสร้างตัวเลขเพื่อให้แน่ใจว่าเราจะไม่พบข้อขัดแย้งและยังช่วยให้เราติดตามกลับไปที่ไฟล์ต้นฉบับจากแหล่งที่มาของข้อมูลและสิ่งที่เกิดขึ้นในแต่ละขั้นตอนของ ETL


2

ฉันคิดว่าเหตุผลหนึ่งที่จะทำก็คือถ้าหน่วยงานทั้งหมดที่สืบทอดมาจากนิติบุคคลแม่บางส่วน พูดเช่นคุณต้องการแสดงความคิดเห็นในเอนทิตีประเภทใด ๆ :

create table god_entity (
  id bigserial primary key
);

create table some_table (
  id bigint primary key references god_entity(id),
  ...
);

create table some_other_table (
  id bigint primary key references god_entity(id),
  ...
);

create table comment (
  id bigint primary key references god_entity(id),
  ...
);

create table entity_comment (
  entity_id bigint not null references god_entity(id),
  comment_id bigint not null references god_entity(id),

  primary key (entity_id, comment_id)
);

มักจะไม่ทำเช่นนี้ .

ไม่ทราบเกี่ยวกับคุณสมบัติของประสิทธิภาพ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.