laravel / framework

The Laravel Framework.
https://laravel.com
MIT License
32.66k stars 11.04k forks source link

orderedUuid method uses uuid v4 instead of v7 #53631

Closed dmytrozelonkin closed 3 days ago

dmytrozelonkin commented 3 days ago

Laravel Version

11.33.2

PHP Version

8.3

Database Driver & Version

mariadb:11.4

Description

I use uuid as primary key instead of integer. I changed type in migration file $table->uuid('id')->primary(); and added Illuminate\Database\Eloquent\Concerns\HasUuids trait to the model.

When I fill the table with data and do sorting by id the records are not sorted in correct way. I see that HasUuids trait calls Str::orderedUuid() method which calls $factory->uuid4(). If i understood correct the v4 generates random uuid.

The documentation says

By default, The HasUuids trait will generate "ordered" UUIDs for your models. These UUIDs are more efficient for indexed database storage because they can be sorted lexicographically.

Looks like orderedUuid method should use v7 instead of v4.

Steps To Reproduce

Create a migration Schema::create('records', function (Blueprint $table) { $table->uuid('id')->primary(); $table->string('title'); $table->timestamp('created_at'); $table->timestamp('updated_at'); });

Create a model with HasUuids trait

class Record extends Model { use \Illuminate\Database\Eloquent\Concerns\HasUuids; }

Create a N records to fill the table. The sorting by id should be equivalent sorting by created_at but it doesn't.

dmytrozelonkin commented 3 days ago

This issue was resolved by changing the column type from $table->uuid('id')->primary() to $table->char('id', 36)->primary().

dmytrozelonkin commented 3 days ago

Also, I don't understand why uuid4 is used for generating ordered uuids instead of uuid7.

Karem-sobhy commented 1 day ago

@dmytrozelonkin Mariadb saves the uuid type as bin which results in incorrect order with the pseudo ordered uuid4 laravel uses You can still use the uuid datatype of mariadb still which is faster and take much less space but with the new trait that uses uuid7 HasVersion7Uuid All about this could be found here

51883 issue

52029 pr

Edit Also note this will be the default behaviour starting from laravel 12

52433