<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>پست‌های انتشارات حسین بیگی</title>
        <link>https://virgool.io/husseinbeygi/feed</link>
        <description>مجموعه مقالات حسین بیگی</description>
        <language>fa</language>
        <pubDate>2026-06-16 22:38:37</pubDate>
        <image>
            <url>https://files.virgool.io/</url>
            <title>حسین بیگی</title>
            <link>https://virgool.io/husseinbeygi</link>
        </image>

                    <item>
                <title>حکایت شیخ و مریدان : Bloom Filter</title>
                <link>https://virgool.io/husseinbeygi/%D8%AD%DA%A9%D8%A7%DB%8C%D8%AA-%D8%B4%DB%8C%D8%AE-%D9%88-%D9%85%D8%B1%DB%8C%D8%AF%D8%A7%D9%86-bloom-filter-h7hg6rp5fsao</link>
                <description>مریدی «تگری زنان» نزد شیخ برفت و گفت یا شیخ حالم دریاب که بغایت رسید. شیخ فرمود : مریدا تو را چه شده ؟مرید گفت : یا شیخ چندی پیش استارتاپی زدیم در خصوص حمل و نقل درون قلعه با چهارپایان که نامش را خوش رکاب گذاشته ایم!شیخ گفت : خب!؟؟نوش جان!چه شده که به ما رجوع کردی؟؟مرید گفت : در این استارت آپ ما در بخش ثبت نام به کاربران اجازه میدهیم نام کاربری را برای خود انتخاب کنند!و یک Index و محدودیتUNIQUE  هم زده ایم تنگش!حال که میزان ثبت نام روزانه ما زیاد شده، از آن رو هم مردم ما به پاس چشم و هم چشمی به مانند تاریخ زایمان به دنبال نام های عجیب و خاص هستند و در بیکاری خود نشسته و یکی یکی نام ها را امتحان میکنند که لاکچری ترینشان را برای خودشان بردارند!بگو خب!شیخ گفت : خب!مرید ادامه داد : حال این مرض مردم شهر برای ما دردسر شده!میزان IO دیتابیس بالا رفته و نرم افزار در حیاتی ترین جای خود کند عمل میکند!شیخ گفت : خب حذفش کن!مرید گفت : A/B تست کردیم 100 درصد نارضایتی خالص بدون حتی اندکی پالم!نمیشود!راه بده جان ما!شیخ دستی به ریش خود کشید و گفت چیزی برتو گویم که خود نیز صبح شنبه فهمیدم!برای این مشکل الگوریتمی طراحی شده به نام BloomFilterحال بنشین تا از برایش روی منبر بروم!به خاطر داشته باش که این الگوریتم بسی پیچیده و جای کار دارد و میتوان به میزان دلخواه آن را پیشرفته کرد.اما به صورت ساده که مطلب را بیان کند ادامه میدهم فکر کن مثلا همین &quot;کوپال&quot; خودمان میخواهد در خوش رکاب ثبت نام کند!در مرحله اول نام شخص را هش کن!بعد باقیمانده آن را بر عددی بدست آور (مثلا 64) و تو عددی خواهی یافت بین 0 تا 63 و آن را در RAM یا Redis ذخیره کن!یا مثلا بیتی را یک کن!نمیدانم روشش با خودت!سری بعد اگر شفتالو خانم آمد برای ثبت نام بعد از اجرای دستور بالا برو و در Redis نگاه کن و ببین آیا این عدد ثبت شده!یا یک شده است!اگر نبود که 100 درصد مطمئن باش که درست است و برو ثبت نام کن!اگر بود حال دو راه می باشد!که یا ثبت نام شده و یا نشده، چرا چونکه شاید روزی نامی بعد از هش کردن و باقیمانده گرفتن عددش با یکی دیگر از نام های قبلی یکی شودو وقتی به Redis رجوع میکنی میبینی که هست! از این رو یا تو تصمیم میگیری که بروی و در دیتابیس هم چک کنی!و یا نه!برایتان صرفه ندارد و به شخص میگویی نامی دیگر انتخاب کن!خط القرآن که نیست!این روش در بسیاری از سیستم های بزرگ استفاده میشود که در کل باعث کاهش IO به دیتابیس و کاهش هزینه میشود! برای مثال همین جیمیل مثلا اگر دقت کرده باشی بروی و نام &quot;دست دراز 886&quot; را بزنی میگوید این نام ثبت شده میخواهی &quot;دراز دست 889&quot; را امتحان کنی!؟خدا خیر داده اصلا حسش ندارد که به دیتابیس برود.البته تصمیم استفاده از این روش با طراح سیستم است!بعد از این سخن، مرید نعره‌ زد و خشتک درید و لپ‌ تاپ‌ خود را به زمین کوبید فغان کشان به کشتی مروارید سیاه پناه برد!!</description>
                <category>حسین بیگی</category>
                <author>حسین بیگی</author>
                <pubDate>Wed, 18 May 2022 23:33:50 +0430</pubDate>
            </item>
                    <item>
                <title>داستان Stored Procedure و گوربه</title>
                <link>https://virgool.io/husseinbeygi/%D8%AF%D8%A7%D8%B3%D8%AA%D8%A7%D9%86-stored-procedure-%D9%88-%DA%AF%D9%88%D8%B1%D8%A8%D9%87-vxyvyee2zbul</link>
                <description>خایله خبدر دنیایی که همه از این ORM  قشنگا استفاده میکنن، شما اونی باش که Stored Procedure مینویسه!واستا یک دقه!!فوش نده! بزار بگمما توی علم کامپیوتر یک مفهومی داریم به اسم IO که همه میدونیم چیه!آفرین(اینجا) همون هارد و فضای ذخیره سازی و اگه تحت شبکه باشه اون TCP  که همه باهم دست به دست هم دادن به مهر که کوئری مارو کنن آباد، هستش(خرده نگیر مهندس میدونم زیاد تر از این حرفاس).استفاده از این IO خیلی گرونه( از ماکارونی هم گرونه تره!) در حدی که هر رفت و برگشت به DB یک گوربه میمیره!پس بیایم گوربه ها رو با کم کردن استفاده از IO نجات بدیم.بله!حالا یک مثالی بزنم برات که کیف کنی!شما در نظر بگیر ما یک جدولی داریم مثلا کاربر ها توی اونن بعد یک جدول دیگه داریم که مثلا عکس ها توی اونن یک جدول دیگه داریم که قراره این داده ها رو توی اون ذخیره کنیم در حالت غیر یک پارچه و اینکه شما از سی شارپ و DBContext که داری بیای اینو هندل کنیاولش با Linq  زیبا یک کوئری میزنی و داده هایی که میخوای رو از جدول کاربر ها میگیری!(رفت و برگشت)تازه ما در نظر میگیریم که شما حواست بوده و به جایIEnumerable  از IQueryable استفاده کردی Jبعد در خط بعدی میای دوباره یک رفت برگشت دیگه میکنی و داده هایی که از عکس ها میخوای میگیری!حالا همه اینا رو با یک رفت و برگشت دیگه اضافه میکنی به جدول سوم!سه تا گوربه مرد!سه بار رفتی و برگشتی به DB بدبخت بیچاره!اونم که صداش در نمیاد!حالا در نظر بگیر یک SP بنویسی که یک رفت برگشت میزنی و فقط به دیتا بیس میگی که اون قضیه بود که بهت گفته بودم ! دمت گرم اجراش کن! دیتا بیس هم که از قبل میدونه چی کار میخواد بکنه به راحتی اجرا میکنه!در این حالت ما یک گوربه تلفات میدیم!به جای سه گوربه!پس سریع تره!حال همین خودش هم داستان داره که سریع تر بشه!ولی خب از همون حالت قبلی بهتره!اونایی که در خط SP نیستن و خون گوربه ها رو پایه مال میکنن! هم میتونن یک Profiler باز کنن و ببین چه غوغایی اون پشته!اگه Profiler نداری ! توی EF بیا لاگ مربوط به کوئری های تولید شده رو فعال کن که برات لاگ بگیره ! همه شلم شوربا رو نشون نمیده ولی خب خالی از لطف نیست!</description>
                <category>حسین بیگی</category>
                <author>حسین بیگی</author>
                <pubDate>Mon, 16 May 2022 21:35:31 +0430</pubDate>
            </item>
                    <item>
                <title>حکایت شیخ و مریدان : انتخاب GUID برای کلید اصلی</title>
                <link>https://virgool.io/husseinbeygi/%D8%AD%DA%A9%D8%A7%DB%8C%D8%AA-%D8%B4%DB%8C%D8%AE-%D9%88-%D9%85%D8%B1%DB%8C%D8%AF%D8%A7%D9%86-%D8%A7%D9%86%D8%AA%D8%AE%D8%A7%D8%A8-guid-%D8%A8%D8%B1%D8%A7%DB%8C-%DA%A9%D9%84%DB%8C%D8%AF-%D8%A7%D8%B5%D9%84%DB%8C-l0of35k8b2fa</link>
                <description>روزی شیخ در سایه­­ی درختی در انتهای دهاتشان نشسته بود و از آرامش و صدای کلاغان لذت میبرد که ناگهان مریدی بر وی نازل گشت و به صورت آتش به اختیار وی را تکان های نامردانه­ای داد و گفت:یا شیخ.مسئلتون ؟شیخ که هنوز در ریکاوری از آن حرکت عجیب مرید بود گفت:-مسئلتون و درد، مردک نمی بینی در حال لذت بردنم؟؟؟ حال بگو ببینم چه شده؟مرید گفت : ای شیخ آیا استفاده از GUID برای کلید اصلی(Primary Key)  جایز است؟؟؟شیخ گفت : خیر!بدان و آگاه باش ای بشر که این کار جز درد و بدبختی برای DB ندارد!!مرید که سخت قفل کرده بود گفت: واااااااااات؟؟؟برای چه؟؟؟شیخ گفت : زمانی که شما جدول را میسازی عموما دو مسئله وجود دارد که معمولا با هم گرفته میشوند یکی کلید اصلی (Primary Key) و دیگری Clusterd Index!مرید که قیافه­اش به میزان کافی گیج شده بودن را نشان میداد، استثنا هیچ نگفت و شیخ ادامه داد:بله!وقتی میای میگی این ستون Id مرا Primary Key  بکن بانک اطلاعاتی به صورت پیش فرض یک Clustered Index نیز برای آن می­سازد!خب این Primary Key  را که همه میدانیم یعنی چه!تکراری نباشد!NULL نباشد!و از این حرفها، اما بحث اصلی روی Clustered Index می باشد!تاحالا فکر کردی که این Clustered Index چه میکنه؟؟؟اصلا فرقش با Non-Clustered Index چیه؟؟؟چرا فقط یکی ازش میسازن؟؟؟و دیگه نمیشه ازش ساخت!(توی جدول هاااا)مرید گفت:خیر شیخ!اصلا تاکنون نفکریده بودم! شما که غریبه نیستی اصلا نمیدونستم اینا جدان!شیخ ادامه داد: زمانی که Clustered Index میسازیم، جدول ما به صورت خودکار و زمان ورود داده بر اساس این Clustered Index مرتب میشود!یعنی اگر شما Clustered Index را یک ستون نرمال عددی در نظر بگیری اگر ابتدا ID 3 را وارد کنی و بعد ID 2 را وارد کنی، ردیف دومی که اضافه بشه میره قبل ردیف اول میشینه!(که حالا این خودش چجوری این کار میکنه بسته به دیتابیس روش کارش متفاوته که خارج از حوصله این روضه هایی هستش که میخونم!)حالا اگه شما بیای این ستون رو Identity قرار بدی عالی میشه یعنی دیگه هزینه جابه جایی هم نمیدی!و پیج های داده هات مرتب هستن(یکم توی پست IO در این خصوص رفتم روی منبر!)حالا چه فایده داره!وقتی میگی من فلان داده رو میخوام، دیتابیس ما باهوشه و بلده چجوری سریع بره سراغش(رجوع شود به ساختمان داده بخش B-Tree ( اگه از GUID استفاده کنی عملا گند زدی به این مرتب سازی!چون تصادفی هستش دیتابیس دردسر زیادی داره که مرتب سازی کنه! آره اینجوریاس!مرید گفت : یا شیخ!ملتفت فرمودی!اما شرایطی هستش که نمیشه Identity استفاده کرد مثلا Id یک جدول بسته به تراکنش جداول دیگه هستش و بسیار هم دردسر ساز.امکان داره در دو تراکنش ایزوله ما یکهو دوتا Id یکسان تولید کنیم!و هزاران خطاهای ارزنده دیگر!حال چه کنیم؟؟؟شیخ گفت:بدان و آگاه باش که میتوانی از Sequential Table ها استفاده کنید خب!مرید گفت : شیخ جواب نمی­دهد به مولا!!شیخ گفت :ای بابا تو هم گیری هاااااا!دو تا ستون تعریف کن یکی رو عددی بزار Clustered Index را روی آن و دیگری را GUID کن Primary Key را روی آن!هرچه باشد از اینکه هردو یکی باشد بهتر است!مرید که کف کرده بود، خشتک درید و به سر بر کوه های آلپ نهاد!</description>
                <category>حسین بیگی</category>
                <author>حسین بیگی</author>
                <pubDate>Mon, 16 May 2022 21:33:41 +0430</pubDate>
            </item>
                    <item>
                <title>ACID  چیست؟</title>
                <link>https://virgool.io/husseinbeygi/hb-acid-zai271c3iw4c</link>
                <description>1.Atomictyرک پوست کنده بگم یعنی یا تمام دستورات اجرا میشن یا نمیشن!یکمش بشه ، نصفش بشه ، باباش نذاشت که اجرا بشه، رفت دید اندازش نیست و اینا نداریم.یا همش یا هیچیش!2.Consistencyدر این بحث ما دوتا مورد داریم ، یکی Data Consistency یکی هم Read Consistency خب اینا یعنی چی؟؟؟؟Data Consistencyشما نگا کنن این مورد رو خود کاربر تعیین میکنه مثلا در دیتا بیس های Relational  ما از کلید های خارجی استفاده میکنیم که رو هوا داده وارد نشه!یکم منطق و دلیل پشتش باشه.البته اگه بررسی کنید متوجه میشید که این بخش Atomicty بی ربط به اینجا نیست!چرا؟چون شما فکر کن یک پولی انتقال میدی، بعد دیتا بیس (حالا به هر دلیلی) کرش میکنه ! الله اکبر پوله کجا رفت ! اگه Atomicty نبود که رفت هوا ولی چون هست!برمیگرده سرجاش!حالا اگه شما نگاه کنین اگه نبود که Data Consistency خراب میشد!حالا مثال ! فکر کن یک جدول داری که توش لایک ها رو  مثلا همین لینکدین! ذخیره میکنی ! بعد میبینی که اگه لایک ها زیادبشه اون موقع معنی نمیده که بری توی جدول لایک هات کوئری بزنی تعداد بگیری! یک فیلد توی جدول پست ها اضافه می کنی که سیستم هر ازگاهی میره با صله رحم به جدول لایک پست ها یک کوئری میگیره و تعداد رو توی این فیلد میزاره!بعدا که خواستی میخونیش!چرا چون سریع تره!حالا اگه پست بیانسه! موقع نمایش لایک هاش به جای 12503 لایک بگی که 12K لایک خورده ! زمین به اسمون میاد!؟ نه!پس همین کارو میکنی ! اما اگه برنامه موجودی حسابه و انتقال پول دیگه از این خبرا نیست و طراحیش سخت تره!اصلا یک علتی هم که مردم میان  Delete Cascade میزارن توی بانک ها همینه!شما فکر کن یک پستی حذف بشه! بعد رکورد هایی که لایک ها رو نگه میداشته، نشه!چی بشه! کی جمع کنه اون همه داده یتیم رو!Read Consistencyاین بحث خیلی بزرگه! ولی خب چون امروزه همه یاد گرفتن که برن سراغ میکروسرویس ها ( مونولوتیک دور نندازین، انقدر ها هم بدرد نخور نیست!)و بعدش بیان با یک CQRS  به لطف کتابخانه های متعدد، Read رو بدن به  این دیتابیس قشنگا مثل ردیس و Write  و رو بدن به مثلا SQL Server   حالا داستان اینه که در سیستم های خیلی خیلی بزرگ زمان میبره که ردیس بدبخت با این بانک اصلی هماهنگ بشه!این یکی از مسائلی قابل مثال برای Read Consistency هستش! که یک بحث جالبی پیش اومده به اسم eventual Consistency  که یعنی دیر و زود داره ولی سوخت سوز نداره! بالاخره اینا باهم هماهنگ میشن!( یک مطلب کامل برای همین خواهم نوشت!)یعنی بالاخره آقا در سیستم های خیلی بزرگ گاهی پیش میاد که ما داده ای رو ذخیره کنیم و زمانی طول بکشه هرچند کوتاه) این داده هماهنگ بشن!خب!3.Isolationاگه یک Transaction اجرا بشه چهار اتفاق میتونه بی افته1- داده بخونی که  امکان داره اصلا کامیت نشده باشه!یا ابالفضل!(Dirty Read)2- داده بخونی! کامیت باشه ها!اما توی لیست رکورد های خروجی نباشه!دوباره مجبوری کوئری بگیری(non-repeatable Read)  مثال بزنم ! فکر کن داری جمع خرید های امروز رو میگیری به همراه لیستشون و قبل اینکه برسی به دستور SELECT آخر که مال خروجی گرفتن هستش، یک بنی بشری میاد تعداد خرید هارو آپدیت میکنه(مثلا دستی توسط صندوق دار) شما 12 تا آیتم داری که دستی حساب میکنی جمعش میشه 1200 تومن ، بعد اومدی SUM که توی دیتابیس گرفتی رو نگاه میکنی میبینی نوشته 1000 تومن یعنی چی؟ یعنی دارای non-repeatable Read شدی ! مجبوری دوباره گزارش بگیری.3- قبلیه با یک لاک کردن ردیف یا ستون یا جدول یا... قابل حل هستش ! نمیزاری که آپدیت کنن!ولی اگه یکی جدید اضافه کردن چی؟جمع دستی کالا ها که تعدادش 12 تا هستش شده 1200 تومن ولی جمع سیستمی میگه 1400 تومن! اون یکی کو؟؟؟؟اضافه شده ولی توی لیست نیست!(phantom Read)4- شما فکر کن یک ردیفی رو  میخوای اپدیت کنی!و transaction رو اجرا میکنی!هم زمان یک بنی بشر دیگه ای هم داره روی همون داده همین کارو میکنه!شما دکمه ذخیره رو میزنی میبینی یک چیز دیگه آپدیت شده!(یا بالعکس) به این مسئله میگن  (lost Update)برای روضه هایی که بالا خوندم اومدن راه هایی در نظر گرفتن که این بسته به حساسیت داده به روش های مختلف جبران میشه!1-Read uncommitted یعنی آقا هیچ کاری نکن اصلا اگه حتی داده کامیت نشده بود هم بخون!(تمام تراکنش ها از هم خبر دارن و روی هم تاثیر میزارن حتی اونایی که امکان داره وسط راه  Roleback بشن!و شماDirty Read رو داری! )2-Read Commited تراکنش ها فقط تغییرات کامیت شده رو میبینن! Dirty Readحل شده اینجا!3-Repeatable Read اینجا دیتابیس مطمئن میشه که وسط راه کسی به دیتا کُخ نریزه(مشهدی هستش یعنی تغییر نده) حالا چجوری مثلا با لاک کردن داده(خودش یک درس سه واحدیه!)4-SnapShot یعنی شما فکر کن در زمان شروع تراکنش یکی عکس از دیتابیس میگیره و با همون داده ها کار میکنه!مشکل ها همه حل میشه!5-Serializable  این دیگه معرکس! اصلا همزمانی وجود نداره! همه تراکنش ها پشت سر هم اجرا میشن!اینجا هم حل میشه!حالا این داستان هارو هر دیتابیسی یک جور کنترل میکنه!اره خلاصه!مثال Postgres  میاد Repeatable Read رو مثل snapshot هندل میکنه!حالا این یعنی چی؟؟یعنی اگه من یک داده ای رو ذخیره کردم و سیستم رو خاموش کردم، بعدش که اومدم سراغش بهتره سرجاش باشه ! همه دیتابیس ها این کار نمیکنن مثلا ردیس(البته می کنه ها شما باید براش تنظیم کنی) این خودشم سه روش داره که باشه بعدا یکی یکی مطلب میزارم براش!</description>
                <category>حسین بیگی</category>
                <author>حسین بیگی</author>
                <pubDate>Sat, 14 May 2022 22:03:19 +0430</pubDate>
            </item>
            </channel>
</rss>