Syntax | سینتکس
💡 چرا SQL اینقدر با بقیه زبانها متفاوت است؟ (روایتی از کتاب DDIA)
مدتی پیش در حال بازخوانی چپتر دوم کتاب معروف Designing Data-Intensive Applications اثر مارتین کلپمن بودم. کلپمن در این بخش، دست روی مقایسهای میگذارد که شاید بارها شنیده باشیم، اما زاویه دید او به این ماجرا در بستر «زبانهای کوئری دیتابیس»، دیدگاه من را نسبت به SQL کاملاً تغییر داد: پارادایم Imperative (امری) در برابر Declarative (توصیفی).
اگر برای شما هم سؤال است که چرا ساختار SQL اینقدر با زبانهای سنتی برنامهنویسی فرق دارد، این خلاصه و شهود کلیدی را از دست ندهید:
🔹 تفاوت اصلی در یک نگاه
زبانهای Imperative: به کامپیوتر دستور میدهند که یک عملیات را چگونه (How) و با چه ترتیبی در حافظه اجرا کند (مانند حلقهها و تغییر گامبهگام متغیرها).
زبانهای Declarative: صرفاً مشخص میکنند که نتیجه نهایی باید چه چیزی (What) باشد و قوانین حاکم بر داده چیست. جزئیاتِ چگونگی اجرا کاملاً پنهان است.
📜 ریشه تاریخی: از فاجعه تا انقلاب SQL
در دهه ۱۹۷۰ و پیش از ظهور SQL، در مدلهای دیتابیس قدیمیتر (مثل IMS و CODASYL)، برنامهنویسان مجبور بودند با کدهای Imperative و حلقههای متوالی، یک اشارهگر (Pointer) را به صورت دستی میان رکوردها حرکت دهند تا دادهای را پیدا کنند.
بزرگترین فاجعه چه بود؟ اگر ساختار فیزیکی دیتابیس روی دیسک تغییر میکرد (مثلاً یک ستون جابهجا میشد یا نحوه ذخیرهسازی عوض میشد)، تمام کدهای پروژه خراب میشدند و باید از اول بازنویسی میشدند!
اما SQL این مشکل را حل کرد. شما فقط میگویید چه دادهای میخواهید:
SELECT * FROM users WHERE age > 18;
با این کار، وظیفه نحوه اجرا به Query Optimizer (بهینهساز کوئری دیتابیس) واگذار شد. دیتابیس خودش تصمیم میگیرد که از کدام ایندکس یا الگوریتم (مثلاً Hash Join یا Merge Join) برای استخراج داده استفاده کند و برنامهنویس درگیر جزئیات سختافزار نمیشود.
📐 ربط زبانهای Declarative به جبر رابطهای (Relational Algebra)
زبان SQL بر پایهی یک نظریه ریاضی به نام «جبر رابطهای» بنا شده است. در ریاضیات دوران مدرسه، قوانینی وجود دارد که اجازه میدهد فرمولها را ساده کنیم بدون اینکه نتیجه تغییر کند؛ مثلاً:
(x+y)⋅z=x⋅z+y⋅z
ما در ریاضی فقط فرمول را مینویسیم و نگران نیستیم که پردازنده چطور ضرب را انجام میدهد. این قوانین جبری به Query Optimizer دیتابیس اجازه میدهد تا یک عبارت پیچیده و سنگین را پشت صحنه به یک عبارت ریاضی سادهتر و بهینهتر تبدیل کند.
🌐 یک مثال شهودی: دنیای بدون CSS را تصور کنید!
فرض کنید CSS وجود نداشت و میخواستید در یک لیست، پسزمینه آیتمهای انتخابشده (selected.) قرمز شود. در رویکرد امری (با JavaScript) باید یک حلقه بنویسید، تکتک المانها را چک کنید و رنگ بزنید. این کد شکننده است؛ اگر المان جدیدی بعداً به صفحه اضافه شود، قرمز نمیشود و باید حلقه را دوباره دستوری اجرا کنید. مرورگر هم نمیتواند این حلقه دستی را موازیسازی کند.
اما در دنیای Declarative (با CSS) مینویسید:
.selected { background-color: red; }
شما فقط وضعیت ایدهآل را توصیف میکنید. حالا اگر مرورگر آپدیت شود یا شتابدهنده گرافیکی (GPU) جدیدی بیاید، مرورگر خودش پشت صحنه نحوه اعمال این رنگ را بهینهسازی میکند، بدون اینکه نیاز باشد شما کدتان را دست بزنید.
🎯 ۳ مزیت کلیدی زبانهای توصیفی (Declarative) از زبان کلپمن:
1️⃣ استقلال داده (Data Independence): کد توصیفی به ساختار فیزیکی ذخیرهسازی داده وابسته نیست. میتوانید ایندکسها را تغییر دهید یا دیتابیس را بهینهسازی کنید، بدون اینکه کدهای برنامه شما آسیب ببینند.
2️⃣ پتانسیل بالای بهینهسازی: موتورهای زیرین (مثل دیتابیس یا انجین مرورگر) کنترل کاملی روی نحوه اجرا دارند، بنابراین میتوانند کد شما را به شدت بهینهتر از یک حلقه امریِ دستی اجرا کنند.
3️⃣ قابلیت موازیسازی (Parallelization): کدهای توصیفی به دلیل عدم تغییر مستقیم وضعیت (State)، به راحتی روی چندین هسته پردازنده یا چندین سرور پخش و موازی میشوند؛ اتفاقی که در کدهای امریِ دارای حلقه، فوقالعاده سخت و پر از Bug است.
📌 شما در پروژههای خودتون چقدر سعی میکنید منطق برنامهنویسی رو به سمت Declarative ببرین؟ تجربهای از چالشهای کدهای Imperative در دیتابیسهای قدیمی دارید؟ خوشحال میشم نظراتتون رو برام بنویسید.
📖 منبع: کتاب Designing Data-Intensive Applications (Chapter 2) - Martin Kleppmann
#software_engineering #database #sql #ddia #backend #system_design #programming
@Syntax_fa
26 · 1.9K ·