【问题标题】:Laravel and MySQL understanding Index and composite/compound indexLaravel 和 MySQL 理解索引和复合/复合索引
【发布时间】:2020-06-04 09:30:23
【问题描述】:

在 Laravel (v 6.8) 中,我为 users 表创建了以下迁移。

用户迁移

public function up()
{
    Schema::create('users', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->string('username')->unique()->index();
        $table->string('email')->unique()->index();
        $table->timestamp('email_verified_at')->nullable();
        $table->string('password')->nullable();
        $table->enum('role', ['super', 'admin', 'manager', 'subscriber', 'user'])->default('user');
        $table->boolean('is_root')->default(FALSE);
        $table->rememberToken();
        $table->timestamps();

        $table->unique(['username', 'email'], 'user_unique_credentials');
        $table->index(['username', 'email'], 'user_index_columns');
    });
}

说明

我知道index 的基本知识以及它是如何工作的,但我对个人columncomposite/compound index 上的index 不太清楚。

应用程序可能仅通过usernameemail 进行查询,或者我可能同时查询两个表。因此,正如您在我的迁移代码中看到的那样,我为每一列以及两列都设置了$this->index(),这会创建一个compoundindex

问题

我想知道我是否正确设置了所有indexes,还是按照我的方式设置是个坏主意?

如果不正确,我可以知道正确的方法吗?

【问题讨论】:

  • 我假设 usernameemail 各自是独一无二的。而不是 username,email 对是单独唯一的。因此,每个都应该是唯一的。似乎将其指定为索引也是多余的,因为 MySQL 将创建一个唯一索引来强制执行唯一性(对此不太确定 - 不太了解 Laravel - 让它创建重复索引是浪费)。
  • 自从收到任何回复后,我开始测试自己,结果和你说的一样。创建一个uniqueMySQL 为它创建一个index。所以,在这种情况下,不需要创建一个单独的index. 现在我的脑海中仍然存在一个查询是我应该创建一个复合unique 还是在单个列上,因为我必须检查两者的唯一性或单个的唯一性。据我了解,我需要申请个人和复合。但需要专家指导。

标签: mysql laravel database-migration


【解决方案1】:

@danblack感谢您的帮助。

好的,尝试使用EXPLAINquery 以各种方式设置uniqueindex 最后,我找到了如下的最终版本。

public function up()
{
    Schema::create(
        'users',
        function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('username')->unique();
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password')->nullable();
            $table->enum('role', ['super', 'admin', 'manager', 'subscriber', 'user'])->default('user');
            $table->boolean('is_root')->default(FALSE);
            $table->rememberToken();
            $table->timestamps();

            $table->unique(['username', 'email'], 'users_unique_credentials');
        }
    );
}

这样当我们查询单个列时,它将使用自己的唯一索引。当我们搜索具有多个 WHERE 子句的两列时,它将使用 compound unique 索引。

【讨论】:

  • 对复合索引的需求并不强烈。如果同时搜索,mysql 将查看其中一个索引,如果找到记录,则可以很快验证第二个值。如果该对的存在是查询的唯一部分,则 if 将(不明显)变慢,任何其他查询条件或提取的字段(如is_root)将导致完全相同的查询时间。感谢您参与做出这个回答。
  • @danblack 非常感谢您的意见。抱歉,没有提及您的帮助。我会更新的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-06
  • 1970-01-01
  • 1970-01-01
  • 2019-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多