问题
I'm using the Laravel 4.2 schema builder to create some tables referencing each other, and am having some issues.
I have a simplified ERD. Note that only relevant columns are shown:

Note that I cannot modify the tblcurrencies
and tbldomains
tables in any way, since I am developing a module to hook into an existing system.
I am trying to achieve the following:
- The
extensions
table contains extra information about rows in thetbldomains
table - The
prices
table contains pricing information about a domain in a certain currency, with the additional type value (registration, renewal, transfer) - I want to use foreign keys so that I can cascade deletions.
Currently, I use the following code to create the two tables:
Capsule::schema()->create('extensions', function ($table) {
$table->engine = 'InnoDB';
$table->integer('relid', 10);
// ...
$table->primary(['relid']);
$table->foreign('relid')->references('id')->on('tbldomains')->onDelete('cascade');
});
Capsule::schema()->create('prices', function ($table) {
$table->engine = 'InnoDB';
$table->integer('relid', 10);
$table->integer('currency', 10);
$table->enum('type', ['domainregister', 'domainrenew', 'domaintransfer']);
// ...
$table->primary(['relid', 'currency', 'type']);
$table->foreign('relid')->references('relid')->on('extensions')->onDelete('cascade');
$table->foreign('currency')->references('id')->on('tblcurrencies')->onDelete('cascade');
});
The creation script for the prices
table results in the following SQL query:
create table `prices` (`relid` int unsigned null auto_increment primary key, `currency` int unsigned null auto_increment primary key, `type` enum('domainregister', 'domainrenew', 'domaintransfer') not null, ...) engine = InnoDB
Which in turn results in the following error:
SQLSTATE[42000]: Syntax error or access violation: 1075 Incorrect table definition; there can be only one auto column and it must be defined as a key
I have also tried setting the primary keys as unique instead, figuring that perhaps Laravel automatically set primary integer keys as auto increment.
Furthermore, I tried setting the columns as unsigned
and index
, as suggested by this and this answer
How do I stop the schema builder from setting the relid
and currency
fields to auto increment, since they are simply foreign keys?
回答1:
based on Laravel Documentation Api on the below link, only string()
method can have length attribute.
Laravel Documentation Api
So to make those two column unsigned
and not primary key
or auto increment
make the following change:
from this:
$table->integer('relid', 10);
$table->integer('currency', 10);
to this:
$table->integer('relid', false, true);
$table->integer('currency', false, true);
Because as per the documentation the integer()
method syntax is:
integer(string $column, bool $autoIncrement = false, bool $unsigned = false)
And what you did is you assigned a value (10) to a boolean variable ($autoIncrement) which will always returns true on this case. For further proof of this, please refer back to the below link from php.net. php.net Boolean
I had the same issue before, and when I start referring back Laravel documentation 90% of confusion will be cleared. Hope this helps you.
Note: you can also use unsignedInteger()
method, which i think it's more explicit and easier to remember:
unsignedInteger(string $column, bool $autoIncrement = false)
So the code will be like so:
$table->unsignedInteger('relid');
$table->unsignedInteger('currency');
来源:https://stackoverflow.com/questions/41504219/laravel-schema-builder-primary-key-as-foreign-key