46

I am using laravel and laravel migration mechanism. I created tables and seted up foreign keys. But the tables are MyISSAM so no foreign keys are created. Where do I enable / configure this? (to change it to InnoDB and not in the mysql server).

Keyvan Gholami
  • 168
  • 1
  • 3
  • 15
DigitalWM
  • 4,406
  • 3
  • 18
  • 15

9 Answers9

128

You can edit your /config/database.php file, search for mysql entry and change:

'engine' => null,

to

'engine' => 'InnoDB',

This saves you from adding $table->engine = "InnoDB"; for each of your Schemas ;)

Thomas LAURENT
  • 1,592
  • 1
  • 11
  • 9
  • This is perfect! Thank you! – Christoffer Nov 19 '17 at 13:57
  • 1
    The question is now, why Laravel allows to create foreign key in the migrations files using MyISAM. Using MySQL 5.7 (so with InnoDB as default), the `migrate` command still creates table with MyISAM, and my foreign keys are only indexes. Weird. – Vincent Decaux Aug 04 '18 at 10:44
  • 2
    @VincentDecaux, Laravel has given all the developers the functionality to create the foreign keys via migration code. Suppose if Laravel doesn't allow this functionality and someone, who is using the InnoDB engine, needed it then obviously he'll have to write the query(ies) separately to add foreign key constraints. Which in result will double his/her work and time as well. – Mr.Singh Oct 11 '19 at 07:25
14

Define engine like this

  Schema::create("models", function(Blueprint $table) {
            $table->engine = "InnoDB";
  }
srsajid
  • 1,717
  • 15
  • 12
7

You can set the engine inside Schema\Table closure.

Manolis Agkopian
  • 1,033
  • 13
  • 22
crynobone
  • 1,814
  • 12
  • 22
4

Another approach (for whose that don't uses database.php) is to include on .env file:

DB_ENGINE=InnoDB

Remember to check if you have 'engine' => env('DB_ENGINE', null), on your database.php

Tiago Gouvêa
  • 15,036
  • 4
  • 75
  • 81
4

I found @ThomasLAURENT is the best solution but what about the existing tables I have in my database.

Working around.

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class ConvertTablesIntoInnoDB extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        $tables = [
            'users',
            'products',
        ];
        foreach ($tables as $table) {
            DB::statement('ALTER TABLE ' . $table . ' ENGINE = InnoDB');
        }
    }
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        $tables = [
            'users',
            'products',
        ];
        foreach ($tables as $table) {
            DB::statement('ALTER TABLE ' . $table . ' ENGINE = MyISAM');
        }
    }
}

This will allow us to convert all the tables and roll-back them when I need.

Yousef Altaf
  • 2,631
  • 4
  • 46
  • 71
3

I would recommend to update your Mysql to 5.5 or higher. The default storage engine for Mysql now is InoDB

Before MySQL 5.5.5, MyISAM is the default storage engine. (The default was changed to InnoDB in MySQL 5.5.5.) MyISAM is based on the older (and no longer available) ISAM storage engine but has many useful extensions.

http://dev.mysql.com/doc/refman/5.5/en/myisam-storage-engine.html

Once done, you can easily map relationships within the entity classes via Laravel

Pradeep
  • 9,667
  • 13
  • 27
  • 34
Akash
  • 4,956
  • 11
  • 42
  • 70
  • If the tables exist, changing the version to get a different default will not cause the existing tables to change. You need `ALTER TABLE t ENGINE=InnoDB;` (for each `t`). – Rick James Jan 13 '17 at 20:48
2
Schema::create('users', function($table)
{
    $table->engine = 'InnoDB';

    $table->string('email');
});

Like document Laravel: https://laravel.com/docs/4.2/schema#storage-engines

P/s: Thanks @Nico Haase for reminding me to provide the link.

  • Is there any way for a global definition, such that it works for **all** tables? What's that `email` column used for? – Nico Haase Mar 14 '19 at 15:08
  • @NicoHaase, that email column is just an example & to answer your question `Yes` you can define it globally. To do that go to `config/database.php` and under `mysql` key change `'engine' => null,` to `'engine' => 'InnoDB',`. – Mr.Singh Oct 11 '19 at 07:30
  • 1
    This looks like copy&paste from https://laravel.com/docs/4.2/schema#storage-engines - if you already do this, you should at least provide a link – Nico Haase Oct 11 '19 at 07:35
1

Use InnoDb tables on the server side it's best way to success. Use MySQL Workbench. It easy in Workbench. And, if you want read the native manual

RDK
  • 4,540
  • 2
  • 20
  • 29
0

The best approach for those that don't use database.php) is to include on the .env file: DB_ENGINE=InnoDB. Remember to check if you have 'engine' => env('DB_ENGINE', null) on your database.php