23 بهمن 1397 ساعت 22:48

Lazy Eager Loading یا بارگذاری مشتاق تنبل در لاراول

در لاراول نیز برای جلوگیری از ایجاد کئوری های سنگین و ایجاد خطای n+1 می توان از Eager Loading  استفاده کرد. 

گاهی مواقع نیاز داریم که پس از بارگذاری اطلاعات یک ردیف از جدول، اطلاعات یک یا چند جدول دیگر که با جدول پدر رابطه دارند را بارگذاری کنیم.

در حالت عادی شما باید برای این کار کئوری های متفاوتی نوشته و یا چندین جوین انجام دهید. 

لاراول برای حل این مشکل  Lazy Eager Loading  را معرفی کرده است!

یک از مهمترین فواید استفاده از  Lazy Eager Loading  جلوگیری از ایجاد خطای n+1 می باشد.

اگر شما یک لاراول کار هستید یا به تازگی با این فریم وورک قدرتمند آشنا شده اید حتما واژه ی Eloquent را شنیده اید.

Eloquent (بخوانید الکوینت!) نام ORM قدرتمند لاراول می باشد که علاوه بر امکانات بسیاری که در اختیار شما قرار می دهد، شما را از نوشتن کئوری های پیچیده بی نیاز می کند.

حال همین امکان مفید ممکن است پروژه شما را تا مرز نابودی پیش ببرد!

برای آشنایی بیشتر با ما همراه باشید.

تصور کنید شما جدولی بنام users دارید که این جدول با جدول دیگری با نام images رابطه ی یک به چند دارد( یعنی هر یوزر می تواند یک یا چند ایمیج داشته باشد) ، رابطه ی بین جدول users و images را بصورت زیر  می نویسیم:

// Model : Users
	public function Images(){
		$this->hasMany('Images');
	}
	

حال برای گرفتن اطلاعات کاربران و تصاویر آنها بصورت زیر به شیوه ی معمول عمل خواهیم کرد:

$users = Users::all();
foreach( $users as $user ) {
echo $user->name;
$images = $user->images;
	// Do someting with the $books
}

در مثال بالا ابتدا لیست تمام کاربران گرفته خواهد شد و سپس به ازای هر کاربر یک دستور برای دریافت تصاویر آن اجرا خواهد شد

SELECT * FROM users;
-- Foreach of the users, another query to select the images
	-- i.e. $users->images part of the loop
SELECT * FROM images WHERE user_id = 1
SELECT * FROM images WHERE user_id = 2
SELECT * FROM images WHERE user_id = 3
SELECT * FROM images WHERE user_id = 4
SELECT * FROM images WHERE user_id = 5
...

اگر سیستم شما کوچک باشد و دیتابیس شما داده ی زیادی نداشته باشد مشکلی ایجاد نمی شود، اما اگر دیتابیس شما حاوی اطلاعات زیادی باشد پروژه ی شما به خطر خواهد افتاد و سرور شما بزودی از کار خواهد افتاد و یا باید سرور خود را ارتقاع دهید...

اما چاره چیست؟؟؟

لاراول برای حل این مشکل Eager loading را پیشنهاد داده است.

اما Eager loading چیست؟

یک الگوی طراحی رایج در برنامه نویسی کامپیوتر است و در آن تا زمانی که به یک شی نیاز نداریم از آن نمونه ای ساخته نمی شود.  اگر از آن به درستی و در جای مناسب استفاده شود می تواند کارایی برنامه را افزایش دهد. مخالف Lazy Loading،  (یا بارگزاری حریص) eager loading است. کارایی Lazy Loading به ویژه در نمونه سازی از اشیایی که هزینه بر هستند (همچون: دسترسی به سرویس های شبکه) مهم است، . به طور مثال در مورد صفحات وب ما می خواهیم محتوای اصلی صفحه خیلی زود و در حداقل زمان بارگزاری شود و سایر محتوای ها بر حسب نیاز بارگزاری شوند.

 

در لاراول نیز برای جلوگیری از ایجاد کئوری های سنگین و ایجاد خطای n+1 می توان از Eager Loading  استفاده کرد. 

حال برای آشنای شما بیاید یک بار دیگر و با استفاده از بارگذاری تنبل اطلاعات کاربران و تصاویر مربوط به آنها را دیافت کنیم:

$users = Users::with('images')->get();
foreach( $users as $user ) {
	echo $users->name;
	$images = $user->images;
	// Do someting with the $images
}

لارول با دستور بالا متوجه خواهد شد که همراه با اطلاعات کاربران اطلاعات مربوط به تصاویر آنها را زیر بارگذرای کند، که در این حالت کئوری های زیر اجرا خواهد شد:

SELECT * FROM users;
SELECT * FROM images WHERE user_id IN (1,2,3,4,5,6,7,8..);

همانگونه که متوجه شده اید با استفاده از بارگذاری تنبل شما قادر خواهید بود با سرعت بالاتر اطلاعات را دریافت و از ایجاد کئوری های سنگین و خطای n+1 جلوگیری کنید.

 

شما همچنین می توانید چندین رابطه را نیز بصورت همزمان بارگذرای کنید.

تصور کنید شما مدلی بنام user  هستید که اطلاعات مطالب  نطرات مربوط به هر مطلب آنها در جداول جداگانه ای می باشد. شما می توانید با استفاده از دستور زیر همراه با فراخوانی اطلاعات user اطلاعات مربوط به پست ها و نظرات مربوط به هر پست  را نیز دریافت نمایید:

User::with('post.comments')->get()

 

در مطالب بعدی سعی خواهم کرد شما را بیشتر با روابط Eager loading آشنا کنم.

 

در صورتی که سوالی دارید از بخش نظرات سوال خودتون رو بپرسید یا نظرتون رو راجع به این مقاله بیان کنید.

 

1630 admin
نظرات

برای اطلاع از پاسخ به نظر شما می توانید ایمیل یا شماره موبایل خود را وارد نمایید. *

ایمیل و شماره موبایل شما کاملا مخفی خواهد ماند و در سایت نمایش داده نخواهد شد. *

پاسخ به نظر
اگر نظری برای این مطلب ارسال شد از طریق ایمیل مرا اطلاع بده!

هنوز برای این مطلب نظری ارسال نشده است!
0