I am trying to create a Migration in Laravel but it fails saying I got multiple primary keys.
public function up()
{
Schema::create('spins', function (Blueprint $table) {
$table->integer('rid', true, true);
$table->bigInteger('pid');
$table->integer('result');
$table->integer('bet');
$table->timestamps();
$table->primary(array('rid', 'pid'));
});
}
The error:
SQLSTATE[42000]: Syntax error or access violation: 1068 Multipleprimary key defined
(SQL: alter table `spins` add primary key `spins_rid_pid_primary` (`rid`, `pid`))
Each table can only have one primary key. Access can automatically create a primary key field for you when you create a table, or you can specify the fields that you want to use as the primary key.
A composite key in SQL can be defined as a combination of multiple columns, and these columns are used to identify all the rows that are involved uniquely. Even though a single column can't identify any row uniquely, a combination of over one column can uniquely identify any record.
Migrations are optional but recommended. @ecksdee if you don't add a migration which creates a table in the database then you don't need Model in Laravel terms at all, because an Eloquent model is just an object relational mapper to a table that is part of your database.
The autoincrement of rid
is the problem (second parameter in the line below).
$table->integer('rid', true, true);
If you are using InnoDB as MySQL engine it doesn't allow composite primary keys with an auto increment.
But if you change to the MyISAM engine it would be possible to do so.
Add $table->engine = 'MyISAM';
to your Migration.
Declare the rid
field as a normal integer column
Laravel doesn't provide a method to change existing columns so you need to run a raw SQL query: DB::statement('ALTER TABLE spins MODIFY rid INTEGER NOT NULL AUTO_INCREMENT');
public function up()
{
Schema::create('spins', function (Blueprint $table) {
$table->engine = 'MyISAM';
$table->integer('rid')->unsigned();
$table->bigInteger('pid');
$table->integer('result');
$table->integer('bet');
$table->timestamps();
$table->primary(array('rid', 'pid'));
DB::statement('ALTER TABLE spins MODIFY rid INTEGER NOT NULL AUTO_INCREMENT');
});
}
Your primary key makes no sense.
You are adding a composite primary key to an auto incrementing column and another column. The auto incrementing column will already always be unique so you should just have only that be your primary key.
If you need pid
to be unique, set rid
to your primary key and add a unique key on pid
.
Schema::create('spins', function (Blueprint $table) {
$table->increments('rid');
$table->bigInteger('pid');
$table->integer('result');
$table->integer('bet');
$table->timestamps();
$table->unique('pid');
});
If for some reason you do need your primary key to include rid
and pid
, this seems to work for me.
CREATE TABLE `spins` (
`rid` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`pid` BIGINT(20) NOT NULL,
`result` INT(11) NOT NULL,
`bet` INT(11) NOT NULL,
`created_at` TIMESTAMP NOT NULL,
`updated_at` TIMESTAMP NOT NULL,
PRIMARY KEY (`rid`, `pid`)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With