💎 اصول Normalization در طراحی دیتابیس 💎
امروز میخوام در مورد یکی از مهمترین اصول طراحی دیتابیس یعنی "نرمالسازی" صحبت کنم. اگه میخواین دیتابیستون پر سرعت و بدون مشکل کار کنه، باید با این سه فرم اصلی نرمالسازی آشنا بشین.
1⃣ فرم اول نرمال (1NF)
تو فرم اول نرمال، باید همهی ستونهای دیتابیستون "اتمی" باشن. یعنی هر سلول از جدول باید فقط یه مقدار داشته باشه، نه چندتا مقدار!
📌 مثال:
فرض کن یه جدول داری که توش شماره تلفنهای چند نفر رو ذخیره کردی. اگه تو یه سلول چند تا شماره تلفن ذخیره کنی، دیتابیست تو فرم اول نرمال نیست باید هر شماره تلفن توی یه ردیف جدا باشه.
2⃣ فرم دوم نرمال (2NF)
وقتی فرم اول رو رعایت کردی، میرسی به فرم دوم. تو این فرم، باید مطمئن بشی که همهی ستونهای غیرکلیدی، وابسته به کلید اصلی (Primary Key) باشن.
📌 مثال:
فرض کن یه جدول داری که اطلاعات دانشآموزان و درسهایی که میخونن رو ذخیره میکنه. اگه یه ستون مربوط به اطلاعات کلاس (مثل شماره کلاس) باشه که وابسته به دانشآموز نباشه، دیتابیست تو فرم دوم نرمال نیست. باید اون اطلاعات رو تو یه جدول جدا ذخیره کنی.
3⃣ فرم سوم نرمال (3NF)
حالا که فرم دوم رو رعایت کردی، میرسیم به فرم سوم. اینجا باید مطمئن بشی که هیچ ستون غیرکلیدی به یه ستون غیرکلیدی دیگه وابسته نباشه
📌 مثال:
اگه تو جدول دانشآموزان، هم اسم شهر و هم اسم استان رو ذخیره کنی و استان وابسته به شهر باشه، دیتابیس تو فرم سوم نرمال نیست. باید شهر و استان رو تو یه جدول دیگه ذخیره کنی.
جمع بندی 🎯
این سه فرم نرمالسازی باعث میشن دیتابیستون بهینهتر باشه، خطاهای کمتری داشته باشه و به راحتی قابل توسعه باشه. پس اگه میخواین دیتابیستون تو پروژههای بزرگ دچار مشکل نشه، حتما این اصول رو رعایت کنین 😉
امید وارم مفید بوده باشه :)
@ninja_learn_ir
امروز میخوام در مورد یکی از مهمترین اصول طراحی دیتابیس یعنی "نرمالسازی" صحبت کنم. اگه میخواین دیتابیستون پر سرعت و بدون مشکل کار کنه، باید با این سه فرم اصلی نرمالسازی آشنا بشین.
1⃣ فرم اول نرمال (1NF)
تو فرم اول نرمال، باید همهی ستونهای دیتابیستون "اتمی" باشن. یعنی هر سلول از جدول باید فقط یه مقدار داشته باشه، نه چندتا مقدار!
📌 مثال:
فرض کن یه جدول داری که توش شماره تلفنهای چند نفر رو ذخیره کردی. اگه تو یه سلول چند تا شماره تلفن ذخیره کنی، دیتابیست تو فرم اول نرمال نیست باید هر شماره تلفن توی یه ردیف جدا باشه.
2⃣ فرم دوم نرمال (2NF)
وقتی فرم اول رو رعایت کردی، میرسی به فرم دوم. تو این فرم، باید مطمئن بشی که همهی ستونهای غیرکلیدی، وابسته به کلید اصلی (Primary Key) باشن.
📌 مثال:
فرض کن یه جدول داری که اطلاعات دانشآموزان و درسهایی که میخونن رو ذخیره میکنه. اگه یه ستون مربوط به اطلاعات کلاس (مثل شماره کلاس) باشه که وابسته به دانشآموز نباشه، دیتابیست تو فرم دوم نرمال نیست. باید اون اطلاعات رو تو یه جدول جدا ذخیره کنی.
3⃣ فرم سوم نرمال (3NF)
حالا که فرم دوم رو رعایت کردی، میرسیم به فرم سوم. اینجا باید مطمئن بشی که هیچ ستون غیرکلیدی به یه ستون غیرکلیدی دیگه وابسته نباشه
📌 مثال:
اگه تو جدول دانشآموزان، هم اسم شهر و هم اسم استان رو ذخیره کنی و استان وابسته به شهر باشه، دیتابیس تو فرم سوم نرمال نیست. باید شهر و استان رو تو یه جدول دیگه ذخیره کنی.
جمع بندی 🎯
این سه فرم نرمالسازی باعث میشن دیتابیستون بهینهتر باشه، خطاهای کمتری داشته باشه و به راحتی قابل توسعه باشه. پس اگه میخواین دیتابیستون تو پروژههای بزرگ دچار مشکل نشه، حتما این اصول رو رعایت کنین 😉
#sql #database #db #nf
👍11❤1
💎 چطوری مشکلات Dirty Read، Non-Repeatable Read، Phantom Read و Deadlock رو هندل کنیم؟ 💎
توی پست قبلی درباره چند تا مشکل مثل Dirty Read، Non-Repeatable Read، Phantom Read و Deadlock حرف زدیم. امروز میخوایم ببینیم چطوری میتونیم اینا رو توی برنامهمون هندل کنیم. اینا مشکلاتیه که میتونن عملکرد دیتابیس و اپلیکیشن رو خراب کنن، ولی با استفاده از تکنیکهای کنترل همزمانی و ایزولیشن میشه جلوی اینا رو گرفت.
1⃣ Dirty Read 💾
برای جلوگیری از Dirty Read، باید از سطح ایزولیشن مناسبی استفاده کنیم. یکی از بهترین سطوح ایزولیشن برای این کار Read Committed هست. این سطح تضمین میکنه که فقط دادههای commit شده قابل خوندن هستن.
مثال:
فرض کن توی دیتابیستون از سطح ایزولیشن Read Committed استفاده میکنی. اگه تراکنش A داره دادههایی رو آپدیت میکنه، تراکنش B تا وقتی که A کارش تموم نشده و دادهها رو commit نکرده، نمیتونه اون دادهها رو ببینه. پس از Dirty Read جلوگیری میشه.
2⃣ Non-Repeatable Read 🔄
برای جلوگیری از Non-Repeatable Read، باید سطح ایزولیشن رو به Repeatable Read تغییر بدیم. این سطح ایزولیشن تضمین میکنه که اگر یک بار دادهای رو توی تراکنش خوندیم، تا پایان تراکنش دیگه تغییر نمیکنه.
مثال:
فرض کن توی یه فروشگاه آنلاین، وقتی یه کاربر قیمت یه محصول رو چک میکنه، باید مطمئن بشی که اون قیمت تا پایان تراکنش تغییر نمیکنه. با استفاده از Repeatable Read، هر چی کاربر دید، همون میمونه.
3⃣ Phantom Read 👻
برای حل مشکل Phantom Read باید از سطح ایزولیشن Serializable استفاده کنیم. این سطح از ایزولیشن باعث میشه که نه تنها دادههای موجود، بلکه هر داده جدیدی هم تا پایان تراکنش دیده نشه.
مثال:
فرض کن یه مدیر داره گزارش تعداد کارمندای یه بخش رو چک میکنه. با سطح ایزولیشن Serializable، اگر کارمند جدیدی در طول تراکنش اضافه بشه، مدیر اون رو تا پایان تراکنش نمیبینه و از Phantom Read جلوگیری میشه.
4⃣ Deadlock 🔐
برای هندل کردن Deadlock، چند راه وجود داره:
1⃣ اجتناب از قفلهای طولانی:
تراکنشها رو سبک و سریع نگه دار تا قفلهای طولانی ایجاد نشن.
2⃣ ترتیب دسترسی یکسان:
مطمئن شو که تراکنشها به منابع به یه ترتیب دسترسی پیدا میکنن. یعنی اگر A و B هر دو به رکوردهای ۱ و ۲ نیاز دارن، هر دو اول رکورد ۱ رو قفل کنن و بعد برن سراغ رکورد ۲.
3⃣ زمانبندی دوباره تراکنشها:
میتونی از دیتابیس بخوای که اگه Deadlock تشخیص داد، یکی از تراکنشها رو ریست کنه و دوباره اجرا کنه.
مثال:
فرض کن توی اپلیکیشن مالیات دو تراکنش همزمان دارن از منابع یکسان استفاده میکنن. یکی از راههای جلوگیری از Deadlock اینه که مطمئن بشی تراکنشها به یه ترتیب مشخص به منابع دسترسی دارن، مثلاً اول رکورد ۱ رو قفل میگیرن و بعد رکورد ۲.
جمعبندی 🎯
با استفاده از سطوح ایزولیشن و یه سری تکنیکهای مدیریت تراکنش، میتونیم مشکلاتی مثل Dirty Read، Non-Repeatable Read، Phantom Read و Deadlock رو توی دیتابیسهامون حل کنیم. اگر این نکات رو توی اپلیکیشنهاتون رعایت کنید، کارتون خیلی راحتتر و پایدارتر میشه.
امید وارم مفید بوده باشه :)
@ninja_learn_ir
توی پست قبلی درباره چند تا مشکل مثل Dirty Read، Non-Repeatable Read، Phantom Read و Deadlock حرف زدیم. امروز میخوایم ببینیم چطوری میتونیم اینا رو توی برنامهمون هندل کنیم. اینا مشکلاتیه که میتونن عملکرد دیتابیس و اپلیکیشن رو خراب کنن، ولی با استفاده از تکنیکهای کنترل همزمانی و ایزولیشن میشه جلوی اینا رو گرفت.
1⃣ Dirty Read 💾
برای جلوگیری از Dirty Read، باید از سطح ایزولیشن مناسبی استفاده کنیم. یکی از بهترین سطوح ایزولیشن برای این کار Read Committed هست. این سطح تضمین میکنه که فقط دادههای commit شده قابل خوندن هستن.
مثال:
فرض کن توی دیتابیستون از سطح ایزولیشن Read Committed استفاده میکنی. اگه تراکنش A داره دادههایی رو آپدیت میکنه، تراکنش B تا وقتی که A کارش تموم نشده و دادهها رو commit نکرده، نمیتونه اون دادهها رو ببینه. پس از Dirty Read جلوگیری میشه.
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
2⃣ Non-Repeatable Read 🔄
برای جلوگیری از Non-Repeatable Read، باید سطح ایزولیشن رو به Repeatable Read تغییر بدیم. این سطح ایزولیشن تضمین میکنه که اگر یک بار دادهای رو توی تراکنش خوندیم، تا پایان تراکنش دیگه تغییر نمیکنه.
مثال:
فرض کن توی یه فروشگاه آنلاین، وقتی یه کاربر قیمت یه محصول رو چک میکنه، باید مطمئن بشی که اون قیمت تا پایان تراکنش تغییر نمیکنه. با استفاده از Repeatable Read، هر چی کاربر دید، همون میمونه.
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
3⃣ Phantom Read 👻
برای حل مشکل Phantom Read باید از سطح ایزولیشن Serializable استفاده کنیم. این سطح از ایزولیشن باعث میشه که نه تنها دادههای موجود، بلکه هر داده جدیدی هم تا پایان تراکنش دیده نشه.
مثال:
فرض کن یه مدیر داره گزارش تعداد کارمندای یه بخش رو چک میکنه. با سطح ایزولیشن Serializable، اگر کارمند جدیدی در طول تراکنش اضافه بشه، مدیر اون رو تا پایان تراکنش نمیبینه و از Phantom Read جلوگیری میشه.
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
4⃣ Deadlock 🔐
برای هندل کردن Deadlock، چند راه وجود داره:
1⃣ اجتناب از قفلهای طولانی:
تراکنشها رو سبک و سریع نگه دار تا قفلهای طولانی ایجاد نشن.
2⃣ ترتیب دسترسی یکسان:
مطمئن شو که تراکنشها به منابع به یه ترتیب دسترسی پیدا میکنن. یعنی اگر A و B هر دو به رکوردهای ۱ و ۲ نیاز دارن، هر دو اول رکورد ۱ رو قفل کنن و بعد برن سراغ رکورد ۲.
3⃣ زمانبندی دوباره تراکنشها:
میتونی از دیتابیس بخوای که اگه Deadlock تشخیص داد، یکی از تراکنشها رو ریست کنه و دوباره اجرا کنه.
مثال:
فرض کن توی اپلیکیشن مالیات دو تراکنش همزمان دارن از منابع یکسان استفاده میکنن. یکی از راههای جلوگیری از Deadlock اینه که مطمئن بشی تراکنشها به یه ترتیب مشخص به منابع دسترسی دارن، مثلاً اول رکورد ۱ رو قفل میگیرن و بعد رکورد ۲.
BEGIN TRANSACTION;
-- Lock resources in the same order
جمعبندی 🎯
با استفاده از سطوح ایزولیشن و یه سری تکنیکهای مدیریت تراکنش، میتونیم مشکلاتی مثل Dirty Read، Non-Repeatable Read، Phantom Read و Deadlock رو توی دیتابیسهامون حل کنیم. اگر این نکات رو توی اپلیکیشنهاتون رعایت کنید، کارتون خیلی راحتتر و پایدارتر میشه.
#sql #dead_lock #programing
🔥12❤4👍1
خب خب خب ORM چیه ؟ 🛸
امروز میخوام دربارهی یه موضوع مهم و کاربردی تو دنیای برنامهنویسی حرف بزنم: ORM یا همون Object-Relational Mapping.
🧠 ORM یعنی چی؟
ORM (Object-Relational Mapping) یه تکنیک تو برنامهنویسیه که دادههای دیتابیس رو به شکل اشیاء (objects) تو زبونهای شیگرا مثل پایتون، جاوا یا سیشارپ مدیریت میکنه. به بیان ساده، ORM یه پل ارتباطی بین دنیای شیگرایی (کلاسها و اشیاء) و دنیای دیتابیسهای رابطهای (جداول و ستونها) میسازه. با ORM دیگه لازم نیست مستقیم با کوئریهای SQL کار کنی؛ در عوض، با همون زبون برنامهنویسیات دیتابیس رو کنترل میکنی.
مثلاً به جای اینکه بنویسی:
میتونی تو پایتون با Django ORM اینجوری بنویسی:
و همون نتیجه رو بگیری
📚 ORM چطوری کار میکنه؟
فرض کن تو دیتابیست یه جدول به اسم
تو برنامهات یه کلاس به اسم
چند تا سناریو رو با هم ببینیم:
1⃣ ذخیره کردن داده:
یه شیء از کلاس
2⃣ خوندن داده:
میتونی به جای کوئری SQL، از متدهایی مثل
به همین سادگی ORM تمام پیچیدگیهای کار با دیتابیس رو از دید تو مخفی میکنه و یه رابط کاربری راحت بهت میده.
قبل از اینکه ORMها باشن، برنامهنویسها مستقیم با SQL کار میکردن. (هرچند همین الانشم توی زبان های هایی که orm مناسبی براش ساخته نشده برنامه نویسان بصورت خام کد sql میزنن مثل برنامه نویسان golang)
این چند تا مشکل داشت و داره:
کدهای طولانی:
برای هر عملیات ساده، باید یه کوئری SQL مینوشتی که گاهی خیلی پیچیده میشد.
خطای زیاد:
یه اشتباه کوچیک تو کوئری (مثل یه typo) میتونست ساعتها وقتت رو تلف کنه.
سختی نگهداری:
اگه ساختار دیتابیست عوض میشد (مثلاً یه ستون اضافه یا کم میشد)، باید همه کوئریها رو دستی تغییر میدادی.
تفاوت پارادایم:
SQL یه زبون declarative (اعلانی) هست، ولی زبونهایی مثل پایتون imperative (دستوری) هستن. این یعنی برنامهنویس باید مدام بین دو مدل فکری جابهجا میشد.
ORM اومد که این مشکلات رو حل کنه:
سادگی:
کار با دیتابیس مثل کار با اشیاء تو زبون خودت میشه.
امنیت:
ORMها معمولاً جلوی حملاتی مثل SQL Injection رو میگیرن.
انعطافپذیری:
میتونی دیتابیس رو عوض کنی (مثلاً از MySQL بری به PostgreSQL) بدون اینکه کل کدت رو تغییر بدی.
سرعت توسعه:
چون کوئرینویسی کمتر میشه، وقت بیشتری برای منطق اصلی برنامهات داری.
جمعبندی ✍
ORM یه ابزار باحال و قدرتمنده که کار با دیتابیس رو برای برنامهنویسها راحتتر، سریعتر و امنتر میکنه. با ORM دیگه لازم نیست با SQL خام کلنجار بری و میتونی با همون زبون برنامهنویسیات همهچیز رو مدیریت کنی.
➖➖➖➖➖➖➖➖➖
امروز میخوام دربارهی یه موضوع مهم و کاربردی تو دنیای برنامهنویسی حرف بزنم: ORM یا همون Object-Relational Mapping.
🧠 ORM یعنی چی؟
ORM (Object-Relational Mapping) یه تکنیک تو برنامهنویسیه که دادههای دیتابیس رو به شکل اشیاء (objects) تو زبونهای شیگرا مثل پایتون، جاوا یا سیشارپ مدیریت میکنه. به بیان ساده، ORM یه پل ارتباطی بین دنیای شیگرایی (کلاسها و اشیاء) و دنیای دیتابیسهای رابطهای (جداول و ستونها) میسازه. با ORM دیگه لازم نیست مستقیم با کوئریهای SQL کار کنی؛ در عوض، با همون زبون برنامهنویسیات دیتابیس رو کنترل میکنی.
مثلاً به جای اینکه بنویسی:
SELECT * FROM users
میتونی تو پایتون با Django ORM اینجوری بنویسی:
users = User.objects.all()
و همون نتیجه رو بگیری
📚 ORM چطوری کار میکنه؟
فرض کن تو دیتابیست یه جدول به اسم
users
داری که ستونهاش اینان: id،name
و
تو برنامهات یه کلاس به اسم
User
میسازی که پراپرتیهایی مثل id
، name
و email
داره. ORM این کلاس رو به جدول users
توی دیتابیس مپ (map) میکنه. یعنی هر شیء از کلاس User
نمایانگر یه رکورد تو جدول users
میشه.چند تا سناریو رو با هم ببینیم:
1⃣ ذخیره کردن داده:
یه شیء از کلاس
User
میسازی، مقادیرش رو پر میکنی و با یه متد مثل save()
ذخیرهاش میکنی. ORM این کار رو به یه دستور SQL (مثل INSERT
) تبدیل میکنه و اجرا میکنه.user = User(name='علی', email='ali@example.com')
user.save()
2⃣ خوندن داده:
میتونی به جای کوئری SQL، از متدهایی مثل
all()
یا filter()
استفاده میکنی. ORM پشت صحنه کوئری مناسب رو میسازه و دادهها رو به شکل اشیاء برمیگردونه.# همه کاربرها
users = User.objects.all()
# فیلتر کردن
ali_users =
User.objects.filter(name='علی')
به همین سادگی ORM تمام پیچیدگیهای کار با دیتابیس رو از دید تو مخفی میکنه و یه رابط کاربری راحت بهت میده.
البته هر orm با orm های دیگه فرق داره هرچی یه orm بیشتر abstraction انجام داده باشه استفاده ازش راحت تر میشه🚀 ORM برای چی به وجود اومد؟
ولی توی مقیاس بالاتر همین سادگی باعث پیچیدگی میشه.
قبل از اینکه ORMها باشن، برنامهنویسها مستقیم با SQL کار میکردن. (هرچند همین الانشم توی زبان های هایی که orm مناسبی براش ساخته نشده برنامه نویسان بصورت خام کد sql میزنن مثل برنامه نویسان golang)
این چند تا مشکل داشت و داره:
کدهای طولانی:
برای هر عملیات ساده، باید یه کوئری SQL مینوشتی که گاهی خیلی پیچیده میشد.
خطای زیاد:
یه اشتباه کوچیک تو کوئری (مثل یه typo) میتونست ساعتها وقتت رو تلف کنه.
سختی نگهداری:
اگه ساختار دیتابیست عوض میشد (مثلاً یه ستون اضافه یا کم میشد)، باید همه کوئریها رو دستی تغییر میدادی.
تفاوت پارادایم:
SQL یه زبون declarative (اعلانی) هست، ولی زبونهایی مثل پایتون imperative (دستوری) هستن. این یعنی برنامهنویس باید مدام بین دو مدل فکری جابهجا میشد.
ORM اومد که این مشکلات رو حل کنه:
سادگی:
کار با دیتابیس مثل کار با اشیاء تو زبون خودت میشه.
امنیت:
ORMها معمولاً جلوی حملاتی مثل SQL Injection رو میگیرن.
انعطافپذیری:
میتونی دیتابیس رو عوض کنی (مثلاً از MySQL بری به PostgreSQL) بدون اینکه کل کدت رو تغییر بدی.
سرعت توسعه:
چون کوئرینویسی کمتر میشه، وقت بیشتری برای منطق اصلی برنامهات داری.
جمعبندی ✍
ORM یه ابزار باحال و قدرتمنده که کار با دیتابیس رو برای برنامهنویسها راحتتر، سریعتر و امنتر میکنه. با ORM دیگه لازم نیست با SQL خام کلنجار بری و میتونی با همون زبون برنامهنویسیات همهچیز رو مدیریت کنی.
#️⃣ #database #sql #orm
➖➖➖➖➖➖➖➖➖
🥷 CHANNEL | GROUP
❤14👍4