Laravel 将自动将此外键添加到主键';s指数?

Laravel 将自动将此外键添加到主键';s指数?,laravel,laravel-5,eloquent,Laravel,Laravel 5,Eloquent,假设我有一个父表和一个子表,在Laravel中,对于表顺序,我的模型如下所示: public function up() { Schema::create('orders', function(Blueprint $table) { $table->integer('customer_id')->unsigned(); $table->foreign('customer_id')->references('id')->

假设我有一个父表和一个子表,在Laravel中,对于表
顺序
,我的模型如下所示:

public function up()
{
    Schema::create('orders', function(Blueprint $table)
    {
        $table->integer('customer_id')->unsigned();
        $table->foreign('customer_id')->references('id')->on('customers')->onDelete('cascade');

        $table->increments('id');
< P> >我知道雄辩者会认为<代码> ID>代码>是命令< /C> >的主键,因此在主键上会自动创建索引。

我应该如何确保
customer\u id
是主键索引的一部分,设置顺序如下:

1.  customer_id
2.  id
表格示例

      Customer
    +-------------+
    | id          | --> primary key
    |- - - - - - -|
    | name        |
    | address     |
    +-------------+
           |
           |
           |
           A
      Order     
    +------------------+        
    | customer_id (fk) | --- primary key
    | id               | --- primary key        
    |- - - - - - - - - |
    | date             |
    +------------------+ 
Eloquent会自动将此外键添加到主键的索引中吗

嗯,不是自动的,但很容易

要指定自定义主键,可以从Blueprint类调用
primary()
方法,通过$table调用。ie$table->primary()

对于单个主键,它接受一个字符串,该字符串指定要成为主键的列的名称

对于复合键,您可以传递要设为主的列的字符串数组。就你而言

$table->primary(
['id','customer\u id']
)

Eloquent会自动将此外键添加到主键的索引中吗

嗯,不是自动的,但很容易

要指定自定义主键,可以从Blueprint类调用
primary()
方法,通过$table调用。ie$table->primary()

对于单个主键,它接受一个字符串,该字符串指定要成为主键的列的名称

对于复合键,您可以传递要设为主的列的字符串数组。就你而言

$table->primary(
['id','customer\u id']

)

我决定尝试一下,看看会发生什么

从客户表开始,我运行了以下语句

CREATE TABLE customers (
    id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
    `name` VARCHAR(255),
    created_at DATETIME,
    updated_at DATETIME,
    PRIMARY KEY (id)
);
然后我创建了以下内容

CREATE TABLE orders (
    id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
    customer_id INT(11) UNSIGNED,
    created_at DATETIME,
    updated_at DATETIME,
    PRIMARY KEY (id, customer_id)
);
EXPLAIN SELECT *
FROM customers
INNER JOIN orders ON customers.id = orders.customer_id;
注意:如果使用
主键(customer\u id,id)
,将导致SQL错误。这让我相信,您尝试复制的DB2功能在MySQL上的工作方式不会完全相同,我们实际上需要一个外键

然后在用测试数据填充这些表之后,我运行以下程序

CREATE TABLE orders (
    id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
    customer_id INT(11) UNSIGNED,
    created_at DATETIME,
    updated_at DATETIME,
    PRIMARY KEY (id, customer_id)
);
EXPLAIN SELECT *
FROM customers
INNER JOIN orders ON customers.id = orders.customer_id;
这导致

+------+-------------+-----------+------+---------------+------+---------+------+--------+-------------------------------------------------+
| id   | select_type | TABLE     | TYPE | possible_keys | KEY  | key_len | ref  | ROWS   | Extra                                           |
+------+-------------+-----------+------+---------------+------+---------+------+--------+-------------------------------------------------+
|    1 | SIMPLE      | customers | ALL  | PRIMARY       | NULL | NULL    | NULL |      4 |                                                 |
|    1 | SIMPLE      | orders    | ALL  | NULL          | NULL | NULL    | NULL | 262402 | USING WHERE; USING JOIN buffer (flat, BNL JOIN) |
+------+-------------+-----------+------+---------------+------+---------+------+--------+-------------------------------------------------+
然后我添加了外键

ALTER TABLE orders ADD FOREIGN KEY customer_id (customer_id) REFERENCES customers (id) ON DELETE CASCADE ON UPDATE CASCADE;
使用相同的精确数据运行相同的精确解释查询,我现在得到结果

+------+-------------+-----------+------+---------------+-------------+---------+-----------------------+-------+-------+
| id   | select_type | TABLE     | TYPE | possible_keys | KEY         | key_len | ref                   | ROWS  | Extra |
+------+-------------+-----------+------+---------------+-------------+---------+-----------------------+-------+-------+
|    1 | SIMPLE      | customers | ALL  | PRIMARY       | NULL        | NULL    | NULL                  |     4 |       |
|    1 | SIMPLE      | orders    | ref  | customer_id   | customer_id | 4       | cookbook.customers.id | 43751 |       |
+------+-------------+-----------+------+---------------+-------------+---------+-----------------------+-------+-------+
EXPLAIN SELECT * FROM orders WHERE customer_id = 4;
正如您所看到的,当我添加外键时,计算的行要少得多,这正是我们要寻找的。让我惊讶的可能是因为我不是DBA,运行以下命令会产生相同的结果

+------+-------------+-----------+------+---------------+-------------+---------+-----------------------+-------+-------+
| id   | select_type | TABLE     | TYPE | possible_keys | KEY         | key_len | ref                   | ROWS  | Extra |
+------+-------------+-----------+------+---------------+-------------+---------+-----------------------+-------+-------+
|    1 | SIMPLE      | customers | ALL  | PRIMARY       | NULL        | NULL    | NULL                  |     4 |       |
|    1 | SIMPLE      | orders    | ref  | customer_id   | customer_id | 4       | cookbook.customers.id | 43751 |       |
+------+-------------+-----------+------+---------------+-------------+---------+-----------------------+-------+-------+
EXPLAIN SELECT * FROM orders WHERE customer_id = 4;
即使在这种情况下,复合主键也不会为您做任何事情,但是外键起到了巨大的作用


综上所述,我认为放弃复合主键是安全的,只需将
id
设置为主键,并将
customer\u id
设置为外键。这也使您能够级联删除和更新。我决定尝试一下,看看会发生什么

从客户表开始,我运行了以下语句

CREATE TABLE customers (
    id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
    `name` VARCHAR(255),
    created_at DATETIME,
    updated_at DATETIME,
    PRIMARY KEY (id)
);
然后我创建了以下内容

CREATE TABLE orders (
    id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
    customer_id INT(11) UNSIGNED,
    created_at DATETIME,
    updated_at DATETIME,
    PRIMARY KEY (id, customer_id)
);
EXPLAIN SELECT *
FROM customers
INNER JOIN orders ON customers.id = orders.customer_id;
注意:如果使用
主键(customer\u id,id)
,将导致SQL错误。这让我相信,您尝试复制的DB2功能在MySQL上的工作方式不会完全相同,我们实际上需要一个外键

然后在用测试数据填充这些表之后,我运行以下程序

CREATE TABLE orders (
    id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
    customer_id INT(11) UNSIGNED,
    created_at DATETIME,
    updated_at DATETIME,
    PRIMARY KEY (id, customer_id)
);
EXPLAIN SELECT *
FROM customers
INNER JOIN orders ON customers.id = orders.customer_id;
这导致

+------+-------------+-----------+------+---------------+------+---------+------+--------+-------------------------------------------------+
| id   | select_type | TABLE     | TYPE | possible_keys | KEY  | key_len | ref  | ROWS   | Extra                                           |
+------+-------------+-----------+------+---------------+------+---------+------+--------+-------------------------------------------------+
|    1 | SIMPLE      | customers | ALL  | PRIMARY       | NULL | NULL    | NULL |      4 |                                                 |
|    1 | SIMPLE      | orders    | ALL  | NULL          | NULL | NULL    | NULL | 262402 | USING WHERE; USING JOIN buffer (flat, BNL JOIN) |
+------+-------------+-----------+------+---------------+------+---------+------+--------+-------------------------------------------------+
然后我添加了外键

ALTER TABLE orders ADD FOREIGN KEY customer_id (customer_id) REFERENCES customers (id) ON DELETE CASCADE ON UPDATE CASCADE;
使用相同的精确数据运行相同的精确解释查询,我现在得到结果

+------+-------------+-----------+------+---------------+-------------+---------+-----------------------+-------+-------+
| id   | select_type | TABLE     | TYPE | possible_keys | KEY         | key_len | ref                   | ROWS  | Extra |
+------+-------------+-----------+------+---------------+-------------+---------+-----------------------+-------+-------+
|    1 | SIMPLE      | customers | ALL  | PRIMARY       | NULL        | NULL    | NULL                  |     4 |       |
|    1 | SIMPLE      | orders    | ref  | customer_id   | customer_id | 4       | cookbook.customers.id | 43751 |       |
+------+-------------+-----------+------+---------------+-------------+---------+-----------------------+-------+-------+
EXPLAIN SELECT * FROM orders WHERE customer_id = 4;
正如您所看到的,当我添加外键时,计算的行要少得多,这正是我们要寻找的。让我惊讶的可能是因为我不是DBA,运行以下命令会产生相同的结果

+------+-------------+-----------+------+---------------+-------------+---------+-----------------------+-------+-------+
| id   | select_type | TABLE     | TYPE | possible_keys | KEY         | key_len | ref                   | ROWS  | Extra |
+------+-------------+-----------+------+---------------+-------------+---------+-----------------------+-------+-------+
|    1 | SIMPLE      | customers | ALL  | PRIMARY       | NULL        | NULL    | NULL                  |     4 |       |
|    1 | SIMPLE      | orders    | ref  | customer_id   | customer_id | 4       | cookbook.customers.id | 43751 |       |
+------+-------------+-----------+------+---------------+-------------+---------+-----------------------+-------+-------+
EXPLAIN SELECT * FROM orders WHERE customer_id = 4;
即使在这种情况下,复合主键也不会为您做任何事情,但是外键起到了巨大的作用


综上所述,我认为放弃复合主键是安全的,只需将
id
设置为主键,并将
customer\u id
设置为外键。这还使您能够级联删除和更新。

尝试添加
$table->primary(数组('id','customer\u id')!请参阅下面的链接。我希望它能帮助你。是否有理由需要它作为主键索引的一部分?这对我来说没什么意义。如果您只是在寻找有效的联接,外键应该足够了,您可以通过执行
解释选择…
来验证它。我的想法是,当我使用
客户id
查询订单表时,MySQL通过主键索引(客户id,id)访问
订单会更快,因为
customer\u id
将是主键索引的第一列。我曾经在DB2上工作过,并且是这样做的,但我猜MySQL的做法有所不同?尝试添加
$table->primary(数组('id','customer_id')!请参阅下面的链接。我希望它能帮助你。是否有理由需要它作为主键索引的一部分?这对我来说没什么意义。如果您只是在寻找有效的联接,外键应该足够了,您可以通过执行
解释选择…
来验证它。我的想法是,当我使用
客户id
查询订单表时,MySQL通过主键索引(客户id,id)访问
订单会更快,因为
customer\u id
将是主键索引的第一列。我曾经在DB2上工作过,并且是这样做的,但我猜MySQL的做法有所不同?我尝试过
$table->primary(['id','customer\u id'),它可以工作,但我想要的是
$table->primary(['customer\u id','id')
因为当我使用
客户id
进行查询时,索引查找订单会更快,但Eloquent不允许我这样做。我收到以下消息:
SQLSTATE[42000]:语法错误或acc