Laravel eloquent 自身与 FK 和 INDEX 的关系

Laravel eloquent self realtion with FK and INDEX

我使用 mysql 8 (image: mysql:8.0)。我想使用 FK 和 INDEX 为用户 table 与用户 table 创建关系并面对奇怪的行为,为什么我的 FK 没有创建以及如何在创建自我关系时添加索引 o FK 和 INDEX don不需要吗?

我的迁移

/**
 * Run the migrations.
 *
 * @return void
 */
public function up()
{
    if (!Schema::hasColumn('users', 'agent_id')) {
        Schema::table('users', function (Blueprint $table) {
            $table->integer('agent_id')->nullable(true);
            $table->foreign('agent_id')->references('id')
                ->on('users');

        });
    }
}

/**
 * Reverse the migrations.
 *
 * @return void
 */
public function down()
{
    if (Schema::hasColumn('users', 'agent_id')) {
        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn('agent_id');
        });
    }

}

那我的table在sql中的表现如何

create table users
(
    id                     bigint unsigned auto_increment
        primary key,
    email                  varchar(191)            not null,
    email_verified_at      timestamp               null,
    password               varchar(191)            not null,
    remember_token         varchar(100)            null,
    created_at             timestamp               null,
    updated_at             timestamp               null,
    ssn                    varchar(50)  default '' not null,
    first_name             varchar(100) default '' not null,
    last_name              varchar(100) default '' not null,
    phone                  varchar(50)  default '' not null,
    cellphone              varchar(50)  default '' not null,
    address                varchar(100) default '' not null,
    coaddress              varchar(100) default '' not null,
    zip                    varchar(50)  default '' not null,
    city                   varchar(50)  default '' not null,
    country                varchar(50)  default '' not null,
    subscribe_to_marketing tinyint(1)   default 0  not null,
    prevent_login          timestamp               null,
    last_logged_in         timestamp               null,
    deleted_at             timestamp               null,
    agent_id               int                     null,
    constraint users_email_unique
        unique (email)
);

我尝试像那样添加索引但遇到错误

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        if (!Schema::hasColumn('users', 'agent_id')) {
            Schema::table('users', function (Blueprint $table) {
                $table->integer('agent_id')->nullable(true);
                $table->foreign('agent_id')->references('id')
                    ->on('users');

            });
        }

        Schema::table('users', function (Blueprint $table) {
            if (!collect(DB::select("SHOW INDEXES FROM users"))->pluck('Key_name')->contains('users_agent_id_index')) {
                $table->index('agent_id');
            }
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        if (Schema::hasColumn('users', 'agent_id')) {
            Schema::table('users', function (Blueprint $table) {
                $table->dropColumn('agent_id');
            });
        }


        Schema::table('users', function (Blueprint $table) {
            if (collect(DB::select("SHOW INDEXES FROM users"))->pluck('Key_name')->contains('users_agent_id_index')) {
                $table->dropIndex('users_agent_id_index');
            }
        });
    }
}

错误

 SQLSTATE[HY000]: General error: 3780 Referencing column 'agent_id' and referenced column 'id' in foreign key constraint 'users_agent_id_foreign' are incompatible. (SQL: alter table `users` add constraint `users_agent_id_foreign` foreign key (`agent_id`) references `users` (`id`))

users table 上的 id 字段是无符号大整数,而 agent_id 您尝试创建的字段是一个整数。将 agent_id 更改为 $table->unsignedBigInteger('agent_id')->nullable(true);

错误提示您的 idagent_id 列不兼容,因为 users table 的 idbigint unsigned 而你的 agent_idint。 更改线路:

$table->integer('agent_id')->nullable(true);

作者:

 $table->unsignedBigInteger('agent_id')->nullable(true);