نسخه:

پایگاه داده: شروع به کار

معرفی

تقریباً هر برنامه وب مدرن با پایگاه داده تعامل دارد. لاراول با استفاده از SQL خام، یک سازنده پرس و جو روان و Eloquent ORM تعامل با پایگاه های داده را در میان انواع پایگاه داده های پشتیبانی شده بسیار ساده می کند . در حال حاضر، لاراول از پنج پایگاه داده پشتیبانی شخص اول را ارائه می دهد:

پیکربندی

پیکربندی سرویس های پایگاه داده لاراول در config/database.php فایل پیکربندی برنامه شما قرار دارد. در این فایل می توانید تمام اتصالات پایگاه داده خود را تعریف کنید و همچنین مشخص کنید که کدام اتصال باید به طور پیش فرض استفاده شود. اکثر گزینه های پیکربندی در این فایل توسط مقادیر متغیرهای محیطی برنامه شما هدایت می شوند. نمونه هایی برای اکثر سیستم های پایگاه داده پشتیبانی شده لاراول در این فایل ارائه شده است.

به طور پیش‌فرض، پیکربندی محیط نمونه لاراول برای استفاده با Laravel Sail آماده است ، که یک پیکربندی Docker برای توسعه برنامه‌های لاراول در ماشین محلی شما است. با این حال، شما آزاد هستید که پیکربندی پایگاه داده خود را در صورت نیاز برای پایگاه داده محلی خود تغییر دهید.

پیکربندی SQLite

پایگاه داده های SQLite در یک فایل واحد در سیستم فایل شما قرار دارند. می توانید با استفاده از touch دستور موجود در ترمینال خود یک پایگاه داده جدید SQLite ایجاد کنید: touch database/database.sqlite . پس از ایجاد پایگاه داده، می توانید با قرار دادن مسیر مطلق به پایگاه داده در DB_DATABASE متغیر محیط، به راحتی متغیرهای محیط خود را برای اشاره به این پایگاه داده پیکربندی کنید:

DB_CONNECTION=sqlite
DB_DATABASE=/absolute/path/to/database.sqlite

به طور پیش فرض، محدودیت های کلید خارجی برای اتصالات SQLite فعال هستند. اگر می‌خواهید آنها را غیرفعال کنید، باید DB_FOREIGN_KEYS متغیر محیطی را به صورت زیر تنظیم کنید false :

DB_FOREIGN_KEYS=false

اگر از نصب کننده لاراول برای ایجاد برنامه لاراول خود استفاده کنید و SQLite را به عنوان پایگاه داده خود انتخاب کنید، لاراول به طور خودکار یک database/database.sqlite فایل ایجاد می کند و مهاجرت های پیش فرض پایگاه داده را برای شما اجرا می کند.

پیکربندی مایکروسافت SQL Server

برای استفاده از پایگاه داده Microsoft SQL Server، باید اطمینان حاصل کنید که پسوندها sqlsrv و pdo_sqlsrv PHP و همچنین وابستگی هایی که ممکن است به آن نیاز داشته باشند مانند درایور Microsoft SQL ODBC را نصب کرده باشید.

پیکربندی با استفاده از URL

به طور معمول، اتصالات پایگاه داده با استفاده از مقادیر پیکربندی چندگانه مانند،،،، و غیره پیکربندی می شوند. host هر یک از این مقادیر پیکربندی متغیر محیطی مربوط به خود را دارند. این بدان معناست که هنگام پیکربندی اطلاعات اتصال پایگاه داده خود بر روی یک سرور تولیدی، باید چندین متغیر محیطی را مدیریت کنید. database username password

برخی از ارائه دهندگان پایگاه داده مدیریت شده مانند AWS و Heroku یک پایگاه داده واحد "URL" ارائه می کنند که شامل تمام اطلاعات اتصال برای پایگاه داده در یک رشته است. نمونه URL پایگاه داده ممکن است چیزی شبیه به زیر باشد:

mysql://root:password@127.0.0.1/forge?charset=UTF-8

این URL ها معمولاً از یک قرارداد استاندارد طرحواره پیروی می کنند:

driver://username:password@host:port/database?options

برای راحتی، لاراول از این URL ها به عنوان جایگزینی برای پیکربندی پایگاه داده شما با چندین گزینه پیکربندی پشتیبانی می کند. اگر گزینه پیکربندی url (یا DB_URL متغیر محیط مربوطه) وجود داشته باشد، برای استخراج اتصال پایگاه داده و اطلاعات اعتبار استفاده می شود.

خواندن و نوشتن اتصالات

گاهی اوقات ممکن است بخواهید از یک اتصال پایگاه داده برای دستورات SELECT و دیگری برای INSERT، UPDATE و DELETE استفاده کنید. لاراول این کار را آسان می کند و اتصالات مناسب همیشه مورد استفاده قرار می گیرند، چه از پرس و جوهای خام، چه از سازنده پرس و جو یا از Eloquent ORM استفاده کنید.

برای اینکه ببینید چگونه اتصالات خواندن/نوشتن باید پیکربندی شوند، بیایید به این مثال نگاه کنیم:

'mysql' => [
'read' => [
'host' => [
'192.168.1.1',
'196.168.1.2',
],
],
'write' => [
'host' => [
'196.168.1.3',
],
],
'sticky' => true,
 
'database' => env('DB_DATABASE', 'laravel'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => env('DB_CHARSET', 'utf8mb4'),
'collation' => env('DB_COLLATION', 'utf8mb4_0900_ai_ci'),
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],

توجه داشته باشید که سه کلید به آرایه پیکربندی اضافه شده است : read و write . sticky کلیدهای read و write دارای مقادیر آرایه ای هستند که حاوی یک کلید واحد هستند: host . بقیه گزینه های پایگاه داده برای read و write اتصالات از آرایه پیکربندی اصلی ادغام خواهند شد mysql .

اگر می‌خواهید مقادیر آرایه اصلی را لغو کنید، فقط باید آیتم‌ها را در آرایه‌های read و قرار دهید . بنابراین، در این مورد، به عنوان میزبان برای اتصال "خواندن" استفاده می شود، در حالی که برای اتصال "نوشتن" استفاده می شود. اعتبار پایگاه داده، پیشوند، مجموعه کاراکترها و همه گزینه های دیگر در آرایه اصلی در هر دو اتصال به اشتراک گذاشته می شود. هنگامی که چندین مقدار در آرایه پیکربندی وجود دارد، یک میزبان پایگاه داده به طور تصادفی برای هر درخواست انتخاب می شود. write mysql 192.168.1.1 192.168.1.3 mysql host

گزینه sticky

گزینه sticky یک مقدار اختیاری است که می تواند برای خواندن فوری رکوردهایی که در چرخه درخواست فعلی در پایگاه داده نوشته شده اند استفاده شود. اگر این sticky گزینه فعال باشد و عملیات "نوشتن" در برابر پایگاه داده در طول چرخه درخواست فعلی انجام شده باشد، هر عملیات "خواندن" بعدی از اتصال "نوشتن" استفاده خواهد کرد. این تضمین می کند که هر داده ای که در طول چرخه درخواست نوشته می شود را می توان بلافاصله در همان درخواست از پایگاه داده بازخوانی کرد. این شما هستید که باید تصمیم بگیرید که آیا این رفتار مطلوب برای برنامه شما است یا خیر.

اجرای پرس و جوهای SQL

هنگامی که اتصال پایگاه داده خود را پیکربندی کردید، می توانید پرس و جوهایی را با استفاده از DB نما اجرا کنید. نما DB روش هایی را برای هر نوع پرس و جو ارائه می دهد: select , update , insert , delete و statement .

اجرای یک جستجوی انتخابی

برای اجرای یک پرس و جو اولیه SELECT، می توانید از select روش روی DB نما استفاده کنید:

<?php
 
namespace App\Http\Controllers;
 
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;
use Illuminate\View\View;
 
class UserController extends Controller
{
/**
* Show a list of all of the application's users.
*/
public function index(): View
{
$users = DB::select('select * from users where active = ?', [1]);
 
return view('user.index', ['users' => $users]);
}
}

اولین آرگومان ارسال شده به select متد، پرس و جوی SQL است، در حالی که آرگومان دوم هر گونه پیوند پارامتری است که باید به پرس و جو متصل شود. به طور معمول، این مقادیر where محدودیت های عبارت هستند. اتصال پارامتر محافظت در برابر تزریق SQL را فراهم می کند.

این select روش همیشه یک array نتیجه را برمی گرداند. هر نتیجه در آرایه یک stdClass شی PHP خواهد بود که یک رکورد از پایگاه داده را نشان می دهد:

use Illuminate\Support\Facades\DB;
 
$users = DB::select('select * from users');
 
foreach ($users as $user) {
echo $user->name;
}

انتخاب مقادیر اسکالر

گاهی اوقات پرس و جو پایگاه داده شما ممکن است منجر به یک مقدار واحد و اسکالر شود. لاراول به جای نیاز به بازیابی نتیجه اسکالر پرس و جو از یک شی رکورد، به شما اجازه می دهد این مقدار را مستقیماً با استفاده از scalar روش بازیابی کنید:

$burgers = DB::scalar(
"select count(case when food = 'burger' then 1 end) as burgers from menu"
);

انتخاب مجموعه نتایج چندگانه

اگر برنامه شما رویه‌های ذخیره‌شده‌ای را فراخوانی می‌کند که چندین مجموعه نتیجه را برمی‌گردانند، می‌توانید از این selectResultSets روش برای بازیابی همه مجموعه‌های نتایج بازگشت‌شده توسط رویه ذخیره‌شده استفاده کنید:

[$options, $notifications] = DB::selectResultSets(
"CALL get_user_options_and_notifications(?)", $request->user()->id
);

استفاده از Bindings با نام

به جای استفاده ? برای نمایش پیوندهای پارامتری خود، می توانید یک پرس و جو را با استفاده از اتصالات نامگذاری شده اجرا کنید:

$results = DB::select('select * from users where id = :id', ['id' => 1]);

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

برای اجرای یک insert دستور، می توانید از insert روش روی DB نما استفاده کنید. مانند select ، این متد پرس و جوی SQL را به عنوان اولین آرگومان خود و bindings را به عنوان آرگومان دوم می پذیرد:

use Illuminate\Support\Facades\DB;
 
DB::insert('insert into users (id, name) values (?, ?)', [1, 'Marc']);

اجرای بیانیه به روز رسانی

این update روش باید برای به روز رسانی رکوردهای موجود در پایگاه داده استفاده شود. تعداد سطرهایی که تحت تأثیر دستور قرار می گیرند توسط روش برگردانده می شود:

use Illuminate\Support\Facades\DB;
 
$affected = DB::update(
'update users set votes = 100 where name = ?',
['Anita']
);

اجرای Delete Statement

این delete روش باید برای حذف رکوردها از پایگاه داده استفاده شود. مانند update ، تعداد ردیف های تحت تأثیر با روش برگردانده می شود:

use Illuminate\Support\Facades\DB;
 
$deleted = DB::delete('delete from users');

اجرای یک بیانیه عمومی

برخی از دستورات پایگاه داده هیچ مقداری را بر نمی گرداند. برای این نوع عملیات، می توانید از statement روش زیر در DB نما استفاده کنید:

DB::statement('drop table users');

اجرای یک بیانیه آماده نشده

گاهی اوقات ممکن است بخواهید یک دستور SQL را بدون اتصال هیچ مقداری اجرا کنید. برای انجام این کار می توانید از روش DB نما استفاده کنید: unprepared

DB::unprepared('update users set votes = 100 where name = "Dries"');

از آنجایی که دستورات آماده نشده پارامترها را متصل نمی کنند، ممکن است در برابر تزریق SQL آسیب پذیر باشند. شما هرگز نباید اجازه دهید مقادیر کنترل شده توسط کاربر در یک عبارت آماده نشده باشد.

تعهدات ضمنی

هنگام استفاده از DB نما statement و unprepared روش‌ها در تراکنش‌ها، باید مراقب باشید که از اظهاراتی که باعث تعهد ضمنی می‌شوند، خودداری کنید . این عبارات باعث می شود که موتور پایگاه داده به طور غیرمستقیم کل تراکنش را انجام دهد و لاراول از سطح تراکنش پایگاه داده بی خبر بماند. یک مثال از چنین عبارتی ایجاد یک جدول پایگاه داده است:

DB::unprepared('create table a (col varchar(1) null)');

لطفاً برای فهرستی از تمام عباراتی که باعث commit های ضمنی می شوند ، به دفترچه راهنمای MySQL مراجعه کنید .

استفاده از اتصالات چندگانه پایگاه داده

اگر برنامه شما چندین اتصال را در config/database.php فایل پیکربندی شما تعریف می کند، می توانید از طریق connection روش ارائه شده توسط DB نما به هر اتصال دسترسی داشته باشید. نام اتصال ارسال شده به connection روش باید با یکی از اتصالات لیست شده در config/database.php فایل پیکربندی شما یا پیکربندی شده در زمان اجرا با استفاده از config کمک کننده مطابقت داشته باشد:

use Illuminate\Support\Facades\DB;
 
$users = DB::connection('sqlite')->select(/* ... */);

می‌توانید با استفاده از روش موجود در یک نمونه اتصال، به نمونه خام و زیربنایی PDO یک getPdo اتصال دسترسی پیدا کنید:

$pdo = DB::connection()->getPdo();

گوش دادن به رویدادهای پرس و جو

اگر می‌خواهید برای هر کوئری SQL که توسط برنامه شما اجرا می‌شود، بسته‌ای را مشخص کنید، می‌توانید از روش DB نما استفاده کنید listen . این روش می تواند برای ثبت پرس و جوها یا اشکال زدایی مفید باشد. می توانید بسته شدن شنونده درخواست خود را به boot روش ارائه دهنده خدمات ثبت کنید :

<?php
 
namespace App\Providers;
 
use Illuminate\Database\Events\QueryExecuted;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\ServiceProvider;
 
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
// ...
}
 
/**
* Bootstrap any application services.
*/
public function boot(): void
{
DB::listen(function (QueryExecuted $query) {
// $query->sql;
// $query->bindings;
// $query->time;
});
}
}

نظارت بر زمان پرس و جو تجمعی

یک گلوگاه عملکرد رایج برنامه های کاربردی وب مدرن، مدت زمانی است که آنها برای جستجو در پایگاه های داده صرف می کنند. خوشبختانه، لاراول زمانی که زمان زیادی را صرف جستجوی پایگاه داده در طول یک درخواست واحد می‌کند، می‌تواند بسته شدن یا برگشت تماس را به انتخاب شما فراخوانی کند. برای شروع، یک آستانه زمانی پرس و جو (بر حسب میلی ثانیه) و بسته شدن به whenQueryingForLongerThan روش ارائه دهید. می توانید این روش را در boot روش ارائه دهنده خدمات فراخوانی کنید :

<?php
 
namespace App\Providers;
 
use Illuminate\Database\Connection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\ServiceProvider;
use Illuminate\Database\Events\QueryExecuted;
 
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
// ...
}
 
/**
* Bootstrap any application services.
*/
public function boot(): void
{
DB::whenQueryingForLongerThan(500, function (Connection $connection, QueryExecuted $event) {
// Notify development team...
});
}
}

معاملات پایگاه داده

می توانید از transaction روش ارائه شده توسط DB نما برای اجرای مجموعه ای از عملیات در یک تراکنش پایگاه داده استفاده کنید. اگر یک استثنا در بسته شدن تراکنش ایجاد شود، تراکنش به طور خودکار برگردانده می شود و استثنا دوباره پرتاب می شود. اگر بسته شدن با موفقیت انجام شود، تراکنش به طور خودکار انجام خواهد شد. در حین استفاده از روش، نیازی نیست نگران عقب نشینی یا تعهد به صورت دستی باشید transaction :

use Illuminate\Support\Facades\DB;
 
DB::transaction(function () {
DB::update('update users set votes = 1');
 
DB::delete('delete from posts');
});

رسیدگی به بن بست ها

این transaction روش یک آرگومان دوم اختیاری را می پذیرد که تعداد دفعاتی را که یک تراکنش باید در زمان وقوع بن بست تکرار شود را مشخص می کند. هنگامی که این تلاش ها تمام شد، یک استثنا ایجاد می شود:

use Illuminate\Support\Facades\DB;
 
DB::transaction(function () {
DB::update('update users set votes = 1');
 
DB::delete('delete from posts');
}, 5);

استفاده دستی از تراکنش ها

اگر می خواهید یک تراکنش را به صورت دستی شروع کنید و کنترل کاملی بر بازگشت و تعهد داشته باشید، می توانید از روش beginTransaction ارائه شده توسط DB نما استفاده کنید:

use Illuminate\Support\Facades\DB;
 
DB::beginTransaction();

می توانید تراکنش را از طریق rollBack روش زیر برگردانید:

DB::rollBack();

در نهایت، می توانید یک تراکنش را از طریق commit روش زیر انجام دهید:

DB::commit();

روش های تراکنش نما DB ، تراکنش ها را هم برای سازنده پرس و جو و هم برای ORM Eloquent کنترل می کند .

اتصال به پایگاه داده CLI

اگر می خواهید به CLI پایگاه داده خود متصل شوید، می توانید از db دستور Artisan استفاده کنید:

php artisan db

در صورت نیاز، می‌توانید نام اتصال پایگاه داده را برای اتصال به اتصال پایگاه داده که اتصال پیش‌فرض نیست، تعیین کنید:

php artisan db mysql

بازرسی پایگاه های داده شما

با استفاده از دستورات db:show و db:table Artisan، می توانید بینش ارزشمندی از پایگاه داده خود و جداول مرتبط با آن به دست آورید. برای مشاهده یک نمای کلی از پایگاه داده خود، از جمله اندازه، نوع، تعداد اتصالات باز، و خلاصه ای از جداول آن، می توانید از دستور استفاده کنید db:show :

php artisan db:show

می توانید با ارائه نام اتصال پایگاه داده به دستور از طریق --database گزینه، مشخص کنید که کدام اتصال پایگاه داده باید بررسی شود:

php artisan db:show --database=pgsql

اگر می‌خواهید تعداد ردیف‌های جدول و جزئیات نمای پایگاه داده را در خروجی فرمان قرار دهید، می‌توانید به ترتیب گزینه‌های --counts و را ارائه کنید --views . در پایگاه داده های بزرگ، بازیابی تعداد ردیف و جزئیات مشاهده می تواند کند باشد:

php artisan db:show --counts --views

علاوه بر این، می توانید از Schema روش های زیر برای بررسی پایگاه داده خود استفاده کنید:

use Illuminate\Support\Facades\Schema;
 
$tables = Schema::getTables();
$views = Schema::getViews();
$columns = Schema::getColumns('users');
$indexes = Schema::getIndexes('users');
$foreignKeys = Schema::getForeignKeys('users');

اگر می خواهید اتصال پایگاه داده ای را که اتصال پیش فرض برنامه شما نیست بررسی کنید، می توانید از connection روش زیر استفاده کنید:

$columns = Schema::connection('sqlite')->getColumns('users');

نمای کلی جدول

اگر می خواهید یک نمای کلی از یک جدول جداگانه در پایگاه داده خود داشته باشید، می توانید db:table دستور Artisan را اجرا کنید. این دستور یک نمای کلی از جدول پایگاه داده شامل ستون ها، انواع، ویژگی ها، کلیدها و فهرست های آن ارائه می دهد:

php artisan db:table users

نظارت بر پایگاه های داده شما

با استفاده از دستور Artisan، اگر پایگاه داده شما بیش از تعداد مشخصی از اتصالات باز را مدیریت می کند، db:monitor می توانید به لاراول دستور دهید تا یک رویداد را ارسال کند . Illuminate\Database\Events\DatabaseBusy

برای شروع، باید db:monitor دستور را برای اجرای هر دقیقه برنامه ریزی کنید . این فرمان نام پیکربندی های اتصال پایگاه داده را که می خواهید نظارت کنید و همچنین حداکثر تعداد اتصالات باز که باید قبل از ارسال یک رویداد تحمل شوند را می پذیرد:

php artisan db:monitor --databases=mysql,pgsql --max=100

زمان‌بندی این دستور به تنهایی برای راه‌اندازی اعلانی که تعداد اتصالات باز را به شما هشدار می‌دهد کافی نیست. هنگامی که فرمان با پایگاه داده‌ای مواجه می‌شود که تعداد اتصالات باز دارد که از آستانه شما فراتر می‌رود، یک DatabaseBusy رویداد ارسال می‌شود. AppServiceProvider برای ارسال اعلان به شما یا تیم توسعه‌تان، باید به این رویداد در برنامه‌تان گوش دهید :

use App\Notifications\DatabaseApproachingMaxConnections;
use Illuminate\Database\Events\DatabaseBusy;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Notification;
 
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Event::listen(function (DatabaseBusy $event) {
Notification::route('mail', 'dev@example.com')
->notify(new DatabaseApproachingMaxConnections(
$event->connectionName,
$event->connections
));
});
}