Laravel-Migrationen für Schema-Builder, die in zwei Spalten eindeutig sind

125

Wie kann ich eindeutige Einschränkungen für zwei Spalten festlegen?

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
quelle
1
Diese Detailgenauigkeit fehlt leider in den Laravel-Dokumenten . Es wäre so einfach, es im Vorbeigehen zu erwähnen. Details wie dieses und zum Beispiel die Tatsache, dass das Framework immer davon auszugehen scheint, dass jede Tabelle automatisch inkrementiert wird id, verleihen dem Framework ein amateurhaftes Gefühl an den Rändern. Schimpfe ich? :-(
cartbeforehorse

Antworten:

277

Der zweite Parameter besteht darin, den Namen des eindeutigen Index manuell festzulegen. Verwenden Sie ein Array als ersten Parameter, um einen eindeutigen Schlüssel über mehrere Spalten hinweg zu erstellen.

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

oder (etwas ordentlicher)

$table->unique(['mytext', 'user_id']);
Collin James
quelle
1
+1 danke dafür ... nicht sicher, wie ich es in der Dokumentation verpasst habe. Ich muss blind sein: P
OACDesigns
Ich habe auch irgendwie übersehen, dass der zweite Parameter darin besteht, den Index manuell zu benennen, und ich hatte einen automatisch generierten Indexnamen, der zu lang war. Danke mann! +1
Ciprian Mocanu
1
+1 für array(). Weil ich es ohne Array versucht habe und es nicht funktioniert hat. Kann ich den Einschränkungsnamen angeben, während der zusammengesetzte Schlüssel über den Schema-Generator ausgeführt wird?
Pankaj
Ja, das ist der zweite Parameter
Collin James
7
Die generierten Indexnamen haben das Format, table_column1_column2...n_uniquewenn jemand unsicher ist. Das Löschen der eindeutigen Einschränkung würde dann darauf verweisen, dass in$table->dropUnique('table_column1_column2...n_unique');
Jonathan
19

Einfach können Sie verwenden

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

Referenz: http://laravel.com/docs/master/migrations#creating-indexes

Als Beispiel:

    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']);
    });
İsmail Atkurt
quelle
4
Dies garantiert jedoch keine Eindeutigkeit, sondern fügt lediglich einen zusammengesetzten Index hinzu. Normalerweise möchten Sie nicht dasselbe Tag zweimal im selben Beitrag, daher ist es für diesen Anwendungsfall besser, es zu verwenden ->unique().
Okdewit
3
@ Fx32 dies tut Garantie Einzigartigkeit , weil es eine Verbund schafft Primärschlüssel (die indiziert ist). Ich stimme ->unique()jedoch immer noch zu, dass dies in dieser speziellen Frage angemessener ist, da 'mytext'dies wahrscheinlich zu einem schlechten Schlüssel führen würde, wie dies bei jedem VARCHARoder jeder TEXTSpalte der Fall wäre . ->primary([])Dies ist ideal, um die Eindeutigkeit von Ganzzahlen wie Pivot-Fremdschlüsseln sicherzustellen.
Jeff Puckett
2
Beachten
0
DB::statement("ALTER TABLE `project_majr_actvities`
               ADD UNIQUE `unique_index`(`activity_sr_no`, `project_id`)");
Rajendra Rajput
quelle
eine mündliche Erklärung wäre eine hilfreiche Ergänzung zu Ihrer Antwort sein
con