This article appeared at https://jaychen.cc

The author JayChen

This is a basic tutorial for benchmarking data migration and data population in Laravel documents.

migration

Laravel provides a database migration method to manage databases. Imagine a scenario: In a multi-person development project, your colleagues have changed a database structure and changed the code. With Git, you can synchronize the code changed by your colleagues. However, with the database structure, you can only manually copy the SQL statements changed by your colleagues and execute them to ensure that the database structure is consistent. The database migration concept in Laravel, then, is used to solve a solution to ensure that the database structure is consistent within the team.

Migration is very simple to use. You write some PHP code and execute it, and Laravel will automatically update the database. If your colleague wants to change a field in your database, write PHP code, update your code with Git, and perform migrate. Let’s see how to use it.

migrate

Laravel refers to the PHP code that writes database changes as migrations. The migration file can be created using PHP artisan make: Migration filename. If you want to create a new user table, you can create a migration file by running PHP artisan make:migration create_user_table –create=user. This will create a PHP file with file creation time _filename in the database/migrations/ directory. This is the file we will use to write the database structure changes. One thing to note here is that while the name of the migration file can be arbitrary, for administrative convenience, it is best that the file name reflect the database operation to be performed. For example, in this case, we are creating a user table, so we call the file name create_user_table.

PHP artisan make:migration filename Has two optional parameters

  • --create=tablenameIndicates that the migration is used to create tables.
  • --table=tablenameThis indicates that the migration is used to operate on the table tablename.

The migration file create_user_table that we create will contain two methods.


public function up(a)
{
    Schema::create('user'.function (Blueprint $table) {
        $table->increments('id');
        $table->timestamps();
    });
}


public function down(a)
{
    Schema::dropIfExists('user');
}
Copy the code

These two methods are mutually inverse operations. For example, we can write information about the user table we want to create in the up method, and delete the user table in the Down method. In this way, we can do the rollback operation, when we create the user table and find that a field name is wrong, we can delete the user table by down, and then create the user table again.

If the user table has three fields: ID,username, and email, you can write them in the up method

public function up(a)
{
    Schema::create('user'.function (Blueprint $table) {
        $table->increments('id')->index()->comment('user id');
        $table->string('name')->default(' ')->comment('Username');
        $table->string('email')->nullable()->comment('User Mailbox');
        $table->timestamps();
    });
}
Copy the code

Normally, our logic is written in the closure function. Even if you don’t fully understand the above code, you can probably guess the following points:

  • The table we operate on is the User table.
  • The ID field is defined in the user table because theincrementsMethod, so id isauto_incrementAnd call theindexThe method description adds an index to the ID, and finallycommentEquivalent to comments.
  • With the id experience, it’s easy to understand the name field,stringMethod Description Name Yesvarchar/charThe type,defaultDefines a default value for the name field.
  • The email field is callednullableThe email field is left blank.
  • You can use chained calls to define the field structure.

If you need to define a field of type TEXT, you can call the text() method. For more information, see the Laravel Database Structure Constructor document.

PHP Artisan Migrate Laravel will automatically create user tables for us using the create method. At this point, we have successfully created the table using Larvel’s migration capability.

Rollback

Using Laravel’s migration feature can lead to regrets.

PHP Artisan Migrate select user from user table and delete it from user table. This is where we use the down method.

public function down(a)
{
    Schema::dropIfExists('user');
}
Copy the code

PHP Artisan migrate :rollback PHP Artisan migrate :rollback PHP Artisan migrate :rollback

Rename table

In addition to creating a table, you can also use migration to record any other operation of the table, including modifying table properties, modifying fields, and so on. Here is another example of how to rename a table using a migration.

  • Suppose we have the table user, and we need to rename it to Users. The first thing is to executephp artisan make:migration rename_user_to_users --table userTo create the migration file.
  • inupMethod to write the logic we want to rename the table.

public function up(a)
{
    Schema::table('user'.function (Blueprint $table) {
        Schema::rename('user'.'users');
    });
}
Copy the code
  • In order for rollback to be implemented successfully, we still need todownMethod to write the logic to undo the rename operation.
public function up(a)
{
    Schema::table('user'.function (Blueprint $table) {
        //
        Schema::rename('users'.'user');
    });
}
Copy the code
  • The last executionphp artisan migrateYou can rename the user table. If you need to roll back, just do itphp artisan migrate:rollback.

You will notice that if a migration is performed, a second migration will not be performed again. This is because Laravel creates a migrations table in the database to record which migrations have been performed.

That’s enough for a basic introduction to migration. The above should cover most of the requirements. If you need more detail, you may need to read Laravel’s indecible documentation. 🙂

Seeder

Laravel also has a seeder in addition to migration, which is used for data padding. If you need some test data in your project, you can also write PHP code to populate the test data, so that everyone has the same test data by synchronizing the code with Git.

Similarly, data population is called a Seeder in Laravel. If you want to populate a table, you need to create a Seeder. Generate a seeder class by executing PHP artisan make:seeder UserTableSeeder. Here we want to populate the representation of the data table test, so the name is UserTableSeeder. Of course, the name is not mandatory, just for the sake of recognition.

When UserTableSeeder is created, a UserTableSeeder class is generated in the database/seeders directory. This class has only one run method. You can write code to insert the database in the run method. Suppose we use the DB facade to insert data into the test table.

class UserTableSeeder extends Seeder
{

    public function run(a)
    {
        DB::table('users')->insert($insertData); }}Copy the code

After writing the code, run the PHP Artsian db:seeder –class= UserTableSeeder command to populate the data. After the execution, check that the database has data.

If we have multiple tables to populate, it is not possible to execute PHP artisan DB :seeder –class= XXXX one by one after writing PHP code. There is an easy way. $this->call(UserTableSeeder::class); Then execute PHP artisan DB :seeder, Laravel will execute the run method in DatabaseSeeder and perform the migration one by one.

Unlike migration, if you execute PHP artisan DB :seeder multiple times, the data will be populated multiple times.

If you want to insert a lot of test data at once, then using a DB facade in the run method to do it one by one is not a good idea. Laravel provides a model factory way to create large amounts of data.

Model factory

Model factory means that it is essentially a factory pattern. So, creating data using a model factory requires two things

  1. Create the factory and define the data that the factory will return.
  2. Call the factory to get the data.

Laravel creates a factory class for User Model by running PHP artisan make:factory UserFactory –model=User. This file will be stored in the database/factory directory. Open the file and you can see the following code:

$factory->define(App\User::class, function (Faker $faker) {
    return [
        //
    ];
});
Copy the code

In this case, the value of return is the data we obtained in step 2 using the factory. The logic to generate the data is simply written in the closure function. The Faker class needs to be mentioned here. This is a third-party library that Laravel integrates with. What this library does is interesting: ** is used to generate fake data. ** If you want to insert 100 users into the User table, then you need 100 username, so you don’t have to write your own logic to generate a lot of test01, test02 and so on. Using Faker will generate a lot of real username for you. (I don’t know if this is boring :)…) .

Now, assuming that the User table has three fields: ID, email, and USERNAME, I want to generate 100 users by first implementing the logic in the factory class.

$factory->define(App\Models\User::class, function (Faker $faker) {
    return [
    	// Call the Faker API directly to generate fake data. See the faker documentation for more information.
        'username' => $faker->name,
        'email' => $faker->unique()->safeEmail,
    ];
});
Copy the code

Now that we have defined the factory, we will use the model factory in the UserSeeder@run function to generate the test data.


class UserTableSeeder extends Seeder
{

    public function run(a)
    {
        factory(App\User::class)->times(10)->make()->each(function($user,$index){ $user->save(); }); }}Copy the code

The cascade of calls in the run function was a black line when I first started working on Laravel, but once I got used to it, the code was pretty readable

  • factory(App\User::class)Specifies which factory to return, parameterApp\User::classIt’s the unique identifier of the factory. So here we’re defining the factorydefineThe first argument to is already specified.
  • ->times(10)Specifies that the factory schema is required to generate 10 User data. That’s 10 callsdefineThe second argument to the function.
  • ->make()Encapsulate the generated 10 User data into a collection object in Laravel.
  • ->each()Is a function in the Laravel set,eachThe function operates on each element in the set. This is where you save the data directly to the database.

Ok, so much for the basic operations of data migration and data population. More complex uses… It doesn’t necessarily work.