Laravel迁移创建subscriptions表时触发SQL语法错误求助
首先,先看看你遇到的错误提示:
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 (SQL: create table subscriptions (id bigint unsigned not null auto_increment primary key, month int unsigned not null auto_increment primary key, price int unsigned not null auto_increment primary key, status tinyint not null default '1', created_at timestamp null, updated_at timestamp null) default character set utf8mb4 collate 'utf8mb4_unicode_ci')
问题根源其实很简单——你误用了Laravel Schema构建器中integer()方法的参数!
你写的代码里:
$table->integer('month',4); $table->integer('price',7);
这里的第二个参数不是字段长度,而是用来设置该字段是否为自增字段(默认值是false)。当你传入4和7这种非布尔值时,Laravel会把它当作true处理,这就导致month和price都被设置成了自增主键,再加上默认的id自增主键,一个表里出现了三个自增主键,这明显违反了MySQL的规则(一个表只能有一个自增列,且必须是主键),所以触发了这个错误。
修正后的代码
如果你的需求是设置字段的显示长度(注意:MySQL中int类型的长度只是显示宽度,不影响实际存储范围),应该用->length()链式调用;如果需要无符号整数,可以用unsignedInteger()方法。以下是正确的写法:
Schema::create('subscriptions', function (Blueprint $table) { $table->id(); // 设置month为无符号整数,显示长度4 $table->unsignedInteger('month')->length(4); // 设置price为无符号整数,显示长度7 $table->unsignedInteger('price')->length(7); $table->tinyInteger('status')->default(1); $table->timestamps(); });
或者如果你不需要特意设置显示长度,直接写$table->unsignedInteger('month');和$table->unsignedInteger('price');就可以了,完全不影响功能。
备注:内容来源于stack exchange,提问作者Ahsan

