Миграция Laravel в построителе схем уникальна для двух столбцов

125

Как я могу установить уникальные ограничения для двух столбцов?

class MyModel extends Migration {
  public function up()
  {
    Schema::create('storage_trackers', function(Blueprint $table) {
      $table->increments('id');
      $table->string('mytext');
      $table->unsignedInteger('user_id');
      $table->engine = 'InnoDB';
      $table->unique('mytext', 'user_id');
    });
  }
}

MyMode::create(array('mytext' => 'test', 'user_id' => 1);
// this fails??
MyMode::create(array('mytext' => 'test', 'user_id' => 2);
user391986
источник
1
К сожалению, такой уровень детализации отсутствует в документации Laravel . Было бы так легко упомянуть об этом мимоходом. Подобные детали и, например, тот факт, что фреймворк всегда, кажется, предполагает, что каждая таблица будет иметь автоинкремент id, придают фреймворку дилетантское ощущение по краям. Я разглагольствую? :-(
cartbeforehorse 04

Ответы:

278

Второй параметр - вручную установить имя уникального индекса. Используйте массив в качестве первого параметра для создания уникального ключа для нескольких столбцов.

$table->unique(array('mytext', 'user_id'));

или (немного аккуратнее)

$table->unique(['mytext', 'user_id']);
Коллин Джеймс
источник
1
+1 спасибо за это ... не уверен, как я это пропустил в документации. Я, должно быть, слеп: P
OACDesigns
Я также как-то упустил тот факт, что второй параметр - это вручную назвать индекс, и у меня было автоматически сгенерированное имя индекса, которое было слишком длинным. Спасибо, мужик! +1
Ciprian Mocanu
1
+1 за array(). Потому что я пробовал без массива, и это не сработало. Могу ли я указать имя ограничения при запуске составного ключа через построитель схем?
Pankaj
Да, это второй параметр
Коллин Джеймс
7
Сгенерированные имена индексов имеют формат, table_column1_column2...n_uniqueесли кто-то не уверен. Опуская ограничение уникальности будет затем ссылки , что в$table->dropUnique('table_column1_column2...n_unique');
Джонатану
19

Просто вы можете использовать

$table->primary(['first', 'second']);

Ссылка: http://laravel.com/docs/master/migrations#creating-indexes

Например:

    Schema::create('posts_tags', function (Blueprint $table) {

        $table->integer('post_id')->unsigned();
        $table->integer('tag_id')->unsigned();

        $table->foreign('post_id')->references('id')->on('posts');
        $table->foreign('tag_id')->references('id')->on('tags');

        $table->timestamps();
        $table->softDeletes();

        $table->primary(['post_id', 'tag_id']);
    });
Исмаил Аткурт
источник
4
Однако это не гарантирует уникальности, а просто добавляет составной индекс. Обычно вам не нужен один и тот же тег дважды в одном и том же сообщении, поэтому для этого варианта использования лучше использовать ->unique().
okdewit
3
@ Fx32 это делает гарантию уникальности , поскольку она создает составной первичный ключ (который индексируется). Тем не менее, я все же согласен, что ->unique()это более уместно в этом конкретном вопросе, потому 'mytext'что, вероятно, будет иметь плохой ключ, как и любой столбец VARCHARили TEXT. ->primary([])отлично подходит для обеспечения уникальности целых чисел, таких как внешние ключи сводной таблицы.
Джефф Пакетт,
2
Также обратите внимание , что составные первичные ключи , как правило , с неодобрением разработчиками Laravel, и они не поддерживаются красноречив - см github.com/laravel/framework/issues/5355
andrechalom
0
DB::statement("ALTER TABLE `project_majr_actvities`
               ADD UNIQUE `unique_index`(`activity_sr_no`, `project_id`)");
Раджендра Раджпут
источник
устное объяснение было бы полезным дополнением к вашему ответу
con