web-dev-qa-db-ja.com

Yii2の移行を使用して複合主キーを作成する方法は?

yii migrateを実行しようとしましたが、次のエラーが表示されました:

create table news-cate ...Exception: 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
The SQL being executed was: CREATE TABLE `news-cate` (
        `news-id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
        `cate-id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY

これが私のコードです:

class m150821_083020_create_newscate_table extends Migration
{
    public function safeUp()
    {
        $this->createTable('news-cate', [
            'news-id' => $this->primaryKey(),
            'cate-id' => $this->primaryKey(),
        ]);
        $this->addForeignKey("fk_news_cate_nid", "news-cate", "news-id", "news", "id", "RESTRICT", "CASCADE");
        $this->addForeignKey("fk_news_cate_cid", "news-cate", "cate-id", "category", "id", "RESTRICT", "CASCADE");
    }

    public function safeDown()
    {
        echo "m150821_083020_create_newscate_table cannot be reverted.\n";
        $this->dropTable("news-cate");
        return false;
    }
}

それでは、Yii2の移行を使用して複合主キーを作成する方法は?

16
user1571234

[〜#〜]更新[〜#〜]

yiiバージョン2.06以降では、新しいスキーマビルダーを使用できます。

<?php
use yii\db\Migration;
...
$this->createTable('news-cate', [
    'news-id' => $this->integer()->notNull(),
    'cate-id' => $this->integer()->notNull(),
]);
$this->addPrimaryKey('news-cate_pk', 'news-cate', ['news-id', 'cate-id']);
...
?>

元の回答

テーブルの作成で主キーを追加せず、タイプを宣言するだけです。

use yii\db\Schema;

,,,

$this->createTable('news-cate', [
    'news-id' => Schema::TYPE_INTEGER . ' NOT NULL',
    'cate-id' => Schema::TYPE_INTEGER . ' NOT NULL',
]);

その後、次のように複合主キーを追加できます。

$this->addPrimaryKey('news-cate_pk', 'news-cate', ['news-id', 'cate-id']);

複数の列の場合、配列は addPrimaryKey() メソッドで許可されます。

これは、生のSQLを記述するよりも優れています。

24
arogachev

この方法を試してください

public function safeUp()
{
   $this->createTable('news-cate', [
        'news-id' =>'int NOT NULL',
        'cate-id' =>'int NOT NULL',
        'PRIMARY KEY (news-id,cate-id)'
      ]);
    $this->addForeignKey("fk_news_cate_nid", "news-cate", "news-id", "news", "id", "RESTRICT", "CASCADE");
    $this->addForeignKey("fk_news_cate_cid", "news-cate", "cate-id", "category", "id", "RESTRICT", "CASCADE");
}
7
scaisEdge

理想的には、2つのテーブルのジャンクションを作成します。 Yiiコマンドラインを使用して、1つのライナーコードだけで移行を作成できます。

php yii migrate/create create_junction_table_for_post_and_tag_tables --fields="created_at:bigInteger"

それは生成されます:

/**
 * Handles the creation for table `post_tag`.
 * Has foreign keys to the tables:
 *
 * - `post`
 * - `tag`
 */
class m160328_041642_create_junction_table_for_post_and_tag_tables extends Migration
{
    /**
     * @inheritdoc
     */
    public function up()
    {
        $this->createTable('post_tag', [
            'post_id' => $this->integer(),
            'tag_id' => $this->integer(),
            'created_at' => $this->dateTime(),
            'PRIMARY KEY(post_id, tag_id)',
        ]);

        // creates index for column `post_id`
        $this->createIndex(
            'idx-post_tag-post_id',
            'post_tag',
            'post_id'
        );

        // add foreign key for table `post`
        $this->addForeignKey(
            'fk-post_tag-post_id',
            'post_tag',
            'post_id',
            'post',
            'id',
            'CASCADE'
        );

        // creates index for column `tag_id`
        $this->createIndex(
            'idx-post_tag-tag_id',
            'post_tag',
            'tag_id'
        );

        // add foreign key for table `tag`
        $this->addForeignKey(
            'fk-post_tag-tag_id',
            'post_tag',
            'tag_id',
            'tag',
            'id',
            'CASCADE'
        );
    }

    /**
     * @inheritdoc
     */
    public function down()
    {
        // drops foreign key for table `post`
        $this->dropForeignKey(
            'fk-post_tag-post_id',
            'post_tag'
        );

        // drops index for column `post_id`
        $this->dropIndex(
            'idx-post_tag-post_id',
            'post_tag'
        );

        // drops foreign key for table `tag`
        $this->dropForeignKey(
            'fk-post_tag-tag_id',
            'post_tag'
        );

        // drops index for column `tag_id`
        $this->dropIndex(
            'idx-post_tag-tag_id',
            'post_tag'
        );

        $this->dropTable('post_tag');
    }
}

そして、テーブル構造はそのようになります:

+------------+------------+------+-----+---------+-------+
| Field      | Type       | Null | Key | Default | Extra |
+------------+------------+------+-----+---------+-------+
| post_id    | int(11)    | NO   | PRI | NULL    |       |
| tag_id     | int(11)    | NO   | PRI | NULL    |       |
| created_at | bigint(20) | YES  |     | NULL    |       |
+------------+------------+------+-----+---------+-------+

下記のURLを参照してください。

http://www.yiiframework.com/doc-2.0/guide-db-migrations.html

1