унікальні на двох стовпцях міграції laravel builder схеми


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);


1
Цей рівень деталізації, на жаль, відсутній у документах Laravel . Це було б так просто згадати мимохідь. Такі деталі і, наприклад, той факт, що рамки завжди, мабуть, припускають, що кожна таблиця матиме автоматичне збільшення id, надають рамці аматорське відчуття по краях. Я збиваю? :-(
cartbeforehorse

Відповіді:


277

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

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

або (трохи акуратніше)

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

1
+1 дякую за це ... не впевнений, як я пропустив це в документації. Я повинен бути сліпим: P
OACDesigns

Я також якось пропустив той факт, що другий парам - це вручну назвати індекс, і у мене було автоматично сформоване ім'я індексу, яке було занадто довгим. Дякую, чоловіче! +1
Ciprian Mocanu

1
+1 для array(). Тому що я спробував без масиву і не вийшло. чи можу я дати ім’я обмеження під час запуску складеного ключа через конструктор схеми?
Панкай

Так, це другий парам
Колін Джеймс

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, і вони не підтримуються Eloquent - див. Github.com/laravel/framework/isissue/5355
andrechalom

0
DB::statement("ALTER TABLE `project_majr_actvities`
               ADD UNIQUE `unique_index`(`activity_sr_no`, `project_id`)");

словесне пояснення було б корисним доповненням до вашої відповіді
con
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.