1 คะแนน โดย GN⁺ 2024-02-18 | 1 ความคิดเห็น | แชร์ทาง WhatsApp

หมายเหตุของฉันเกี่ยวกับการออกแบบสคีมา Postgres ของ GitLab (2022)

  • การศึกษาโครงสร้างสคีมา Postgres ของ GitLab เพื่อเปรียบเทียบกับสคีมาที่ฉันกำลังออกแบบ และเรียนรู้แนวปฏิบัติที่ดีจากการออกแบบสคีมาของ GitLab
  • GitLab เป็นแพลตฟอร์ม DevOps แบบโอเพ่นซอร์ส ซึ่งเป็นทางเลือกของ GitHub และสามารถโฮสต์แบบ self-hosted ได้

การใช้ประเภทคีย์หลักที่เหมาะสม

  • เมื่อฐานข้อมูลยังมีขนาดเล็กอาจไม่เห็นผลชัดเจน แต่เมื่อมีการเติบโต คีย์หลักย่อมมีผลต่อพื้นที่จัดเก็บ ความเร็วในการเขียน และความเร็วในการอ่าน
  • ในบรรดาตารางทั้ง 573 ตาราง GitLab ใช้ประเภทคีย์หลัก bigserial 380 ตาราง และใช้ serial4 อีก 170 ตาราง ที่เหลือ 23 ตารางใช้คีย์หลักเชิงประกอบ

การใช้ ID ภายในและภายนอก

  • การไม่เปิดเผยคีย์หลักไปยังโลกภายนอกถือเป็นแนวปฏิบัติที่ดี
  • GitLab ใช้ทั้ง id ภายในและ iid ภายนอกในตารางอย่างเช่น issues, ci_pipelines, deployments, epics

การใช้ชนิดข้อมูล text พร้อมข้อจำกัดความยาว

  • สคีมา GitLab ใช้ทั้ง character varying(n) และ text แต่ใช้ text มากกว่า
  • ชนิดข้อมูล text ไม่มีข้อจำกัดความยาวในตัวเอง และใช้ CHECK เพื่อกำหนดข้อจำกัดความยาว

กฎการตั้งชื่อ

  • ทุกตารางใช้รูปพหูพจน์ และใช้คำนำหน้าชื่อโมดูลเพื่อจัดการ namespace
  • ชื่อตารางและชื่อคอลัมน์ยึดตามรูปแบบ snake_case

การใช้โซนเวลาสำหรับ timestamp

  • GitLab ใช้ทั้ง timestamp with timezone และ timestamp without timezone
  • งานระบบใช้ timestamp without timezone และงานที่ผู้ใช้ดำเนินการใช้ timestamp with timezone

ข้อจำกัดคีย์ต่างประเทศ

  • GitLab ใช้ข้อจำกัดคีย์ต่างประเทศในตารางส่วนใหญ่ แต่มีบางตารางที่ไม่ใช้ เช่น audit_events, abuse_reports, web_hooks_logs, spam_logs

การแบ่งพาร์ติชันของตารางขนาดใหญ่

  • GitLab แบ่งพาร์ติชันตารางที่อาจมีขนาดเติบโตขึ้นเพื่อเพิ่มประสิทธิภาพการ query

รองรับการค้นหาแบบ LIKE ด้วย Trigrams และ gin_trgm_ops

  • GitLab ใช้ดัชนี GIN (Generalized Inverted Index) เพื่อให้การค้นหามีประสิทธิภาพมากขึ้น

การใช้ jsonb

  • สคีมา GitLab ใช้ชนิดข้อมูล jsonb ในตารางหลายตาราง

เคล็ดลับเพิ่มเติม

  • ในตารางที่สามารถแก้ไขได้ จะใช้ฟิลด์สำหรับตรวจสอบการอัปเดต เช่น updated_at แต่ในตาราง log ที่ไม่สามารถแก้ไขได้จะไม่ใช้
  • Enums ถูกเก็บในรูปแบบ smallint แทน character varying เพื่อประหยัดพื้นที่

GN⁺ ความเห็น:

  • การออกแบบสคีมา Postgres ของ GitLab ช่วยให้มีมุมมองเชิงลึกด้านการออกแบบฐานข้อมูล โดยเฉพาะบทเรียนสำคัญสำหรับการปรับแต่งสคีมาเพื่อรองรับระบบขนาดใหญ่
  • เนื่องจาก GitLab เป็นโอเพ่นซอร์ส การตัดสินใจออกแบบสคีมาเหล่านี้จึงเป็นตัวอย่างที่นักพัฒนาคนอื่นๆ สามารถนำไปประยุกต์ใช้ในโปรเจกต์ของตัวเองได้
  • สิ่งที่ควรเรียนรู้จากสคีมา GitLab คือ ต้องพิจารณาปัจจัยสำคัญที่มีผลต่อประสิทธิภาพและการดูแลรักษาฐานข้อมูลอย่างรอบคอบ ไม่ว่าจะเป็นการเลือกชนิดข้อมูล กลยุทธ์การทำ indexing การแบ่งพาร์ติชัน และการใช้งานข้อจำกัดคีย์ต่างประเทศ

1 ความคิดเห็น

 
GN⁺ 2024-02-18
ความคิดเห็นจาก Hacker News
  • โดยทั่วไปแล้วการไม่เปิดเผยคีย์หลักสู่ภายนอกเป็นแนวปฏิบัติที่ดี โดยเฉพาะเมื่อใช้ตัวระบุจำนวนเต็มหรือ bigint ที่เพิ่มขึ้นตามลำดับแบบอัตโนมัติ เพราะสิ่งเหล่านี้สามารถคาดเดาได้

    • มีข้อเสนอว่าการไม่เผยแพร่คีย์หลักต่อภายนอกเป็นแนวปฏิบัติที่ดี โดยเฉพาะตัวระบุจำนวนเต็มที่เพิ่มแบบลำดับ ซึ่งสามารถคาดเดาได้ จึงยิ่งมีความสำคัญมากขึ้น
  • ตัวอย่างเช่น GitHub มี repository สาธารณะ 128 ล้านแห่งในปี 2020 หากสมมติว่ามี issue ราว 20 รายต่อ repository ก็จะเกินขอบเขตของ serial และการเปลี่ยนชนิดข้อมูลของตารางก็มีต้นทุนสูง

    • โดยยกตัวอย่างจำนวน repository สาธารณะและการประเมินจำนวน issue เพื่อชี้ว่าขอบเขตของ serial อาจถูกเกินขอบ โดยอ้างถึงต้นทุนที่สูงในการเปลี่ยนชนิดข้อมูลของตาราง
  • การพูดถึงขนาดการจัดเก็บของคอลัมน์ UUID ไม่ได้มีเหตุผลมากนัก เมื่อพิจารณาว่ามีคอลัมน์อื่นอีก 5 คอลัมน์อยู่ในตาราง ความต่างระหว่าง 128 บิตกับ 64 บิตจึงแทบไม่สำคัญ

    • ให้เหตุผลว่าความกังวลเรื่องขนาดการเก็บข้อมูลของคอลัมน์ UUID ไม่สำคัญเท่าปัญหาประสิทธิภาพ โดยชี้ว่า UUIDv4 สุ่มโดยสมบูรณ์ไม่เหมาะกับประสิทธิภาพของดัชนี และกล่าวว่า UUIDv7 อาจเป็นทางเลือกที่ดีกว่า
  • มักมีการกล่าวซ้ำๆ ว่า Foreign Key มีต้นทุนสูง แต่เป็นข้ออ้างที่แทบไม่เคยได้รับการพิสูจน์อย่างจริงจัง การใช้ฐานข้อมูลอย่างชาญฉลาดต้องอาศัยความรู้และการทดลองมากกว่าเขียนซ้ำใหม่ และมักให้ผลลัพธ์ที่ดีขึ้น

    • ตั้งคำถามต่อข้ออ้างทั่วไปว่า FK มีต้นทุนสูง และเน้นว่าการใช้ฐานข้อมูลอย่างเหมาะสมมีความสำคัญ
  • อยากรู้ว่ามีใครพูดถึงความต่างด้านประสิทธิภาพระหว่าง GitLab กับ GitHub หรือไม่

    • แสดงความสนใจในความต่างด้านประสิทธิภาพระหว่าง GitLab กับ GitHub โดยรู้สึกว่าเวลาโหลดหน้าเว็บของ GitLab ช้ากว่า GitHub อย่างชัดเจน
  • สงสัยถึงจุดประสงค์ของการเพิ่มตัวอักษร "I" ในตัวแปร CI CI_PIPELINE_IID และ CI_MERGE_REQUEST_IID คิดว่ามาจากการตัดสินใจด้านฐานข้อมูล และบทความนี้ก็ยืนยันสิ่งนั้น

    • สะท้อนความสงสัยเรื่องจุดประสงค์ของตัวอักษร "I" ที่เพิ่มเข้ามาในตัวแปร CI และสรุปว่ามันเกี่ยวข้องกับการเลือกใช้ฐานข้อมูล
  • บทความนี้มีประโยชน์มาก อยากรู้ว่าจะหาเนื้อหาทำนองนี้ได้จากที่ไหนอีก

    • รู้สึกว่าบทความนี้มีประโยชน์มาก และอยากหาส่งรานอื่นที่มีเนื้อหาใกล้เคียงกัน
  • คนเดียวกันหรือเปล่าที่รู้สึกว่าการออกแบบสคีมาและการพัฒนายังล้าหลัง

    • มีความรู้สึกว่าสคีมาและการพัฒนาไม่ทันสมัย โดยเฉพาะความเสี่ยงเรื่องข้อมูลหายระหว่าง migration และตั้งคำถามว่าทำไมฐานข้อมูล/ORM ไม่ได้จัดการ external ID กับ internal ID ให้โดยอัตโนมัติ
  • 1เกียงเท่ากับ 1,000,000,000 ล้านล้าน

    • ชี้ให้เห็นว่าความเป็นจริงคือการต้องเลือกระหว่างจำนวนเต็ม 32 บิตกับ 64 บิต และกล่าวถึงความจำเป็นของชนิดจำนวนเต็มขนาด 5 ไบต์สำหรับรองรับ cardinality ราว 1 ล้านล้าน
  • เมื่อใช้ native UUID v4 type ของ Postgres ขนาดตารางจะเพิ่มขึ้น 25% และอัตรา insert ลดลงเหลือ 25% เมื่อเทียบกับ bigserial

    • แสดงความสนใจในความต่างด้านประสิทธิภาพระหว่าง UUIDv4 กับ bigserial และขอคำอธิบายว่าทำไม UUIDv4 จึงมีประสิทธิภาพแย่ลง