schema builder laravel migrazioni uniche su due colonne


125

Come posso impostare un vincolo univoco su due colonne?

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
Questo livello di dettaglio è purtroppo mancante nei documenti di Laravel . Sarebbe così facile menzionarlo di sfuggita. Dettagli come questo e, ad esempio, il fatto che il framework sembra sempre presumere che ogni tabella avrà l'incremento automatico id, conferiscono al framework una sensazione amatoriale. Sto inveendo? :-(
cartbeforehorse

Risposte:


277

Il secondo parametro consiste nell'impostare manualmente il nome dell'indice univoco. Usa un array come primo parametro per creare una chiave univoca su più colonne.

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

o (un po 'più ordinato)

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

1
+1 grazie per questo ... non sono sicuro di come l'ho perso nella documentazione. Devo essere cieco: P
OACDesigns

In qualche modo ho anche perso il fatto che il secondo parametro è quello di nominare manualmente l'indice e avevo un nome di indice generato automaticamente che era troppo lungo. Grazie amico! +1
Ciprian Mocanu

1
+1 per array(). Perché ho provato senza array e non ha funzionato. posso dare il nome del vincolo durante l'esecuzione della chiave composita tramite il generatore di schemi?
Pankaj

Sì, questo è il secondo param
Collin James

7
I nomi degli indici generati sono nel formato table_column1_column2...n_uniquese qualcuno non è sicuro. L'abbandono del vincolo unico sarebbe quindi fare riferimento a quello in$table->dropUnique('table_column1_column2...n_unique');
Jonathan

19

Semplicemente puoi usare

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

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

Come esempio:

    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
Tuttavia, ciò non garantisce l'unicità, aggiunge solo un indice composto. Di solito, non vuoi lo stesso tag due volte sullo stesso post, quindi per questo caso d'uso è meglio usare ->unique().
okdewit

3
@ Fx32 questo fa garanzia unicità in quanto crea un composito chiave primaria (indicizzata). Tuttavia, sono ancora d'accordo che ->unique()è più appropriato in questa domanda specifica perché 'mytext'probabilmente sarebbe una cattiva chiave come qualsiasi colonna VARCHARo TEXT. ->primary([])sarebbe ottimo per garantire l'unicità su numeri interi come chiavi esterne pivot.
Jeff Puckett

2
Si noti inoltre che le chiavi primarie composite sono generalmente disapprovate dagli sviluppatori Laravel e non sono supportate da Eloquent - vedere github.com/laravel/framework/issues/5355
andrechalom

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

una spiegazione verbale sarebbe un'utile aggiunta alla tua risposta
con
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.