لارافيل, Others / 2024-09-08

إستخدام UUIDs في لارافيل MODELS (الإيجابيات، السلبيات، طريقة الإستخدام)

إستخدام UUIDs في لارافيل MODELS (الإيجابيات، السلبيات، طريقة الإستخدام)

2024-09-08 وقت القراءه : 3 دقائق

جدول المحتويات


في هذه المقالة، سيتم التطرق إلى كيفية إستخدام UUIDs في لارافيل eloquent، عوضا عن إستخدام ids، فما هو UUIDs.


UUIDs هو معرف فريد وهو إختصار إلى Universally Unique Identifiersـ  ويتم تمثيلها كسلسلة سداسية عشرية مقسمة إلى خمس مجموعات يتم فصل كل مجموعة بالوصلة .

بشكل مبسط فإننا نريد إستبدال 

http://www.test.test/users/1 

بـ

http://www.test.test/users/2fc49420-1ea6-47ca-90de-e8e16ee4b09f 


يوجد جدل كبير حول عيوب ومزايا إستخدام UUIDs عوضا عن ids ومن هذه العيوب:-

  • UUIDs تعتمد على 16 bit عوضا عن 4 bit في integer او 8 bit في bigInteger، بالتالي فإنها تستغرق مساحة أكبر للتخزين والفهرسة.
  • نظرا لأن حجم UUIDs كبير، فإنها تأخذ مساحة أكبر في الذاكرة.
  • لا يتم إنشاؤها بشكل تسلسلي (1-2-3....)، مثل integer او big integer بل يتم إنشاؤها بشكل عشوائي، لذلك تعتبر عملية Sorting في المفاتيح الأولية integer primary keys أسرع.


متى يفضل المبرمجون إستخدام UUIDs عوضا عن إستخدام integer, bigInteger primary key؟

  • إخفاء id من المتصفح user=1 بحيث لا يمكن التنبؤ بعدد المستخدمين.
  • إخفاء ترتيب المستخدمين user=1, user=2.
  • جعل user_id لا يمكن تخمينة.


كيفية إستخدام UUIDs في لارافيل.

يفضل إستخدام UUIDs بشكل إضافي إلى الجدول دون الإستغناء عن ids، فيجب أن يحتوي الجدول على الإثنين، لأن ids أسرع، فسيتم إستخدام ids في العمليات التي تحتاج سرعة، ولا نحتاج لإخفاء id المستخدم.

سأطبق المثال على جدول users لذلك سأقوم بإنشاء migration جديد لإضافة uuid إلى جدول users.

php artisan make:migration AddUuidToUsersTable


public function up()
{
    Schema::table('users', function (Blueprint $table) {
        $table->uuid('uuid');
    });
}

كما نلاحظ في ملف migration أن نوع الحقل هو uuid.

إضافة uuid إلى دالة fillable

protected $fillable = [
    'name',
    'email',
    'password',
    'uuid',
];

الأن نحتاج أن يتم إنشاء unique uuid لكل مستخدم يتم تسجيله، لذلك سوف نستعين بـ laravel-uuid package 

composer require "webpatser/laravel-uuid:^3.0"

لإنشاء unique uuid نستخدم 

Uuid::generate()

لكن لتحويلها إلى eloquent نحتاج لإضافتها في دالة boot بداخل UserModel

public static function boot(){
    parent::boot();
    self::creating(function ($model){
        $model->uuid=(string) Uuid::generate(4);
    });
}

وعند إنشاء مستخدم جديد 

public function store(Request $request){
    $user=New User();
    $user->name=$request->name;
    $user->email=$request->email;
    $user->password=$request->password;
    $user->save();
    return redirect('/users');
}


كيفية إستخدام UUIDs في العرض

كيفة يتم إستبدال هذا الرابط

 http://www.test.test/users/1

 بـ

http://www.test.test/users/2fc49420-1ea6-47ca-90de-e8e16ee4b09f 


إذا كنا نستخدام route model binding

Route::get('/users/{user}',[\App\Http\Controllers\UserController::class,'show']);
public function show(User $user){
    return $user;
}

 فإننا نحتاج لإخبار user model بإستخدام uuid عوضا عن ids وذلك من خلال إضافة دالة getRouteKeyName بداخل UserModel

public function getRouteKeyName()
{
    return 'uuid';
}

بعد إضافة الدالة لو قمنا بزيارة الرابط 

http://www.test.test/users/1 

فإنه سوف يعطي أن user غير موجود مع العلم أنه موجود في قاعدة البيانات، وذلك لأننا أخبرنا الـ user model بإستخدام UUIDs عوضا عن إستخدام ids.

لكن لو قمنا بإستخدام 

http://www.test.test/users/2fc49420-1ea6-47ca-90de-e8e16ee4b09f 

فإنه سوف يرجع الـ user.


إذا كنا لا نستخدم route model binding

عند زيارة الرابط

http://www.test.test/users/2fc49420-1ea6-47ca-90de-e8e16ee4b09f 
Route::get('/users/{user_id}',[\App\Http\Controllers\UserController::class,'show']);


public function show($user_id){
    $user=User::where('uuid',$user_id)->first();
    return $user;
}
إضافة تعليق
Loading...