§

จัดรูปแบบคำสั่ง SQL

ภาษาถิ่น
การเยื้อง
ตัวพิมพ์คีย์เวิร์ด
ขึ้นบรรทัดใหม่ก่อนส่วนคำสั่ง
§

วาง SQL

§

SQL ที่จัดรูปแบบแล้ว

ทีมวิศวกรข้อมูลของ KASIKORNBANK ใช้ Snowflake เป็นคลังข้อมูลหลัก และกำหนดให้จัดรูปแบบ SQL ก่อน commit ทุกครั้ง เพราะ CTE ขนาด 200 บรรทัดที่ถูกยุบเป็นบรรทัดเดียวทำให้ diff pull-request อ่านไม่ออก AIS ใช้ BigQuery วิเคราะห์ข้อมูลพฤติกรรมลูกค้าและประสิทธิภาพเครือข่าย ทีม data engineering ใช้แนวทาง dbt Labs เป็นมาตรฐานการจัดรูปแบบเพื่อให้ diff สะท้อนการเปลี่ยนแปลงเชิงตรรกะเท่านั้น Central Group รัน SQL บน Tableau เพื่อรายงานยอดขายข้ามห้างสรรพสินค้า ทีมวิเคราะห์ใช้ตัวจัดรูปแบบนี้เพื่อทำให้คำสั่ง SQL อ่านได้ก่อนแชร์ใน runbook หรือ incident retro โดยข้อมูลไม่ออกจากเบราว์เซอร์

การจัดรูปแบบ SQL ทำงานอย่างไร

การจัดรูปแบบ SQL คือการเขียนใหม่ที่ขับเคลื่อนด้วย lexer โดยวนซ้ำทุก token ในคำสั่งและส่งออกช่องว่างรอบ ๆ ตามกฎของภาษาถิ่นที่เลือก ความหมายของคำสั่งไม่เปลี่ยนแปลง มีเพียงรูปแบบที่ปรับเปลี่ยน

  1. เลือกภาษาถิ่น. Backtick ของ MySQL การแปลง :: ของ PostgreSQL เส้นทางตารางแบบมีจุดของ BigQuery และตัวระบุในวงเล็บเหลี่ยมของ T-SQL ต่างต้องการ tokenizer ที่รู้จักไวยากรณ์เหล่านั้น ตัวเลือกภาษาถิ่นจะกำหนดว่าจะใช้ไวยากรณ์ใด
  2. แบ่ง token จากข้อมูลนำเข้า. ตัวจัดรูปแบบแบ่งคำสั่งออกเป็นสตรีม token ได้แก่ คีย์เวิร์ด (SELECT, JOIN) ตัวระบุ ค่าคงที่ ตัวดำเนินการ วงเล็บ และคอมเมนต์ ค่าคงที่ประเภทสตริงและตัวระบุที่มีเครื่องหมายคำพูดจะถูกส่งผ่านโดยไม่แตะต้อง
  3. ใช้กฎการจัดวาง. ส่วนคำสั่งระดับบนสุด (SELECT, FROM, WHERE, GROUP BY, ORDER BY) จะเริ่มต้นในบรรทัดของตัวเอง นิพจน์ที่คั่นด้วยจุลภาคในรายการเลือกและรายการคอลัมน์ต่างได้รับบรรทัดของตัวเอง โดยเยื้องตามหน่วยการเยื้องที่เลือก
  4. ใช้ตัวพิมพ์คีย์เวิร์ด. ปุ่มตัวพิมพ์คีย์เวิร์ดจะเขียนคีย์เวิร์ด SQL ที่รู้จักใหม่เป็นตัวพิมพ์ใหญ่ ตัวพิมพ์เล็ก หรือคงการพิมพ์เดิมไว้ตามที่ป้อน ตัวระบุจะไม่ถูกแตะต้องเลย ชื่อคอลัมน์และตารางจะคงเดิมเสมอ
  5. ส่งออกสตริงที่จัดรูปแบบแล้ว. สตรีม token จะถูกรวมกลับเป็นสตริงเดียวด้วยอักขระการเยื้อง (2 ช่องว่าง 4 ช่องว่าง หรือแท็บ) และกฎการขึ้นบรรทัดใหม่ที่กำหนดค่า โหมดสดจะรันกระบวนการทั้งหมดซ้ำด้วย debounce 200 มิลลิวินาทีขณะที่คุณพิมพ์

ทำไมต้องพิมพ์สวย SQL

  • อ่าน diff ใน pull-request ได้ง่ายขึ้น. CTE 200 บรรทัดที่เขียนใหม่เป็นบรรทัดเดียวทำให้การ review โค้ดกลายเป็นเกมเดา การจัดรูปแบบที่สม่ำเสมอทำให้ diff จำกัดอยู่กับการเปลี่ยนแปลงที่ทำจริง ไม่ว่าจะเป็นคอลัมน์ใหม่ JOIN เพิ่มเติม หรือ predicate WHERE อื่น เพื่อให้ผู้ตรวจทานเห็นได้โดยไม่ต้องคลี่ช่องว่าง
  • แก้ไขข้อผิดพลาดได้ง่ายขึ้น. เมื่อคำสั่งส่งคืนจำนวนแถวที่ผิด สิ่งแรกที่ทำคืออ่านทีละบรรทัด SQL ที่จัดรูปแบบแล้วจะวาง JOIN แต่ละรายการในบรรทัดของตัวเอง และจัดแนว predicate WHERE เพื่อให้ AND ที่หายไปหรือ OR ที่ผิดที่ปรากฏให้เห็นทันที
  • รูปแบบทีมที่สม่ำเสมอ. ทีมส่วนใหญ่ใช้คู่มือรูปแบบ SQL (dbt Labs, GitLab, Mode Analytics ต่างเผยแพร่ของตัวเอง) และต้องการให้ทุกคำสั่งที่ commit ปฏิบัติตาม การรันตัวจัดรูปแบบก่อน commit จะนำข้อถกเถียงเรื่องรูปแบบออกจากการ review และเหลือเพียงตรรกะให้หารือ
  • แชร์ SQL ในเอกสาร. Runbook, incident retro และเอกสาร Notion ล้วนได้ประโยชน์จาก SQL ที่อ่านจากบนลงล่าง SQL ที่จัดรูปแบบแล้วจะวางลงในบล็อกโค้ดแบบ fenced ได้อย่างสะอาด และพิมพ์ได้อย่างคาดเดาได้ใน PDF โดยไม่มีการขึ้นบรรทัดใหม่ที่น่าอึดอัดกลางคีย์เวิร์ด

การใช้งานทั่วไป

การจัดรูปแบบ SQL ปรากฏในงานวิศวกรรมการวิเคราะห์ การพัฒนา backend และงานปฏิบัติการ เมื่อคำสั่งต้องถูกอ่านโดยผู้ที่ไม่ได้เขียน

  • วิศวกรรมการวิเคราะห์: hook ก่อน commit ในโปรเจกต์ dbt ที่จัดรูปแบบไฟล์โมเดลทุกไฟล์ใหม่ เพื่อให้ diff PR จำกัดอยู่กับการเปลี่ยนแปลงเชิงตรรกะ ไม่ใช่การเปลี่ยนแปลงช่องว่าง
  • การบริหารฐานข้อมูล: วางรายการ log คำสั่งช้าบรรทัดเดียว จัดรูปแบบ และตรวจสอบลำดับ join ขณะเขียน incident retro
  • เอกสาร: นำคำสั่งจาก Looker explore หรือ workbook Tableau มาจัดรูปแบบสำหรับ runbook และฝังเป็นตัวอย่างที่คัดลอกได้สำหรับ rotation on-call

ตัวอย่างที่ทำแล้ว

วาง SELECT u.id,u.email,COUNT(o.id) FROM users u LEFT JOIN orders o ON o.user_id=u.id WHERE u.created_at > '2024-01-01' GROUP BY u.id,u.email ORDER BY u.id; ลงในแผงป้อนข้อมูลโดยตั้งค่าภาษาถิ่นเป็น PostgreSQL การเยื้อง 2 ช่องว่าง และตัวพิมพ์คีย์เวิร์ดเป็นตัวพิมพ์ใหญ่ ผลลัพธ์จะวาง SELECT, FROM, LEFT JOIN, WHERE, GROUP BY และ ORDER BY ในบรรทัดของตัวเอง คอลัมน์แต่ละรายการในรายการเลือกและรายการ group-by จะได้รับบรรทัดที่เยื้องของตัวเอง และ predicate ON จะอยู่ลึกกว่าคีย์เวิร์ด JOIN ที่เป็นของมันหนึ่งระดับ

FAQ

รองรับภาษาถิ่น SQL ใดบ้าง?

เมนู dropdown ภาษาถิ่นครอบคลุม SQL มาตรฐาน MySQL PostgreSQL SQLite MariaDB Transact-SQL (SQL Server / Azure SQL) BigQuery Snowflake และ Redshift ไลบรารี sql-formatter ที่เป็นพื้นฐานยังรู้จัก DuckDB, Spark SQL, Hive, Trino, Db2, N1QL, PL/SQL, ClickHouse, TiDB และ SingleStoreDB ด้วย — การเลือกภาษาถิ่นที่ใกล้เคียงที่สุดจะให้ผลลัพธ์ที่สมเหตุสมผลแม้ว่าเป้าหมายที่แน่นอนจะไม่อยู่ในรายการ ตัวระบุ ค่าคงที่สตริง และตัวดำเนินการเฉพาะภาษาถิ่น (PostgreSQL @>, คำนำหน้า BigQuery SAFE.) จะถูกรักษาไว้ตามเดิม

เครื่องมือนี้ตรวจสอบความถูกต้องของ SQL หรือไม่?

ไม่ ตัวจัดรูปแบบเป็นตัวเขียนใหม่เชิงคำศัพท์ ไม่ใช่ parser มันแบ่ง token จากข้อมูลนำเข้า ใช้กฎการจัดวาง และส่งออกผลลัพธ์ โดยไม่ตรวจสอบว่าคำสั่งถูกต้องตามความหมาย ตารางที่อ้างอิงมีอยู่จริง หรือไวยากรณ์ถูกต้องในภาษาถิ่นที่เลือก รันผลลัพธ์ที่จัดรูปแบบแล้วผ่านฐานข้อมูลจริง หรือ SQL linter เช่น SQLFluff สำหรับการตรวจสอบความถูกต้องจริง

ทำไมคีย์เวิร์ดของฉันถูกแปลงเป็นตัวพิมพ์ใหญ่?

เมนู dropdown ตัวพิมพ์คีย์เวิร์ดค่าเริ่มต้นเป็นตัวพิมพ์ใหญ่ ซึ่งเป็นแนวทางในคู่มือรูปแบบ SQL ที่เผยแพร่ส่วนใหญ่ (dbt Labs, Mode, GitLab) เปลี่ยนเป็น ตัวพิมพ์เล็ก หากทีมของคุณเขียน select / from ด้วยตัวพิมพ์เล็ก หรือ คงเดิม หากต้องการให้ผลลัพธ์คงการพิมพ์ที่คุณพิมพ์ไว้ ตัวระบุจะไม่ถูกกระทบ มีเพียงชุดคีย์เวิร์ดที่รู้จักเท่านั้นที่จะถูกเขียนใหม่

คำสั่งของฉันถูกอัปโหลดไปที่ไหนหรือไม่?

ไม่ ไลบรารี sql-formatter ที่รวมมาทำงานในเบราว์เซอร์ การจัดรูปแบบเกิดขึ้นในเครื่องของคุณ และข้อความคำสั่งไม่ผ่านเครือข่ายเลย คำขอขาออกเพียงอย่างเดียวที่หน้านี้ส่งคือคำขอการวิเคราะห์และโฆษณาที่ใช้ร่วมกันเช่นเดียวกับที่ทุกหน้าบน tools.ultim8soft.com ส่ง ตัวข้อความ SQL เองไม่เป็นส่วนหนึ่งของคำขอใด ๆ

SQL ที่พิมพ์สวยแล้วจะไม่กลายเป็นข้อถกเถียงเรื่องรูปแบบอีกเมื่อตัวจัดรูปแบบจัดการให้ เครื่องมือทำงานในเบราว์เซอร์ทั้งหมด คำสั่งไม่ออกจากหน้าเลย และ tokenizer ที่รู้จักภาษาถิ่นเดียวกับที่ขับเคลื่อนแพ็กเกจ npm sql-formatter จะดำเนินการเขียนใหม่