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


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

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']);
    });

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


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

eine mündliche Erklärung wäre eine hilfreiche Ergänzung zu Ihrer Antwort sein
con
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.