پایگاه داده: شروع به کار
- معرفی
- اجرای پرس و جوهای SQL
- معاملات پایگاه داده
- اتصال به پایگاه داده CLI
- بازرسی پایگاه های داده شما
- نظارت بر پایگاه های داده شما
معرفی
تقریباً هر برنامه وب مدرن با پایگاه داده تعامل دارد. لاراول با استفاده از SQL خام، یک سازنده پرس و جو روان و Eloquent ORM تعامل با پایگاه های داده را در میان انواع پایگاه داده های پشتیبانی شده بسیار ساده می کند . در حال حاضر، لاراول از پنج پایگاه داده پشتیبانی شخص اول را ارائه می دهد:
- MariaDB 10.3+ ( خط مشی نسخه )
- MySQL 5.7+ ( خط مشی نسخه )
- PostgreSQL 10.0+ ( خط مشی نسخه )
- SQLite 3.35.0+
- SQL Server 2017+ ( خط مشی نسخه )
پیکربندی
پیکربندی سرویس های پایگاه داده لاراول در
config/database.php
فایل پیکربندی برنامه شما قرار دارد. در این فایل می توانید تمام اتصالات پایگاه داده خود را تعریف کنید و همچنین مشخص کنید که کدام اتصال باید به طور پیش فرض استفاده شود. اکثر گزینه های پیکربندی در این فایل توسط مقادیر متغیرهای محیطی برنامه شما هدایت می شوند. نمونه هایی برای اکثر سیستم های پایگاه داده پشتیبانی شده لاراول در این فایل ارائه شده است.
به طور پیشفرض، پیکربندی محیط نمونه لاراول برای استفاده با Laravel Sail آماده است ، که یک پیکربندی Docker برای توسعه برنامههای لاراول در ماشین محلی شما است. با این حال، شما آزاد هستید که پیکربندی پایگاه داده خود را در صورت نیاز برای پایگاه داده محلی خود تغییر دهید.
پیکربندی SQLite
پایگاه داده های SQLite در یک فایل واحد در سیستم فایل شما قرار دارند. می توانید با استفاده از
touch
دستور موجود در ترمینال خود یک پایگاه داده جدید SQLite ایجاد کنید:
touch database/database.sqlite
. پس از ایجاد پایگاه داده، می توانید با قرار دادن مسیر مطلق به پایگاه داده در
DB_DATABASE
متغیر محیط، به راحتی متغیرهای محیط خود را برای اشاره به این پایگاه داده پیکربندی کنید:
DB_CONNECTION=sqliteDB_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 )); });}