Just on a side note, shouldn't
$table->bigInteger('country_id')->foreign()->references('id')->on('timezones');
be something like
$table->bigInteger('country_id')->foreign()->references('id')->on('countries');
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
Hi All,
Appreciate any insight you could provide on the following:
Many thanks Nolan
Foreign Keys When should you use them? i.e. even if I’m not using cascading should I still use them for performance reasons?
Pivot Tables As per the example below should I be using pivot tables for all of my foreign relationships e.g. industries, country, etc.? If, not, are there any sort of guidelines?
Index usage: I’ve tried to find some guidelines, but they seem to be all over the place. I get that they increase performance, but that it come with overhead, but are there any guidelines. Example - should I place indexes on foreign keys?
EDIT - changed countries per comment below
Schema::create('companies', function(Blueprint $table) {
$table->increments('id');
$table->integer('parent_id')->foreign()->references('id')->on('companies');
$table->char('name', 100)->index();
$table->char('description', 3500)->nullable();
$table->tinyInteger('type')->unsigned();
$table->integer('size_employees')->unsigned();
$table->integer('size_revenue')->unsigned();
$table->bigInteger('industry_id')->foreign()->references('id')->on('industries');
$table->bigInteger('timezone_id')->foreign()->references('id')->on('timezones');
$table->bigInteger('country_id')->foreign()->references('id')->on('countries');
$table->char('tax_id', 20)->nullable()->unique();
$table->char('vat_id', 20)->nullable()->unique();
$table->char('url', 255);
$table->tinyInteger('status')->unsigned();
$table->char('slug', 100);
$table->timestamp('founded');
$table->timestamps();
});
@nolros A few things (talking MySQL):
foreign key columns are indexed. You don't need to specify anything in the migration, MySQL will do it, no exceptions.
primary key and foreign key field types must match, otherwise you get db error when creating the constraint (running migration). Thus this might be wrong:
$table->integer('parent_id');
$table->bigInteger('industry_id');
$table->bigInteger('timezone_id');
$table->bigInteger('country_id');
unless your id columns on the referenced tables are integer and bigInteger accordingly. Mind that default increments('id') create unsignedInteger type.
All your foreign keys fail silently, ie. migration runs w/o errors but doesn't create the foreign key constraints at all. You want this:
$table->integer('parent_id'); // or unsignedInteger like mentioned above
$table->foreign('parent_id')->references('id')->on('companies');
Pivot tables are required for many-to-many relationships, end of story. You can use them in a few other cases, like self referencing relationships etc, but these are edge-cases - don't bother.
Indexes are good for big tables. It's not something you can answer just like that - index here, index there. Sometimes index increases performance greatly, sometimes it's redundant.
Single column indexes are used in where clauses, order by and group by clauses, min/max. Compound indexes are a bit different, ie. the order of specified columns matters, also leftmost columns must be used and so on and so forth.
To sum up, use index on columns that are likely to be used in where on the tables that will grow. Then, when the time comes that you need to optimize your queries, read http://dev.mysql.com/doc/refman/5.5/en/optimization-indexes.html and make adjustments ;)
Please or to participate in this conversation.