§

قالب‌بندی کوئری‌های SQL

گویش
تورفتگی
حالت کلمات کلیدی
شکست خط قبل از بند
§

کوئری SQL را پیست کنید

§

SQL قالب‌بندی‌شده

در تیم‌های داده‌مهندسی ایران که با پایگاه‌داده‌های PostgreSQL یا MySQL روی سرورهای داخلی یا سرویس‌های ابری ایرانی کار می‌کنند، قالب‌بندی یکدست SQL اختلاف‌های pull request را خوانا نگه می‌دارد. وقتی یک مهندس یک CTE ۲۰۰ خطی را دستی فرمت می‌کند و دیگری آن را به‌صورت یک خط پیست می‌کند، diff درهم می‌ریزد و تغییر واقعی منطق پنهان می‌شود. اجرای کوئری‌ها از طریق یک قالب‌بند ثابت پیش از کامیت، چرخه بازبینی را کوتاه می‌کند.

قالب‌بندی SQL چگونه کار می‌کند

قالب‌بندی SQL یک بازنویسی مبتنی بر تجزیه‌گر واژگانی است که هر توکن کوئری را پیموده و فضای سفید اطراف آن را بر اساس قوانین گویش انتخابی بازتولید می‌کند. معنای کوئری هرگز تغییر نمی‌کند، تنها چیدمان آن.

  1. انتخاب گویش. backtick های MySQL، تبدیل :: در PostgreSQL، مسیرهای جدول با نقطه در BigQuery، و شناسه‌های داخل کروشه در T-SQL هر کدام به یک توکن‌ساز آشنا با آن‌ها نیاز دارند. انتخابگر گویش مشخص می‌کند کدام دستور زبان اعمال شود.
  2. توکن‌سازی ورودی. قالب‌بند کوئری را به جریانی از توکن‌ها تقسیم می‌کند: کلمات کلیدی (SELECT، JOIN)، شناسه‌ها، مقادیر تحت‌اللفظی، عملگرها، پرانتزها و توضیحات. رشته‌های تحت‌اللفظی و شناسه‌های داخل نقل‌قول دست‌نخورده منتقل می‌شوند.
  3. اعمال قوانین چیدمان. بندهای سطح بالا (SELECT، FROM، WHERE، GROUP BY، ORDER BY) در خط مستقل شروع می‌شوند. عبارات جدا شده با کاما در لیست select و لیست ستون‌ها هر کدام خط مستقلی با تورفتگی واحد انتخابی دریافت می‌کنند.
  4. اعمال حالت کلمات کلیدی. کلید حالت کلمات کلیدی، کلمات کلیدی SQL شناخته‌شده را به بزرگ، کوچک یا همان حالت ورودی بازنویسی می‌کند. شناسه‌ها هرگز لمس نمی‌شوند — نام ستون‌ها و جداول همان‌طور که نوشته شده باقی می‌مانند.
  5. تولید رشته قالب‌بندی‌شده. جریان توکن‌ها با کاراکتر تورفتگی (۲ فاصله، ۴ فاصله یا tab) و قانون شکست خط پیکربندی‌شده به رشته واحدی متصل می‌شود. حالت زنده کل این فرآیند را با debounce 200 میلی‌ثانیه هنگام تایپ اجرا می‌کند.

چرا SQL را زیباسازی کنیم

  • خوانایی diff در pull request. یک CTE ۲۰۰ خطی که به یک خط تبدیل شده، بررسی کد را به یک حدس‌بازی تبدیل می‌کند. قالب‌بندی یکدست diff را به تغییر واقعی محدود می‌کند — یک ستون جدید، یک JOIN اضافه، یک شرط WHERE متفاوت — تا بازبینی‌کننده بدون درگیر شدن با فضای سفید آن را ببیند.
  • اشکال‌زدایی آسان‌تر. وقتی یک کوئری نتیجه اشتباه برمی‌گرداند، اولین کار خواندن خط به خط آن است. SQL قالب‌بندی‌شده هر JOIN را در خط مستقل قرار می‌دهد و شرط‌های WHERE را تراز می‌کند تا یک AND فراموش‌شده یا یک OR اشتباه در نگاه اول دیده شود.
  • سبک یکدست تیمی. اکثر تیم‌ها یک راهنمای سبک SQL دارند و می‌خواهند هر کوئری کامیت‌شده از آن پیروی کند. اجرای قالب‌بند پیش از کامیت، بحث سبک را از بازبینی حذف می‌کند و تنها منطق را برای بحث باقی می‌گذارد.
  • اشتراک‌گذاری SQL در مستندات. Runbook ها، گزارش‌های حادثه و مستندات Notion همه از SQL قابل‌خواندن بهره می‌برند. SQL قالب‌بندی‌شده به راحتی در یک بلوک کد تعبیه می‌شود و در خروجی PDF به شکل قابل پیش‌بینی چاپ می‌شود، بدون شکست‌های ناخوانده وسط کلمه کلیدی.

کاربردهای رایج

قالب‌بندی SQL در مهندسی تحلیل، توسعه backend و کارهای عملیاتی هر جا که یک کوئری باید توسط کسی که آن را ننوشته خوانده شود نمود پیدا می‌کند.

  • مهندسی تحلیل: hook قبل از کامیت در یک پروژه dbt که هر فایل مدل را قالب‌بندی می‌کند تا diff های PR به تغییرات منطقی محدود بمانند، نه تغییرات فضای سفید.
  • مدیریت پایگاه داده: یک ورودی slow-query log یک‌خطی را پیست کنید، قالب‌بندی کنید و هنگام نوشتن گزارش حادثه، ترتیب join ها را بررسی کنید.
  • مستندات: یک کوئری از یک explore در Looker یا یک workbook در Tableau بگیرید، آن را برای runbook قالب‌بندی کنید و به عنوان مثال copy-paste پذیر برای تیم 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، تورفتگی ۲ فاصله و حالت کلمات کلیدی بزرگ در پنل ورودی پیست کنید. خروجی SELECT، FROM، LEFT JOIN، WHERE، GROUP BY و ORDER BY را هر کدام در خط مستقل قرار می‌دهد؛ هر ستون در لیست select و لیست group-by خط مستقل تورفته دریافت می‌کند؛ و شرط ON یک تورفتگی عمیق‌تر از کلمه کلیدی JOIN مربوطه دارد. همان کوئری در گویش BigQuery خروجی یکسانی برای این مورد تولید می‌کند اما در صورت وجود شناسه‌های backtick-quoted آن‌ها را حفظ می‌کرد.

FAQ

کدام گویش‌های SQL پشتیبانی می‌شوند؟

منوی کشویی گویش شامل 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 @>، پیشوندهای SAFE. BigQuery) دست‌نخورده حفظ می‌شوند.

آیا این ابزار SQL مرا اعتبارسنجی می‌کند؟

خیر. قالب‌بند یک بازنویسی واژگانی است، نه یک تجزیه‌کننده. ورودی را توکن‌سازی می‌کند، قوانین چیدمان را اعمال می‌کند و نتیجه را تولید می‌کند؛ بررسی نمی‌کند که کوئری از نظر معنایی معتبر است، جداول مرجع وجود دارند یا نه، یا نحو برای گویش انتخابی مجاز است. برای بررسی صحت واقعی، خروجی قالب‌بندی‌شده را از طریق پایگاه داده واقعی (یا یک SQL linter مانند SQLFluff) اجرا کنید.

چرا کلمات کلیدی من بزرگ می‌شوند؟

منوی کشویی حالت کلمات کلیدی به طور پیش‌فرض روی بزرگ تنظیم شده که قرارداد اکثر راهنماهای سبک SQL منتشرشده است. اگر تیم شما select / from را با حروف کوچک می‌نویسد به lower تغییر دهید، یا Preserve را انتخاب کنید اگر می‌خواهید خروجی هر حالت‌نویسی که تایپ کردید را حفظ کند. شناسه‌ها هرگز تحت تاثیر قرار نمی‌گیرند — تنها مجموعه کلمات کلیدی شناخته‌شده بازنویسی می‌شود.

آیا کوئری من جایی آپلود می‌شود؟

خیر. کتابخانه sql-formatter داخلی در مرورگر شما اجرا می‌شود، قالب‌بندی به صورت محلی روی دستگاه شما انجام می‌شود و متن کوئری هرگز از شبکه عبور نمی‌کند. تنها درخواست‌های خروجی این صفحه همان درخواست‌های مشترک analytics و تبلیغات هستند که هر صفحه در tools.ultim8soft.com ارسال می‌کند؛ متن SQL خود بخشی از هیچ‌کدام نیست.

زیباسازی SQL وقتی یک قالب‌بند آن را مدیریت می‌کند دیگر بحث سبک نیست. این ابزار کاملاً در مرورگر شما اجرا می‌شود، کوئری هرگز صفحه را ترک نمی‌کند، و همان توکن‌ساز dialect-aware که بسته npm sql-formatter را تامین می‌کند بازنویسی را انجام می‌دهد.