Ich versuche, Fremdschlüssel in Laravel zu erstellen. Wenn ich jedoch meine Tabelle mit artisan
migriere, wird der folgende Fehler ausgegeben:
[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL
: alter table `priorities` add constraint priorities_user_id_foreign foreign
key (`user_id`) references `users` (`id`))
Mein Migrationscode lautet wie folgt:
migrationsdatei für Prioritäten
public function up()
{
//
Schema::create('priorities', function($table) {
$table->increments('id', true);
$table->integer('user_id');
$table->foreign('user_id')->references('id')->on('users');
$table->string('priority_name');
$table->smallInteger('rank');
$table->text('class');
$table->timestamps('timecreated');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
Schema::drop('priorities');
}
benutzer-Migrationsdatei
public function up()
{
//
Schema::table('users', function($table)
{
$table->create();
$table->increments('id');
$table->string('email');
$table->string('first_name');
$table->string('password');
$table->string('email_code');
$table->string('time_created');
$table->string('ip');
$table->string('confirmed');
$table->string('user_role');
$table->string('salt');
$table->string('last_login');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
Schemea::drop('users');
}
Irgendwelche Ideen, was ich falsch gemacht habe, möchte ich jetzt bekommen, da ich viele Tabellen habe, die ich zum Beispiel erstellen muss. Benutzer, Kunden, Projekte, Aufgaben, Status, Prioritäten, Typen, Teams. Idealerweise möchte ich Tabellen erstellen, die diese Daten mit den Fremdschlüsseln enthalten, z. B. clients_project
und project_tasks
usw.
Hoffe, dass mir jemand helfen kann.
Danke im Voraus.
Fügen Sie es in zwei Schritten hinzu, und es ist gut, es auch unsigniert zu machen:
public function up()
{
Schema::create('priorities', function($table) {
$table->increments('id', true);
$table->integer('user_id')->unsigned();
$table->string('priority_name');
$table->smallInteger('rank');
$table->text('class');
$table->timestamps('timecreated');
});
Schema::table('priorities', function($table) {
$table->foreign('user_id')->references('id')->on('users');
});
}
Die Frage wurde bereits beantwortet, aber ich hoffe, das könnte jemand anderem helfen.
Dieser Fehler ist für mich aufgetreten, weil ich die Migrationstabelle mit dem Fremdschlüssel erstellt habe, bevor der Schlüssel als Primärschlüssel in der ursprünglichen Tabelle vorhanden war. Migrationen werden in der Reihenfolge ausgeführt, in der sie erstellt wurden, wie durch den Dateinamen angegeben, der nach dem Ausführen von migrate:make
generiert wurde. Z.B. 2014_05_10_165709_create_student_table.php
.
Die Lösung bestand darin, die Datei mit dem Fremdschlüssel zu einem früheren Zeitpunkt umzubenennen als die Datei mit dem Primärschlüssel, wie hier empfohlen: http://forumsarchive.laravel.io/viewtopic.php?id=10246
Ich glaube, ich musste auch $table->engine = 'InnoDB';
hinzufügen
In meinem Fall bestand das Problem darin, dass die Haupttabelle bereits Datensätze enthielt und ich die neue Spalte zwang, nicht NULL zu sein. Also hat das Hinzufügen eines -> nullable () zur neuen Spalte den Trick getan. In dem Beispiel der Frage wäre so etwas:
$table->integer('user_id')->unsigned()->nullable();
oder:
$table->unsignedInteger('user_id')->nullable();
Hoffe das hilft jemandem!
In meinem Fall war das Problem beim Migrationszeitpunkt. Seien Sie vorsichtig beim Erstellen von Migrationen. Erstellen Sie zuerst die Kindermigration als die Basismigration. Denn wenn Sie zuerst eine Basismigration erstellen, bei der Ihr Fremdschlüssel nach einer untergeordneten Tabelle sucht, gibt es keine Tabelle, die dann eine Ausnahme auslöst.
Außerdem:
Wenn Sie eine Migration erstellen, wird am Anfang ein Zeitstempel angezeigt. Nehmen wir an, Sie haben eine Migration cat erstellt, so dass sie wie 2015_08_19_075954_the_cats_time.php
aussieht und diesen Code hat
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class TheCatsTime extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('cat', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->date('date_of_birth');
$table->integer('breed_id')->unsigned()->nullable();
});
Schema::table('cat', function($table) {
$table->foreign('breed_id')->references('id')->on('breed');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('cat');
}
}
Nachdem Sie die Basistabelle erstellt haben, erstellen Sie eine weitere Migration breed , die eine untergeordnete Tabelle ist. Sie hat einen eigenen Erstellungszeit- und Datumsstempel. Der Code sieht wie folgt aus:
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class BreedTime extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('breed', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('breed');
}
}
es scheint, dass diese beiden Tabellen korrekt sind, aber wenn Sie php handwerklich migrieren ausführen. Es wird eine Ausnahme ausgelöst, da bei der Migration zuerst die Basistabelle in Ihrer Datenbank erstellt wird, da Sie diese Migration zuerst erstellt haben und unsere Basistabelle eine Fremdschlüsseleinschränkung enthält, die nach einer untergeordneten Tabelle sucht und die untergeordnete Tabelle wahrscheinlich nicht vorhanden ist eine Ausnahme..
So:
Erstellen Sie zuerst eine untergeordnete Tabellenmigration.
Erstellen Sie eine Basistabellenmigration, nachdem die untergeordnete Migration erstellt wurde.
pHP Handwerker migrieren.
fertig wird es funktionieren
In meinem Fall ändere ich einfach die Auftragsmigrationen manuell, so dass Tabellenbenutzer zuerst erstellt werden.
In der Ordnerdatenbank/migrations/Dateiname der Migration haben Sie folgendes Format: Year_month_day_hhmmss_create_XXXX_table.php
Benennen Sie create user file einfach um, sodass das Erstellungsdatum Ihrer Tabellenprioritätstabelle später als das Benutzerdatum festgelegt wird (eine Sekunde später reicht aus).
In meinem Fall bestand das Problem darin, dass die automatisch generierte Migration für die Tabelle users
festgelegt wurde
...
$table->bigIncrements('id');
...
Also musste ich den Spaltentyp ändern
$table->bigInteger('id');
um meine Migration mit dem Fremdschlüssel zum Laufen zu bringen.
Dies mit laravel 5.8.2
In laravel 5.8 verwendet die users_table den Datentyp bigIncrements('id')
für den Primärschlüssel. Wenn Sie eine Fremdschlüsseleinschränkung referenzieren möchten, muss Ihre user_id
-Spalte vom Typ unsignedBigInteger('user_id')
sein.
Die Verwendung von Laravel 5.3 hatte das gleiche Problem.
Die Lösung bestand darin, unsignedInteger anstelle von Integer ('name') -> unsigned () zu verwenden.
Das hat also funktioniert
$table->unsignedInt('column_name');
$table->foreign('column_name')->references('id')->on('table_name');
Der Grund, warum dies funktioniert hat, ist die Tatsache, dass bei Verwendung von integer ('name') -> unsigned die in der Tabelle erstellte Spalte Länge 11 hatte, bei Verwendung von unsigedInteger ('name') die Spalte jedoch Länge hatte 10
Länge 10 ist die Länge für Primärschlüssel, wenn Laravel verwendet wird, sodass die Spaltenlänge übereinstimmt.
Für das Hinzufügen von Fremdschlüsseleinschränkungen in Laravel funktionierte für mich Folgendes:
Erstellen Sie die Spalte als Fremdschlüssel wie folgt:
$ table-> integer ('column_name') -> unsigned ();
Hinzufügen der Beschränkungslinie unmittelbar nach (1), d. H.
$ table-> integer ('column_name') -> unsigned (); $ table-> foreign ('column_name') -> Referenzen ('pk_of_other_table') -> on ('other_table');
Wir können keine Beziehungen hinzufügen, es sei denn, es werden verknüpfte Tabellen erstellt. Laufende Migrationsreihenfolge nach Datum der Migrationsdateien. Wenn Sie also eine Beziehung mit einer Tabelle erstellen möchten, die in der zweiten Migrationsdatei vorhanden ist, schlägt diese fehl.
Ich war mit dem gleichen Problem konfrontiert, also habe ich endlich eine weitere Migrationsdatei erstellt, um alle Beziehungen anzugeben.
Schema::table('properties', function(Blueprint $table) {
$table->foreign('user')->references('id')->on('users')->onDelete('cascade');
$table->foreign('area')->references('id')->on('areas')->onDelete('cascade');
$table->foreign('city')->references('id')->on('cities')->onDelete('cascade');
$table->foreign('type')->references('id')->on('property_types')->onDelete('cascade');
});
Schema::table('areas', function(Blueprint $table) {
$table->foreign('city_id')->references('id')->on('cities')->onDelete('cascade');
});
Ab Laravel 5.8 verwenden Migrationsstubs standardmäßig die bigIncrements-Methode für ID-Spalten. Bisher wurden ID-Spalten mit der Methode increments erstellt.
Dies wirkt sich nicht auf vorhandenen Code in Ihrem Projekt aus. Beachten Sie jedoch, dass die Fremdschlüsselspalten vom selben Typ sein müssen . Daher kann eine mit der Methode increments erstellte Spalte nicht auf eine mit der Methode bigIncrements erstellte Spalte verweisen.
Quelle: Migrations & bigIncrements
Stellen Sie sich vor, Sie erstellen eine einfache rollenbasierte Anwendung und müssen in der Tabelle PIVOT "role_user" auf user_id verweisen.
2019_05_05_112458_create_users_table.php
// ...
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('full_name');
$table->string('email');
$table->timestamps();
});
}
2019_05_05_120634_create_role_user_pivot_table.php
// ...
public function up()
{
Schema::create('role_user', function (Blueprint $table) {
// this line throw QueryException "SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint..."
// $table->integer('user_id')->unsigned()->index();
$table->bigInteger('board_id')->unsigned()->index(); // this is working
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
}
Wie Sie sehen, löst die kommentierte Zeile eine Abfrageausnahme aus, da, wie in den Upgrade - Hinweisen erwähnt, Fremdschlüsselspalten vom gleichen Typ sein müssen , daher müssen Sie entweder den Vorgängerschlüssel (in In diesem Beispiel ist es user_id) bis bigInteger in role_user Tabelle oder ändern Sie bigIncrements Methode in increments Methode in Benutzer Tabelle und verwenden Sie die kommentierte Zeile in der Pivot-Tabelle, es liegt an Ihnen.
Ich hoffe, ich konnte Ihnen dieses Problem klären.
Ich hatte das gleiche Problem mit Laravel 5.8. Nach einem genaueren Blick auf laravel docs, dazu hier Migrations & bigIncrements . Die Art und Weise, wie ich es gelöst habe, ist das Hinzufügen von Primärschlüsseln "$ table-> bigIncrements ('id')" zu jeder einzelnen Tabelle, die mit der Tabelle "users" und ihren Zuordnungen zusammenhängt , in meinem Fall die Tabelle "Rolle" . Zuletzt hatte ich "$ table-> unsignedBigInteger" für die Zuordnung von Rollen zu Benutzern (Many-to-Many), dh Tabelle "role_user" .
1. Users table
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
2. Roles Table
Schema::create('roles', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name')->unique();
$table->string('display_name')->nullable();
$table->string('description')->nullable();
$table->timestamps();
});
3. Table role_user
Schema::create('role_user', function (Blueprint $table) {
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('role_id');
$table->foreign('user_id')->references('id')->on('users')
->onUpdate('cascade')->onDelete('cascade');
$table->foreign('role_id')->references('id')->on('roles')
->onUpdate('cascade')->onDelete('cascade');
$table->primary(['user_id', 'role_id']);
});
ich weiß, das ist eine alte Frage, aber wenn Sie mit Referenzen arbeiten, ist die richtige unterstützende Engine definiert. Setzen Sie die Innodb-Engine für beide Tabellen und denselben Datentyp für die Referenzspalten
$table->engine = 'InnoDB';
Als ich ein paar Jahre nach der ursprünglichen Frage mit Laravel 5.1 hierher kam, hatte ich den gleichen Fehler, da meine Migrationen vom Computer mit dem gleichen Datumscode generiert wurden. Ich habe alle vorgeschlagenen Lösungen durchgearbeitet und dann die Fehlerquelle gefunden.
Ich bin der Meinung, dass die richtige Antwort der folgenden Laracasts ähnelt und Vickies Antwort ähnlich ist, mit der Ausnahme, dass Sie keinen separaten Schemaaufruf hinzufügen müssen. Sie müssen den Tisch nicht auf Innodb einstellen, ich gehe davon aus, dass Laravel dies jetzt tut.
Die Migrationen müssen lediglich zeitlich korrekt festgelegt werden. Dies bedeutet, dass Sie den Datumscode (später) im Dateinamen für Tabellen ändern, für die Sie Fremdschlüssel benötigen. Alternativ oder zusätzlich senken Sie den Datecode für Tabellen, die keine Fremdschlüssel benötigen.
Der Vorteil bei der Änderung des Datumscodes besteht darin, dass Ihr Migrationscode einfacher zu lesen und zu verwalten ist.
Bisher funktioniert mein Code durch Anpassen des Zeitcodes an Push-Back-Migrationen, die Fremdschlüssel benötigen.
Ich habe jedoch Hunderte von Tabellen, und am Ende habe ich nur eine letzte Tabelle für Fremdschlüssel. Nur um die Dinge zum Fließen zu bringen. Ich gehe davon aus, dass ich sie in die richtige Datei ziehen und den Datumscode ändern werde, während ich sie teste.
So ein Beispiel: Datei 2016_01_18_999999_create_product_options_table. Hier muss die Produkttabelle erstellt werden. Schauen Sie sich die Dateinamen an.
public function up()
{
Schema::create('product_options', function (Blueprint $table) {
$table->increments('id');
$table->integer('product_attribute_id')->unsigned()->index();
$table->integer('product_id')->unsigned()->index();
$table->string('value', 40)->default('');
$table->timestamps();
//$table->foreign('product_id')->references('id')->on('products');
$table->foreign('product_attribute_id')->references('id')->on('product_attributes');
$table->foreign('product_id')->references('id')->on('products');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('product_options');
}
die Produkttabelle: Diese muss zuerst migriert werden. 2015_01_18_000000_create_products_table
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->increments('id');
$table->string('style_number', 64)->default('');
$table->string('title')->default('');
$table->text('overview')->nullable();
$table->text('description')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('products');
}
Und zum Schluss noch die Datei, die ich vorübergehend verwende, um Probleme zu lösen, die ich umgestalten werde, wenn ich Tests für die Modelle schreibe, die ich 9999_99_99_999999_create_foreign_keys.php nannte. Diese Schlüssel werden kommentiert, als ich sie herausgezogen habe, aber Sie bekommen den Punkt.
public function up()
{
// Schema::table('product_skus', function ($table) {
// $table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
// });
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
// Schema::table('product_skus', function ($table)
// {
// $table->dropForeign('product_skus_product_id_foreign');
// });
Dieser Fehler trat für mich auf, weil - während die Tabelle, die ich zu erstellen versuchte, InnoDB war, die Fremdtabelle, mit der ich sie in Beziehung zu setzen versuchte, eine MyISAM-Tabelle war!
vergewissern Sie sich, dass Ihre Vorspannungsspalte eine breite Palette von Vorspannungsspalten aufweist
Ich meine, dass Ihr Vorlageschlüssel (in der zweiten Tabelle) derselbe Typ Ihres Pont-Partizipationsschlüssels sein muss (in der ersten Tabelle)
ihr Zeigerhauptschlüssel muss eine nicht signierte Methode sein. Lassen Sie mich folgendes zeigen:
in Ihrer FIRST-Migrationstabelle:
$table->increments('column_name'); //is INTEGER and UNSIGNED
in Ihrer zweiten Migrationstabelle:
$table->integer('column_forein_name')->unsigned(); //this must be INTEGER and UNSIGNED
$table->foreign('column_forein_name')->references('column_name')->on('first_table_name');
EIN ANDERES BEISPIEL, DEN UNTERSCHIED ZU SEHEN
in Ihrer FIRST-Migrationstabelle:
$table->mediumIncrements('column_name'); //is MEDIUM-INTEGER and UNSIGNED
in Ihrer zweiten Migrationstabelle:
$table->mediumInteger('column_forein_name')->unsigned(); //this must be MEDIUM-INTEGER and UNSIGNED
$table->foreign('column_forein_name')->references('column_name')->on('first_table_name');
Eine Sache, die mir aufgefallen ist, ist, dass, wenn die Tabellen eine andere Engine als die Fremdschlüsseleinschränkung verwenden, dies nicht funktioniert.
Zum Beispiel, wenn eine Tabelle verwendet:
$table->engine = 'InnoDB';
Und die anderen Verwendungen
$table->engine = 'MyISAM';
würde einen Fehler erzeugen:
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint
Sie können dies beheben, indem Sie InnoDB am Ende Ihrer Tabellenerstellung wie folgt hinzufügen:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedInteger('business_unit_id')->nullable();
$table->string('name', 100);
$table->foreign('business_unit_id')
->references('id')
->on('business_units')
->onDelete('cascade');
$table->timestamps();
$table->softDeletes();
$table->engine = 'InnoDB'; # <=== see this line
});
}
Ich hatte dieses Problem mit laravel 5.8 und das Hinzufügen dieses Codes an der Stelle, an der ich user_id hinzufüge, hat den Trick gemacht.
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
dann lief ich $ php artisan migrate:fresh
Ich bin verrückt geworden, ich hatte gerade einen Tippfehler:
unsinged()
anstelle von unsigned()
.
In meinem Fall habe ich auf eine Ganzzahlid
-Spalte in einer Zeichenfolgeuser_id
-Spalte verwiesen. Ich habe mich verändert:
$table->string('user_id')
zu:
$table->integer('user_id')->unsigned();
Hoffe es hilft jemandem!
Sie können einen booleschen Parameter direkt in einer Ganzzahlspalte übergeben, der besagt, dass er nicht signiert sein sollte oder nicht. In Laravel 5.4 löste folgender Code mein Problem.
$table->integer('user_id', false, true);
Hier bedeutet der zweite Parameter false , dass er nicht automatisch inkrementiert werden sollte, und der dritte Parameter true bedeutet, dass er nicht vorzeichenbehaftet sein sollte. Sie können Fremdschlüsseleinschränkungen in derselben Migration beibehalten oder trennen. Es funktioniert auf beiden.
Seien Sie sich bewusst: Wenn Laravel eine Tabelle mit einrichtet
$table->increments('id');
dies ist bei den meisten Migrationen Standard. Dadurch wird ein vorzeichenloses Ganzzahlfeld eingerichtet. Stellen Sie daher beim Erstellen einer Fremdreferenz aus einer anderen Tabelle in dieses Feld sicher, dass Sie in der referenzierenden Tabelle das Feld auf UnsignedInteger und nicht (was ich als ein UnsignedBigInteger-Feld angenommen habe) setzen.
Zum Beispiel: in der Migrationsdatei 2018_12_12_123456_create_users_table.php:
Schema::create('users', function (Blueprint $table){
$table->increments('id');
$table->string('name');
$table->timestamps();
Dann in der Migrationsdatei 2018_12_12_18000000_create_permissions_table.php, die die Fremdreferenz wieder für Benutzer einrichtet:
Schema::create('permissions', function (Blueprint $table){
$table->increments('id');
$table->UnsignedInteger('user_id'); // UnsignedInteger = "increments" in users table
$table->boolean('admin');
$table->boolean('enabled');
$table->timestamps();
// set up relationship
$table->foreign('user_id')->reference('id')->on('users')->onDelete('cascade');
}
In meinem Fall habe ich vergessen, Klammern für ->unsigned()
zu verwenden, wenn ich die Spalte definiert habe.
Falscher Code: $table->integer('permission_id')->unsigned;
Wahrer Code: $table->integer('permission_id')->unsigned();
So einfach !!!
wenn Sie Ihre erste 'priorities'
-Migrationsdatei erstellen, führt Laravel zuerst 'priorities'
aus, während die 'users'
-Tabelle nicht vorhanden ist.
wie kann er eine Beziehung zu einer Tabelle hinzufügen, die nicht existiert!.
Lösung: pull out _ Fremdschlüsselcodes aus der 'priorities'
-Tabelle. Ihre Migrationsdatei sollte folgendermaßen aussehen:
und fügen Sie zu einer neuen Migrationsdatei hinzu, hier ist der Name create_prioritiesForeignKey_table
und fügen Sie die folgenden Codes hinzu:
public function up()
{
Schema::table('priorities', function (Blueprint $table) {
$table->foreign('user_id')
->references('id')
->on('users');
});
}
In meinem Fall hat es nicht funktioniert, bis ich den Befehl ausgeführt habe
composer dump-autoload
auf diese Weise können Sie die Fremdschlüssel im Erstellungsschema belassen
public function up()
{
//
Schema::create('priorities', function($table) {
$table->increments('id', true);
$table->integer('user_id');
$table->foreign('user_id')->references('id')->on('users');
$table->string('priority_name');
$table->smallInteger('rank');
$table->text('class');
$table->timestamps('timecreated');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
Schema::drop('priorities');
}
Es kann auch die Reihenfolge der Erstellungsmigration sein. Wenn Sie zuerst die Prioritäten-Tabelle und nach der Benutzertabelle erstellen, ist dies falsch. Wegen der ersten Migration nach einer Benutzertabelle suchen. Sie müssen also die Reihenfolge der Migration ändern
app/database/migrations
verzeichnis
Eine Sache, die ich denke, fehlt in den Antworten hier. Bitte korrigieren Sie mich, falls ich falsch liege. Die Fremdschlüssel müssen jedoch auf dem Pivot-Tisch indiziert werden. Zumindest in mysql scheint das der Fall zu sein.
public function up()
{
Schema::create('image_post', function (Blueprint $table) {
$table->engine = 'InnoDB';
$table->increments('id');
$table->integer('image_id')->unsigned()->index();
$table->integer('post_id')->unsigned()->index();
$table->timestamps();
});
Schema::table('image_post', function($table) {
$table->foreign('image_id')->references('id')->on('image')->onDelete('cascade');
$table->foreign('post_id')->references('id')->on('post')->onDelete('cascade');
});
}
Das Wichtigste ist, dass die Fremdmethode ALTER_TABLE
verwendet, um ein bereits vorhandenes Feld in einen Fremdschlüssel umzuwandeln. Sie müssen also den Tabellentyp definieren, bevor Sie den Fremdschlüssel anwenden. Es muss sich jedoch nicht um einen separaten Schema::
-Aufruf handeln. Sie können beides innerhalb von create machen:
public function up()
{
Schema::create('priorities', function($table) {
$table->increments('id', true);
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
$table->string('priority_name');
$table->smallInteger('rank');
$table->text('class');
$table->timestamps('timecreated');
});
}
Beachten Sie auch, dass der Typ von user_id
auf unsigniert gesetzt ist, um mit dem Fremdschlüssel übereinzustimmen.
In meinem Fall wurde die für die Erstellung der referenzierten Tabelle verantwortliche Migration nicht ordnungsgemäß ausgeführt, sodass in der Datenbank keine Tabelle mit dem Fremdschlüssel referenziert wurde.
Überprüfen Sie, ob die Tabelle vorhanden ist. Falls nicht, überprüfen Sie die Migration dieser Tabelle.
Für mich wurde die Tabellenspalte, auf die sich meine untergeordnete Tabelle bezieht, nicht indiziert.
Schema::create('schools', function (Blueprint $table) {
$table->integer('dcid')->index()->unque();
$table->integer('school_number')->index(); // The important thing is that this is indexed
$table->string('name');
$table->string('abbreviation');
$table->integer('high_grade');
$table->integer('low_grade');
$table->timestamps();
$table->primary('dcid');
});
Schema::create('students', function (Blueprint $table) {
$table->increments('id');
$table->integer('dcid')->index()->unique()->nullable();
$table->unsignedInteger('student_number')->nullable();
$table->integer('schoolid')->nullable();
$table->foreign('schoolid')->references('school_number')->on('schools')->onDelete('set null');
// ...
});
Ignorieren Sie die schreckliche Benennung, es ist von einem anderen schrecklich gestalteten System.
Ich hatte den gleichen Fehler mit Laravel 5 beim Erstellen einer Pivot-Tabelle, und das Problem in meinem Fall war, dass ich keine hatte
->onDelete('cascade');
Das hat mein Problem gelöst
Die Tabelle oder der Index, auf den sich die Einschränkung bezieht, sind noch nicht vorhanden.
wie @haakym sagte, müssen Sie nur den Namen von xxx_xx_xx_xxxxxx_create_users_table umbenennen und eine frühere Datumszeit als xxx_xx_xx_xxxxxx_create_priorities_table festlegen
vergessen Sie nicht, $table->engine = 'InnoDB';
zu verwenden, wenn Sie MySql verwenden, da MyISAM Fremdschlüssel für die Einschränkung nicht unterstützt
Hinzufügen zur nsigned () -Lösung, wenn eine Datenbank mit InnoDB als Engine der Tabellen erstellt wird. Stellen Sie sicher, dass die Fremdtabelle vor den Tabellen erstellt wurde, die abhängig von der Fremdtabelle sind.
Illustration
Fall 1 (frische Tabellen)
Angenommen, Ihre Kommentartabelle hängt von Post-Tabelle (Auslands-Tabelle) ab. Sie müssen die Beitragstabelle erstellen, bevor Sie die Kommentartabelle erstellen
Fall 2 (Tabellen sind bereits vorhanden)
Angenommen, Ihre Kommentartabelle wurde vor Ihrer Beitragstabelle erstellt. Erstellen Sie Ihre Post-Tabelle in einer neuen Migrationsdatei und fügen Sie dann die Fremdschlüssel der Kommentartabelle in eine neue Migrationsdatei ein, die Sie nach der Post-Tabellen-Migration) erstellen erstellt worden.
PS
Ich nehme an, Sie benutzen Laravel
Sie sollten auf diese Weise schreiben
public function up()
{
Schema::create('transactions', function (Blueprint $table) {
$table->bigIncrements('id');
$table->float('amount', 11, 2);
$table->enum('transaction type', ['debit', 'credit']);
$table->bigInteger('customer_id')->unsigned();
$table->timestamps();
});
Schema::table('transactions', function($table) {
$table->foreign('customer_id')
->references('id')->on('customers')
->onDelete('cascade');
});
}
Das Fremdschlüsselfeld sollte ohne Vorzeichen sein, hoffe es hilft !!
wenn Sie in Ihren Tabellenprioritäten dann einen Fremdschlüssel erstellen müssen
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
sie müssen die Spalte ohne Vorzeichen erstellen, damit sie funktioniert.
Wenn keine der oben genannten Lösungen für Neulinge geeignet ist, prüfen Sie, ob beide IDs denselben Typ haben: Beide sind integer
oder beide sind bigInteger
, ... Sie können etwa Folgendes haben:
Haupttabelle (Benutzer zum Beispiel)
$table->bigIncrements('id');
Kindertabelle (Prioritäten zum Beispiel)
$table->unsignedInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
Diese Abfrage schlägt fehl, da users.id
ein BIG INTEGER
ist, wohingegen priorities.user_id
eine INTEGER
ist.
Die richtige Abfrage wäre in diesem Fall die folgende:
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
Ich denke: Der Referenzschlüssel muss "index" sein Zum Beispiel: (runter)
public function up()
{
Schema::create('clicks', function (Blueprint $table) {
$table->increments('id');
$table->string('viewer_id');
$table->integer('link_id')->index()->unsigned();
$table->string('time');
$table->timestamps();
});
Schema::table('clicks', function($table) {
$table->foreign('link_id')->references('id')->on('links')->onDelete('cascade');
});
}
viel Glück.