10 คะแนน โดย GN⁺ 2025-10-16 | 2 ความคิดเห็น | แชร์ทาง WhatsApp
  • SQLite ถูกพัฒนาด้วย ภาษา C มาตั้งแต่ช่วงเริ่มต้น (ปี 2000) เพราะเหตุผลด้านประสิทธิภาพ, ความเข้ากันได้, การพึ่งพาภายนอกที่น้อย, และความเสถียร
  • C ใช้งานได้บนแทบทุกระบบปฏิบัติการและทุกภาษา โดยเฉพาะเหมาะกับการเป็น ไลบรารีระดับต่ำ ที่ต้องทำงานได้รวดเร็ว
  • เหตุผลที่เลือก C แทนภาษาเชิงวัตถุคือเรื่องความยืดหยุ่นในการขยาย, การเรียกใช้จากหลายภาษา, และเพราะในเวลาพัฒนานั้น C++ กับ Java ยังไม่สุกงอมพอ
  • SQLite มีโครงสร้างแบบ ไฟล์เดียวที่แทบไม่มี dependency และใช้เพียงฟังก์ชันขั้นต่ำของไลบรารีมาตรฐาน C
  • แม้จะมีการพูดถึงการเขียนใหม่ด้วย "ภาษาที่ปลอดภัย" อย่าง Rust และ Go แต่ในด้านการควบคุมคุณภาพ, ประสิทธิภาพ, และความสามารถในการถูกเรียกใช้เป็นไลบรารี C ก็ยังได้เปรียบอยู่

1. ทำไม C จึงเป็นตัวเลือกที่เหมาะสมที่สุด

  • SQLite คงไว้เป็นภาษา C มาตั้งแต่เริ่มพัฒนาครั้งแรกเมื่อวันที่ 29 พฤษภาคม 2000 จนถึงปัจจุบัน
    • ตอนนี้ยังไม่มีแผนจะเขียนใหม่ด้วยภาษาอื่น
  • C มี ความสามารถในการควบคุมที่ใกล้กับฮาร์ดแวร์ ขณะเดียวกันก็พกพาได้สูง จนถูกเรียกว่า “แอสเซมบลีแบบพกพา”
  • ภาษาอื่นอาจอ้างว่า “เร็วพอๆ กับ C” ได้ แต่ ไม่มีภาษาใดอ้างว่าเร็วกว่า C

1.1. ประสิทธิภาพ

  • ไลบรารีระดับต่ำ อย่าง SQLite ถูกเรียกใช้งานบ่อยมาก จึงจำเป็นต้องทำงานให้เร็วอย่างยิ่ง
  • ภาษา C เหมาะกับการเขียนโค้ดที่รวดเร็ว และยังเข้าถึงฮาร์ดแวร์ได้ใกล้ชิดโดยยังคงความสามารถในการพกพา
  • ภาษาสมัยใหม่อื่นๆ ก็อาจบอกว่า ‘เร็วเท่า C’ แต่ในงานเขียนโปรแกรมทั่วไป ยังไม่มีภาษาใดที่มั่นใจได้ว่าเร็วกว่า C
  • C ควบคุมหน่วยความจำและทรัพยากร CPU ได้ละเอียด จึงอาจให้ ประสิทธิภาพเร็วกว่าระบบไฟล์ 35% ได้ด้วย

1.2. ความเข้ากันได้

  • แทบทุกระบบสามารถเรียกใช้ ไลบรารีที่เขียนด้วย C ได้
  • ตัวอย่างเช่น แม้แต่บน Android (ที่อิงกับ Java) ก็ยังใช้ SQLite ผ่าน adaptor ได้
  • หาก SQLite ถูกเขียนด้วย Java ก็จะไม่สามารถใช้บน iPhone (Objective-C, Swift) ได้ ทำให้ความเป็นสากลลดลงอย่างมาก

1.3. การพึ่งพาภายนอกต่ำ

  • เพราะพัฒนาเป็น ไลบรารี C จึงมี runtime dependency น้อยมาก
  • ในการตั้งค่าขั้นต่ำ จะใช้เพียงฟังก์ชันพื้นฐานมากๆ ของไลบรารีมาตรฐาน C เท่านั้น เช่น memcmp(), memcpy(), memmove(), memset(), strcmp(), strlen(), strncmp()
  • แม้ใน build ที่สมบูรณ์กว่าก็ยังมี dependency เพียงไม่กี่อย่าง เช่น malloc(), free(), การอ่านเขียนไฟล์ เป็นต้น
  • ภาษาสมัยใหม่มักต้องพึ่งพา runtime ขนาดใหญ่จำนวนมาก และ อินเทอร์เฟซนับพันรายการ

1.4. ความเสถียร

  • C เป็น ภาษาที่เก่าและเปลี่ยนแปลงน้อยจนน่าเบื่อ แต่นั่นก็หมายถึง ความคาดการณ์ได้และความเสถียร
  • สำหรับการสร้าง เอนจินฐานข้อมูลที่เล็ก, เร็ว, และเชื่อถือได้ อย่าง SQLite ภาษาที่สเปกไม่เปลี่ยนบ่อยย่อมเหมาะกว่า
  • หากสเปกของภาษาหรือ implementation เปลี่ยนอยู่บ่อยๆ ก็จะไม่เป็นผลดีต่อความเสถียรของ SQLite

2. ทำไมจึงไม่เขียนด้วยภาษาเชิงวัตถุ

  • นักพัฒนาบางคนอาจคิดว่าหากไม่ใช้แนวคิดเชิงวัตถุก็คงยากที่จะสร้างระบบซับซ้อนอย่าง SQLite แต่เมื่อเทียบกับ C แล้ว การสร้างไลบรารีด้วย C++ หรือ Java จะทำให้ภาษาอื่นเรียกใช้ได้ยากกว่า
  • เพื่อรองรับภาษาที่หลากหลาย เช่น Haskell, Java เป็นต้น การเลือก ไลบรารี C จึงสมเหตุสมผล
  • เชิงวัตถุไม่ใช่ภาษา แต่เป็นรูปแบบการออกแบบ ดังนั้นจึงไม่ได้ผูกกับภาษาใดภาษาหนึ่ง
    • แม้แต่ใน C ก็สามารถใช้ struct และ function pointer เพื่อสร้างแพตเทิร์นเชิงวัตถุได้
  • โครงสร้างเชิงวัตถุไม่ได้ดีที่สุดเสมอไป บางครั้งโค้ดเชิงกระบวนการอาจชัดเจนกว่า ดูแลง่ายกว่า และให้ผลลัพธ์ที่เร็วกว่า
  • ในช่วงเริ่มพัฒนา SQLite (ราวปี 2000)
    • Java ยังไม่สุกงอม
    • ส่วน C++ มี ปัญหาความเข้ากันได้ระหว่างคอมไพเลอร์ที่รุนแรง
      → ในเวลานั้น C จึงเป็น ทางเลือกที่ใช้งานได้จริงและปลอดภัยที่สุด
  • แม้ในปัจจุบัน ก็ยังมีข้อดีไม่มากพอที่จะคุ้มกับการเขียน SQLite ใหม่

3. ทำไมจึงไม่เขียนด้วย "ภาษาที่ปลอดภัย"

  • ช่วงหลังมานี้มีความสนใจใน ภาษาการเขียนโปรแกรมที่ปลอดภัย อย่าง Rust และ Go มากขึ้น แต่ตอนที่ SQLite เริ่มพัฒนาขึ้นมา (รวมถึงในช่วง 10 ปีแรก) ภาษาเหล่านี้ยังไม่มีอยู่
  • หากเขียนใหม่ด้วย Go หรือ Rust ก็มีโอกาสที่บั๊กจะมากขึ้น หรือประสิทธิภาพอาจลดลง
  • ภาษาเหล่านี้มักแทรกโค้ด branch เพิ่มเติม เช่น การตรวจสอบหน่วยความจำ ขณะที่ในแนวทางคุณภาพของ SQLite นั้น การทำ 100% branch coverage มีความสำคัญมาก และส่วนนี้ยังไม่ตอบโจทย์
  • ภาษาที่ปลอดภัยมักยุติโปรแกรมเมื่อเกิดภาวะ out-of-memory แต่ SQLite ถูกออกแบบให้กู้คืนได้แม้อยู่ในภาวะหน่วยความจำไม่พอ
  • Rust, Go และภาษาแนวนี้ยังคงเป็นภาษาใหม่ที่ต้องพัฒนาต่อไปอีก
  • ด้วยเหตุนี้ ทีมพัฒนา SQLite จึงสนับสนุนการเติบโตของภาษาที่ปลอดภัย แต่ในการพัฒนา SQLite เองก็ยังให้ความสำคัญกับ เสถียรภาพของ C ที่ผ่านการพิสูจน์แล้ว

ถึงอย่างนั้น ก็ยังมีความเป็นไปได้ว่าในอนาคตอาจ มีการเขียนใหม่ด้วย Rust ส่วน Go มีโอกาสน้อย เพราะ Go ไม่ชอบ assert()

  • แต่การจะเขียนด้วย Rust ได้นั้น มีเงื่อนไขล่วงหน้าดังนี้:
    • Rust ต้องสุกงอมมากขึ้น และมีวงจรการเปลี่ยนแปลงที่ช้าลง จนกลายเป็น “ภาษาที่เก่าและน่าเบื่อ”
    • ต้องพิสูจน์ได้ว่าสามารถสร้าง ไลบรารีสากลที่หลายภาษาเรียกใช้ได้
    • ต้องสร้างอ็อบเจ็กต์โค้ดที่ ทำงานได้แม้บนอุปกรณ์ฝังตัวหรืออุปกรณ์ที่ไม่มี OS
    • ต้องมีเครื่องมือทดสอบ 100% branch coverage สำหรับไบนารีที่คอมไพล์แล้ว
    • ต้อง กู้คืนจากข้อผิดพลาด OOM (หน่วยความจำไม่พอ) ได้
    • Rust ต้องทำทุกอย่างที่ C ทำใน SQLite ได้ โดยไม่เสียประสิทธิภาพ
  • หากผู้ชื่นชอบ Rust (rustacean) คิดว่าเงื่อนไขข้างต้นครบถ้วนแล้ว และ SQLite ควรถูกเขียนใหม่ด้วย Rust ก็ขอแนะนำให้ติดต่อทีมพัฒนา SQLite โดยตรงเพื่อเสนอความเห็น

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

 
GN⁺ 2025-10-16
ความเห็นใน Hacker News
  • แม้ในช่วง 10 ปีแรกจะยังไม่มีภาษาโปรแกรมที่ปลอดภัย แต่ก็คิดว่าการนำ SQLite มาเขียนใหม่ด้วย Go หรือ Rust มีแนวโน้มจะสร้างบั๊กเพิ่มมากกว่าจำนวนที่แก้ได้ และอาจช้าลงด้วย ถ้าโค้ดที่แทบไม่มีบั๊กถูกสร้างเสร็จแล้วผ่านเวลาและการทดสอบมหาศาล ในสถานการณ์ที่อัตราการเปลี่ยนแปลงต่ำ จะเขียนด้วยภาษาอะไรก็ไม่สำคัญแล้ว ต่อให้เป็น assembly ก็แทบไม่ต่างกัน
    • ประเด็นที่ว่า “อัตราการเปลี่ยนแปลงต่ำก็มีปัญหาน้อย” เคยถูกอธิบายไว้ใน Google Security Blog โดยอ้างว่าปัญหาด้าน memory safety ส่วนใหญ่มาจากโค้ดใหม่ และโค้ดจะปลอดภัยขึ้นเมื่อเวลาผ่านไป ลิงก์ที่เกี่ยวข้อง
    • ฝั่ง Rust ก็มีโปรเจกต์อย่าง Turso ที่เคลื่อนไหวค่อนข้างคึกคัก Turso
    • บางคนก็โต้แย้งว่าไม่ควรเขียนยูทิลิตีพื้นฐานของ Linux ใหม่ด้วย Rust เพราะเป็นซอฟต์แวร์ที่ใช้งานมาหลายสิบปีและบั๊กส่วนใหญ่ก็ถูกกำจัดไปแล้ว จึงไม่จำเป็นต้องเขียนใหม่
    • คิดว่า Zig เหมาะกับการแทนที่โค้ด C บางส่วน และเข้ากับ Python รวมถึงไบนารี C เดิมได้ดี ปรัชญาของ Go ก็ดีอยู่ แต่มีข้อจำกัดตรงที่ optimize ยากและต้องอาศัยนักพัฒนาฝีมือดี Rust ก็ใช้ได้เหมือนกัน แต่การใช้ C เดิมต่อไปพร้อมค่อย ๆ นำ Zig เข้ามาทีละนิดทำได้ง่ายกว่ามาก แม้เราจะกำจัดบั๊กจากโค้ด C ไม่ได้หมด แต่ก็รู้สึกว่าการย้ายไป Rust ทำได้ยากในทางปฏิบัติ
    • มี implementation ของ sqlite ที่พอร์ตไป Go อยู่แล้ว cznic/sqlite
  • นอกจากเหตุผลที่ C เป็นตัวเลือกที่ดีที่สุดในตอนเริ่มพัฒนา SQLite และข้อดีในปัจจุบันแล้ว ก็ไม่คิดว่ามีเหตุผลพิเศษอะไรที่ต้องเอา SQLite ไปเขียนใหม่ด้วยภาษาอื่น การทำฐานข้อมูล SQL แบบเบา ๆ เป็นสิ่งที่ใครก็ทำได้ ดังนั้นจะสร้าง implementation ใหม่ด้วย Rust, C++, Go, Lisp หรือภาษาอะไรก็ได้ตามต้องการ จึงไม่เห็นว่าควรทิ้ง implementation เดิมที่ทำงานได้ดีใน C ไปเปล่า ๆ แล้วบังคับให้นักพัฒนาที่ดูแล SQLite ด้วย C มานานกว่า 25 ปีต้องไปเรียนภาษาใหม่และเริ่มทำใหม่ตั้งแต่ต้น
    • รู้สึกว่าในหลาย fandom ของภาษาโปรแกรมมีแนวโน้มจะยัดเยียดสิ่งที่ตัวเองอยากได้ให้คนอื่น และการยอมรับภาษาใหม่ก็กลายเป็นการต่อสู้แบบผลรวมศูนย์ไปส่วนหนึ่ง ถ้าโปรเจกต์ใดถูกพัฒนาด้วยภาษาหนึ่ง แค่ไม่ใช้ภาษานั้นก็เหมือนเป็นการตั้งคำถามว่าภาษาอื่นจำเป็นหรือไม่ ทั้งที่ในความเป็นจริงตัวเลือกมีหลากหลายกว่านั้นมาก และถ้าจะเขียนใหม่จริง ๆ ก็ยังมี Rust, Go, D, Lisp, Julia และภาษาอื่น ๆ อีกมาก
    • ที่จริงแล้วนักพัฒนา SQLite เปิดกว้างต่อการ rewrite ด้วย Rust หาก Rust ผ่านเงื่อนไขตั้งต้นที่จำเป็น ก็มีโอกาสจะสร้างใหม่ได้ด้วยซ้ำ และยังมีคำแนะนำให้แฟน Rust ติดต่อทีมนักพัฒนา SQLite โดยตรง
    • มีโปรเจกต์อย่าง rqlite และ turso ที่ทำด้วย Rust อยู่แล้ว
    • มี adapter ที่เขียนด้วย Go ทำให้ใช้ sqlite ใน golang ได้โดยไม่ต้องพึ่ง cgo ตอนนี้ sqlite ไม่ได้เป็นแค่ C library อย่างเดียว แต่ยังเป็น file format ของฐานข้อมูลด้วย ในอนาคตอาจมี implementation แบบ pure Rust ออกมา และวันหนึ่งมันอาจกลายเป็น implementation หลักก็ได้
    • ช่วงนี้รู้สึกอึดอัดกับกระแสที่ชอบมองข้ามเทคโนโลยีที่มีอายุเกิน 5 ปีว่าเชยเกินไป คิดว่าควรให้ความเคารพกับเทคโนโลยีที่ถูกขัดเกลามาอย่างยาวนานมากกว่านี้
  • ภาษาแบบปลอดภัยจะสร้าง branch เพิ่มสำหรับตรวจขอบเขตเวลาเข้าถึงอาร์เรย์ แต่ในโค้ดที่ถูกต้อง branch เหล่านั้นจะไม่ถูกรันจริง หมายความว่าการทดสอบ branch ให้ครบ 100% ทำได้ยาก และจุดนี้เกี่ยวข้องกับกลยุทธ์คุณภาพของ SQLite ฟังแล้วรู้สึกว่านี่เป็นเหตุผลใหม่ที่น่าสนใจ
    • ถ้ามั่นใจได้ว่า code branch นั้นจะไม่มีวันถูกรันจริง แบบนี้ก็ไม่จำเป็นต้องทดสอบส่วนนั้นไม่ใช่หรือ? รู้สึกเหมือนกำลังยอมลดทอนความปลอดภัยเพื่อแลกกับ test coverage 100%
    • ในภาษาที่ปลอดภัย คอมไพเลอร์จะเติมโค้ดป้องกันอัตโนมัติอย่าง if (i >= array_length) panic("index out of bounds") เข้าไป แต่ตัวโค้ดนั้นเองก็ผ่านการทดสอบมาอย่างดีจากคอมไพเลอร์ Rust อยู่แล้ว จึงน่าจะไม่ต้องกังวล อยากรู้ว่าตัวเองเข้าใจตรรกะนี้ถูกหรือไม่
    • ถ้าเป็นผู้เชี่ยวชาญอย่าง Dr Hipp และเป็นโปรเจกต์อย่าง sqlite ก็คิดว่าเหตุผลลักษณะนี้ก็มีน้ำหนักอยู่เหมือนกัน
    • Rust ก็มีวิธีอย่าง get_unchecked() ที่ทำให้เข้าถึงข้อมูลได้โดยไม่มี bounds check ซึ่งช่วยให้ยังปลอดภัยและเพิ่มประสิทธิภาพได้ เอกสาร get_unchecked
    • สงสัยว่าจะลดปัญหานี้ได้ไหมด้วยการไม่บังคับ coverage กับ branch ที่แตกไป panic ตามเงื่อนไข
  • SQLite ยังเปิดโอกาสไว้ว่า someday อาจถูกเขียนใหม่ด้วย Rust แต่สำหรับ Go โอกาสค่อนข้างน้อยเพราะข้อจำกัดที่เกี่ยวกับ assert() และมองว่าหากจะย้ายไป Rust ต้องมีเงื่อนไขต่อไปนี้: Rust ต้องนิ่งและเปลี่ยนแปลงน้อยต่อเนื่องไปอีกนาน ต้องเหมาะกับการเขียนไลบรารีทั่วไป ต้องรันได้บน embedded ที่ไม่มี OS ต้องมี tooling สำหรับ branch coverage 100% ต้องมีกลไกจัดการข้อผิดพลาด OOM และต้องมาแทนบทบาทของ C ได้โดยไม่เสียประสิทธิภาพ
    • Rust เปลี่ยนแปลงแบบเข้ากันได้มาตั้งแต่ Rust 1.0 เป็นเวลากว่า 10 ปีแล้ว ความต่างอยู่ที่บางคนอยากให้มันหยุดเปลี่ยนไปเลย ขณะที่บางคนรับได้ถ้ายังมีการเปลี่ยนแปลงต่อ การพัฒนาไลบรารีทั่วไปก็พิสูจน์แล้วว่าทำได้ และการรองรับ embedded แบบไม่มี OS ก็เป็นสิ่งที่ทำได้ชัดเจน ส่วน branch coverage นั้นผู้แสดงความคิดเห็นบอกว่าตัวเองไม่ใช่ผู้เชี่ยวชาญจึงไม่แน่ใจ แต่มีงานด้านนี้ในโครงการอย่าง Ferrocene ส่วนตัวภาษา Rust เองไม่ได้บังคับให้มีการจัดสรรหน่วยความจำ ดังนั้นการจัดการ OOM สามารถตัดสินใจได้ในระดับ standard library ส่วนประเด็นประสิทธิภาพก็ขึ้นอยู่กับนิยามที่ใช้วัด
    • สงสัยว่าใน Go เองจะใช้ if condition { panic(err) } เป็น assert function ได้หรือไม่
  • หลายข้อโต้แย้งดูน่าเชื่อในตอนแรก แต่พอตรวจละเอียดแล้วรู้สึกว่าไม่ได้สมบูรณ์แบบนัก คิดว่าถ้าอธิบายให้ชัดเจนว่าเหตุใดถึงเลือก C ตั้งแต่ราวปี 2000 ได้ ก็เพียงพอแล้ว และปัจจุบันก็ควรยอมรับโค้ดเบสที่ผ่านการขัดเกลามาอย่างดี ส่วนเหตุผลประกอบอื่น ๆ ยังมีจุดที่โต้แย้งได้
    • อยากฟังให้ชัดว่าเหตุผลไหนบ้างที่โต้แย้งได้
    • เหตุผลที่ยกมานั้นใช้สนับสนุนการคงโค้ดเบสเดิมไว้ได้ แต่ถ้าจะโน้มน้าวให้นักพัฒนารุ่นใหม่เลือก C แทนภาษาที่ซับซ้อนกว่า ก็ต้องมีเหตุผลมากกว่านี้
    • (เอกสารนี้ถูกเขียนขึ้นในปี 2017)
    • คาดว่าเป็นเอกสารยาวและลงรายละเอียดมากเพื่อรับมือกับคำถามแนว “ทำไมไม่เขียน X ใหม่” จำนวนมากที่ถูกถามมาตลอดหลายปี
  • มีโปรเจกต์ที่ย้าย SQLite ไป Go แบบอัตโนมัติมาหลายปีแล้วและยังเผยแพร่อย่างต่อเนื่อง modernc.org/sqlite โดยผ่าน test suite เดียวกันได้ดีทีเดียว เพียงแต่เวอร์ชัน Go ช้ากว่ามาก และในหลายกรณีความสะดวกของการพอร์ตแบบ native บน Go สำคัญกว่าความเร็วเสียอีก สรุปคือคิดว่าวิธีที่เป็นจริงได้มากกว่าการเขียน SQLite ใหม่ด้วย Go, Rust, Zig, Nim, Swift ฯลฯ คือการแปลจาก C แบบอัตโนมัติ
    • แม้จะผ่าน test suite ที่เปิดเผยต่อสาธารณะ แต่ได้ยินมาว่า SQLite ยังมี test suite ภายในที่เข้มข้นกว่านั้นมาก
    • การผ่าน test suite ไม่ได้แปลว่าไม่มีบั๊ก เพราะยังอาจมี edge case ใหม่ ๆ หรือปัญหาด้านประสิทธิภาพหลงเหลืออยู่
  • คำถามว่า “ทำไม SQLite ถึงพัฒนาด้วย C” อธิบายไว้ดีในเอกสารทางการอยู่แล้ว แต่พอได้ยินคำถามว่า “ทำไมไม่ใช้ Rust” กลับทำให้นึกถึงคำถามว่า “ทำไมถึงต้องเป็น Rust ด้วย?” ก่อน
    • มีความเห็นว่าคำถามนี้เกิดจากชื่อหัวข้อที่ถูกแต่งเติมขึ้นมา
    • มีโปรเจกต์ rewrite ด้วย Rust แบบนี้อยู่แล้ว: tursodatabase/turso และในบล็อกโพสต์ก็มีการพูดถึงเหตุผลเรื่อง Why ด้วย
    • น้ำเสียงของความเห็นคือ มันก็เหมือนกับการถามว่าทำไม SQLite ถึงเขียนด้วย C แทนที่จะเป็น BASIC
  • ยิ่งอ่านเรื่องการเขียนโค้ด การใช้ซอฟต์แวร์ และบทความเกี่ยวกับการ rewrite มากขึ้น ก็ยิ่งรู้สึกว่าปัญหาอย่างหนึ่งคือ ถ้าการ rewrite มีเป้าหมายแค่ “ความเท่าเทียมของฟังก์ชัน” สิ่งที่มักหายไประหว่างทางคือข้อยกเว้นและแพตช์จำนวนมหาศาลที่สะสมมาเรื่อย ๆ สุดท้ายซอฟต์แวร์ก็พังอีก หรือสิ่งที่เคยทำงานได้ดีกลับพังลง การ rewrite แบบนี้จึงต้องอาศัยความระมัดระวังและการเน้นย้ำอย่างมาก และคิดว่าการกู้คืนให้ครบ 100% ทำได้ยาก แม้แต่ไลบรารีสำคัญอย่าง SDL ก็เช่นกัน น่าจะได้เห็นรีลีสที่พังซ้ำ ๆ และเสียงบ่นจากผู้ใช้ต่อไป มองว่า C จะยังอยู่ไปอีกนานแม้หลังจาก Rust กลายเป็นกระแสหลัก และไม่คิดว่าการ rewrite ควรเป็นตัวเลือกตั้งต้น
  • สิ่งที่น่าสนใจกว่าคือ DuckDB ไม่ได้เขียนด้วย Rust แต่เขียนด้วย C++ ทั้งที่เป็นโปรเจกต์ใหม่ซึ่งเกิดในปี 2019 และดูเหมือนมีโอกาสจะเลือก Rust ได้ แต่สุดท้ายก็ใช้ C++ DuckDB ยังใหม่กว่า และ codebase ก็เล็กกว่า SQLite มาก
    • ได้ยินมาว่าทีมพัฒนา DuckDB มั่นใจใน C++ และเชื่อในความสามารถด้าน autovectorization ของคอมไพเลอร์จึงเลือกทางนี้ ตอนนั้น (2019) Rust ยังไม่มีการรองรับ SIMD ระดับสูงที่ชัดเจน และพวกเขาก็ไม่อยากดูแลโค้ด SIMD ที่เขียนเองด้วยมือ
    • ถ้าเป้าหมายคือประสิทธิภาพสูงสุด ก็คิดว่า C++ สร้างไบนารีที่เร็วกว่าได้ด้วยโค้ดที่น้อยกว่า และ C++ รุ่นใหม่ก็มีความปลอดภัยในระดับ compile-time สูง จึงเหมาะกับโค้ดอย่างฐานข้อมูล
    • คิดว่าถ้าเขียนด้วย C++ สมัยใหม่ก็ถือว่าโอเค
  • ก่อนหน้านี้ก็มีการถกเถียงเรื่อง rewrite SQLite มาหลายครั้งแล้ว ปี 2021, ปี 2018
    • คอมเมนต์ของ tptacek น่าสนใจ เพราะในเอกสารเวอร์ชันก่อนมีย่อหน้าว่าด้วยเรื่อง security แต่ในเอกสารเวอร์ชันล่าสุดย่อหน้านั้นหายไป C เป็นช่องโหว่ด้านความปลอดภัยที่ชัดเจนแม้แต่กับ SQLite เอง เวอร์ชันก่อนหน้านี้อธิบายว่า ‘SQLite ไม่ใช่ไลบรารีที่อ่อนไหวด้านความปลอดภัยมากนัก’ และยังบอกด้วยว่าการรัน SQL ที่ไม่น่าเชื่อถือนั้นเป็นปัญหาใหญ่กว่านี้อยู่แล้ว ส่วนการ import ไฟล์จากภายนอกก็มีโค้ดป้องกันและการทดสอบที่เข้มข้นเพื่อป้องกันปัญหา รวมถึงมี routine สำหรับตรวจสอบล่วงหน้าด้วย เอกสาร Web Archive ปี 2021
 
aer0700 2025-10-16

ผมสงสัยกับประโยคที่ว่า C ก็เป็นความเสี่ยงด้านความปลอดภัยสำหรับ SQLite เหมือนกัน ถึงจะเขียนการทดสอบไว้อย่างดีเพียงพอ และเป็นนักพัฒนาที่มีความชำนาญมากพอ ก็ยังเป็นแบบนั้นอยู่หรือเปล่าครับ ปัญหาอาจอยู่ที่ตรรกะและกระบวนการพัฒนาก็ได้ แต่จะบอกว่าตัวภาษาเองเป็นช่องโหว่ด้านความปลอดภัยนั้นเข้าใจได้ยากครับ ที่จริงแล้วแทบไม่มีโปรแกรมไหนที่ไม่พึ่งพาโครงสร้างพื้นฐานที่เขียนด้วย C เลยด้วยซ้ำ