Taşıma: Yabancı anahtar kısıtlaması eklenemiyor


207

Laravel içinde yabancı anahtarlar oluşturmaya çalışıyorum ancak tabloyu geçirdiğimde artisanaşağıdaki hatayı atıyorum :

[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`))     

Taşıma kodum şöyle:

öncelikler taşıma dosyası

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

kullanıcıların taşıma dosyası

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

Yanlış yaptığımla ilgili herhangi bir fikir, şu anda bunu almak istiyorum, çünkü oluşturmam gereken birçok tablo var, örneğin Kullanıcılar, Müşteriler, Projeler, Görevler, Durumlar, Öncelikler, Türler, Takımlar. İdeal yabancı anahtarlar, i..e ile bu verileri tutan tablolarını oluşturmak istediğiniz clients_projectve project_tasksvb

Umarım birisi başlamama yardımcı olabilir.

Yanıtlar:


356

İki adımda ekleyin ve imzasız yapmak da iyidir:

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

}

117
Teşekkürler Antonio! Benim için sorun, user_id sütununa unsigned () eklenmiyordu, böylece kullanıcılar tablosundaki id sütununun veri türüyle eşleşiyordu. Laravel'in artışları ('id') işlevi işaretsiz bir tamsayı oluşturur, bu nedenle yabancı anahtar sütununun da işaretsiz olması gerekir.
Brad Griffith

7
imzasız eklenmesi dışında Schema::tableyöntemine ayırmak yardımcı oldu! Teşekkürler!
patrickjason91

4
Benim için kimliği de imzasız yapmıyordu. Bahşiş için teşekkürler.
Carl Weis

6
Çözüm @BradGriffith'in yorumunda. Yukarıda belirtildiği gibi, hiç ayrılmaya gerek yok. Cevabı buna göre güncellemek daha iyi olabilir.
Matanya

11
$table->unsignedBigInteger('user_id')User.id ise kullanınbigIncrements
Maksim Ivanov

114

Soru zaten cevaplandı, ama umarım bu başka birine yardımcı olabilir.

Bu hata benim için oluştu, çünkü anahtar özgün tabloda birincil anahtar olarak var olmadan önce içinde yabancı anahtar bulunan geçiş tablosunu oluşturdum. Taşıma işlemleri, çalıştırıldıktan sonra oluşturulan dosya adıyla belirtildiği şekilde oluşturuldukları sırayla yürütülür migrate:make. Örn 2014_05_10_165709_create_student_table.php.

Çözüm, yabancı anahtarlı dosyayı, burada önerilen birincil anahtarlı dosyadan daha erken bir zamana yeniden adlandırmaktı: http://forumsarchive.laravel.io/viewtopic.php?id=10246

Ben de eklemek zorunda kaldım $table->engine = 'InnoDB';


4
Geçiş dosyasını yeniden adlandırdıktan ve aşağıdaki gibi bazı hatalar aldıktan sonra: Akış açılamadı: Böyle bir dosya veya dizin (ve eski taşıma adı görüntülenmiyor) çalıştırmanız gerekiyor: composer dump-autoload
Stelian

14
$ table-> engine = 'InnoDB'; yabancı anahtarı MySql düzeyinde zorunlu kılmak gerekir. Varsayılan laravel motoru yabancı anahtarları desteklemeyen MyIsam!
François Breton

2
Bu da benim için çalıştı, teşekkürler. Ama bu şekilde çalıştığı benim için biraz garip görünüyor. Yani, mantıklı, ancak dosyaları manuel olarak yeniden adlandırmak ve işlemde sahte tarihler bulmak dışında geçiş yürütme sırasını belirtmenin bir yolu olmalı
allisius

2
Buraya herhangi bir hata aldığım için gelmedim, ancak yabancı bir anahtar olan sütuna yanlış değerler ekleyebildim. Sonra InnoDB hakkındaki yorumu ve cevabı gördüm. Bunu bilmek güzeldi. Teşekkürler çocuklar :)
SuperNOVA

2
Taşıma işlemlerinizi oluşturma sırası, taşıma sırasında hala önemini korumaktadır. Bu sorunla karşılaştım ama bu sorunu çözdü.
mugabits

60

Laravel ^ 5.8

Laravel 5.8 itibariyle , geçiş taslakları varsayılan olarak kimlik sütunlarında bigIncrements yöntemini kullanır. Önceden, ID sütunları increments yöntemi kullanılarak oluşturuluyordu.

Bu, projenizdeki mevcut kodları etkilemez; ancak, yabancı anahtar sütunlarının aynı türde olması gerektiğini unutmayın . Bu nedenle, bir sütun artışlarla yöntem kullanılarak oluşturulan referans olamaz bigIncrements yöntemi kullanılarak oluşturulmuş bir sütun.

Kaynak: Göçler ve bigIncrements


Misal

Diyelim ki basit bir rol tabanlı bir uygulama inşa ediyoruz, ve referanslar için gereken düşünelim user_id içinde MİL tablosunun "role_user" .

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('user_id')->unsigned()->index(); // this is working
        $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
    });
}

Gördüğünüz gibi, yorumlanan satır bir sorgu istisnası atar, çünkü yükseltme notlarında belirtildiği gibi, yabancı anahtar sütunları aynı türden olmalıdır , bu nedenle yukarıdaki anahtarı değiştirmeniz gerekir (bu örnekte user_id ) BigInteger içinde role_user tablo veya değiştirmek bigIncrements için yöntemde artışlarla içinde yöntemle kullanıcıların masa ve Pivot tablodaki yorumladı satırını kullanın, bu size kalmış.


Umarım bu konuyu size açıklığa kavuşturabilirim.


1
Teşekkür ederim. Hayatımı kurtardın. Açıklamanızın ardından, yabancı anahtarımı önerdiğiniz gibi bigInteger olarak değiştirdim. Schema::table('goal_objective', function (Blueprint $table) { $table->bigInteger('job_title_id')->after('target')->unsigned()->nullable(); $table->foreign('job_title_id')->references('id')->on('job_titles')->onDelete('set null'); } İşe yaradı. Teşekkür ederim.
Bruce Tong

1
@BruceTong, yardım edebildiğim için memnunum.
chebaby

1
Evet, bu en alakalı cevap.
Mohd Abdul Mujib

1
Bu cevap çok faydalı.
Karim Pazoki

1
En iyi cevap. Thank you
VishalParkash

49

Benim durumumda, sorun ana tablonun içinde zaten kayıtların olması ve yeni sütunun NULL olmamasına zorlamaktı. Böylece yeni sütuna bir -> nullable () eklemek hile yaptı. Sorunun örneğinde şöyle bir şey olurdu:

$table->integer('user_id')->unsigned()->nullable();

veya:

$table->unsignedInteger('user_id')->nullable();

Umarım bu birine yardımcı olur!


Üst tablonuzdaki 'id' sütununun da imzasız olması gerektiğini unutmayın! $ Table-> increments ('id') gibi bir çizgi kullanma; otomatik olarak varsayılan olarak imzasız olur.
Colin Stadig

Bu benim için çalıştı. Üst tablo kimliğinin veri türünü BigIncrements'tan artışlara değiştirdim.
Emmanuel Benson

22

Benim durumumda sorun, userstablo için otomatik olarak oluşturulan geçişin ayarlanmasıydı

...
$table->bigIncrements('id');
...

Bu yüzden sütun türünü değiştirmek zorunda kaldım


$table->bigInteger('id');

yabancı anahtarla göçümü yapmak için.

Bu laravel ile 5.8.2


Yabancı anahtar sütunu, aynı sütun türüne sahip olması gerektiğinden
Daniele

9
Bu benim için çalıştı $ table-> unsignedBigInteger ('user_id'); laravel 5.8. *
Adam Winnipass

Ayrıca 5.8 ile bu sorunu vardı, bu benim için düzeltildi! Teşekkürler!
Mike Sheward

Beni uzun bir geceden kurtardı!
chq

19

Benim durumumda, göç zamanlaması dikkatli olunurken, göç oluştururken öncelikle alt göçü temel göçten daha fazla yarattık. Çünkü ilk önce yabancı anahtarınız olan temel geçiş oluşturursanız, alt tabloyu arayacak ve sonra bir istisna atacak tablo olmayacaktır.

Daha fazlası:

Taşıma oluşturduğunuzda, başında bir zaman damgası vardır. diyelim ki bir geçiş kedisi oluşturdunuz, bu şekilde görünecek 2015_08_19_075954_the_cats_time.phpve bu koda sahip olacak

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

Ve temel tabloyu oluşturduktan sonra , kendi tablo oluşturma zamanı ve tarih damgası olan alt tablo olan başka bir göç türü oluşturursunuz. Kod şöyle görünecektir:

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

Bu her iki tablo doğru gibi görünüyor ama php esnaf göç çalıştırdığınızda . Bir istisna atar çünkü taşıma ilk olarak veritabanınızda temel tabloyu oluşturur, çünkü bu geçişi önce oluşturdunuz ve temel tablonuzda alt tabloyu arayacak yabancı anahtar kısıtlaması var ve muhtemelen alt tablo yok. bir istisna..

Yani:

İlk olarak alt tablo geçişi oluşturun.

Alt geçiş oluşturulduktan sonra temel tablo geçişi oluşturun.

php zanaatkar göç.

yaptım işe yarayacak


13

Benim durumumda, sadece tablo kullanıcılarının önce yaratılması için sipariş taşımalarının manuel olarak yürütüldüğünü değiştiriyorum.

Klasör veritabanı / taşıma / taşıma dosya adınızda şu biçim vardır: year_month_day_hhmmss_create_XXXX_table.php

Tablo öncelikleri tablonuzun oluşturulma tarihi kullanıcı tarihinden daha sonra ayarlanacak şekilde kullanıcı dosyasını oluştur'u yeniden adlandırmanız yeterlidir (bir saniye sonra bile yeterlidir)


13

Laravel 5.8'de users_table bigIncrements('id'), birincil anahtar için veri türünü kullanır . Böylece, bir yabancı anahtar kısıtlamasına başvurmak istediğinizde user_idsütununuzun unsignedBigInteger('user_id')tür olması gerekir .


çok teşekkür ederim, yabancı anahtarın istisnaya neden olduğunu anlamaya çalışmak için bir saat geçirdim
Ya Basha

10

Laravel 5.8 kullanarak da aynı sorunu yaşıyordum. Laravel belgelerine daha yakından baktıktan sonra, burada da Göçler ve bigIncrements . Çözdüğüm yol, tablo "kullanıcılar" ve ilişkilendirmeleri ile ilgili her tabloya birincil anahtar "$ table-> bigIncrements ('id')" eklemektir . Benim durumumda tablo "rol" . Son olarak, kullanıcılara rolleri ilişkilendirmek için "$ table-> unsignedBigInteger" vardı , yani "role_user" tablosu .

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

9

Ben laravel 5.8 ile bu sorunu vardı ve ben burada Laravel belgelerinde gösterildiği gibi , ben yabancı bir anahtar eklemek nerede bu kodu düzeltildi .

$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');

sonra koştum $ php artisan migrate:refresh

Bu sözdizimi oldukça ayrıntılı olduğundan, Laravel daha iyi bir geliştirici deneyimi sağlamak için konvansiyon kullanan ek, ters yöntemler sağlar. Yukarıdaki örnek şöyle yazılabilir:

Schema::table('posts', function (Blueprint $table) {
    $table->foreignId('user_id')->constrained()->onDelete('cascade');
});

7

Laravel 5.3'ü kullanmak aynı soruna sahipti.

Çözüm, integer ('name') -> unsigned () yerine unsignedInteger kullanmaktı .

İşte bu işe yaradı

$table->unsignedInt('column_name');
$table->foreign('column_name')->references('id')->on('table_name');

Bunun nedeni tamsayı ('name') -> unsigned kullanıldığında tabloda oluşturulan sütunun 11 uzunluğu, ancak unsigedInteger ('name') kullanıldığında sütunun 10 uzunluğu olmasıdır.

Uzunluk 10, Laravel kullanılırken sütun uzunluğu eşleşecek şekilde birincil anahtarların uzunluğudur.


Dostum, mesajınızı bulduğum için ham sql'den vazgeçmek üzere olduğum için teşekkür ederim. Ben hakkında daha laravel Birincil anahtar uzunluğu 10 olmak zorunda kalıyor neden okumak zorunda ve herhangi bir neden varsa neden tam sayısını ( 'sütununu') yapıyor olacak -> imzasız () unsigedInteger ( 'sütunu') farklı olmalıdır
Arnaud Bouchot

6

Bu hata benim için oluştu - yaratmaya çalıştığım tablo InnoDB iken - ilişkilendirmeye çalıştığım yabancı tablo bir MyISAM tablosu!


MyISAM yabancı anahtar kısıtlamalarını desteklemez. Muhtemelen işe yaradı çünkü MyISAM'a geçmek, muhtemelen bir nedenden dolayı orada bulunan yabancı anahtarı tamamen görmezden gelmesine neden oldu. Dikkatli ol.
greggle138

5

İlişkili tablolar oluşturulmadıkça ilişki ekleyemeyiz. Laravel, taşıma dosyalarını taşıma dosyalarının tarihine göre çalıştırır. Dolayısıyla, 2. geçiş dosyasındaki bir tabloyla ilişki oluşturmak istiyorsanız başarısız olur.

Aynı sorunla karşılaştım, bu yüzden sonunda tüm ilişkileri belirtmek için bir geçiş dosyası daha oluşturdum.

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

1
dosyaya ne isim verdin 9999_99_99_999999_create_foreign_keys.php?
Iannazzi

9999_99_99_99999 dosyasını taşıma dosya adına eklemek, geri alma özelliğini bozacağı için kötü bir fikirdir.
Maulik Gangani

5

Dikkat: Laravel aşağıdakileri kullanarak bir tablo oluşturduğunda

$table->increments('id');

Çoğu taşıma işleminde standart olan bu, işaretsiz bir tamsayı alanı oluşturur. Bu nedenle, başka bir tablodan bu alana yabancı başvuru yaparken, başvuru tablosunda, alanı UnsignedInteger olarak ayarladığınızdan (ne olduğumu varsaydım) UnsignedBigInteger alanına ayarladığınızdan emin olun.

Örneğin: 2018_12_12_123456_create_users_table.php taşıma dosyasında:

Schema::create('users', function (Blueprint $table){
    $table->increments('id');
    $table->string('name');
    $table->timestamps();

Ardından, kullanıcılara dış referansı ayarlayan 2018_12_12_18000000_create_permissions_table.php taşıma dosyasında:

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

5

Bu şekilde yazmalısın

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

Yabancı anahtar alanı imzasız olmalıdır , umarım yardımcı olur !!


Sadece imzasız değil, bir bigIncrements sütununa başvurduğunda, unsiged olmalıdırBigInteger
gondwe

4

Laravel'de yabancı anahtar kısıtlaması eklemek için aşağıdakiler benim için çalıştı:

  1. Yabancı anahtar olacak sütunu aşağıdaki gibi oluşturun:

    $ Tablo-> tamsayı ( 'column_name) ->) (imzasız;
  2. (1) 'den hemen sonra sınırlama çizgisi ekleme yani

    $ Tablo-> tamsayı ( 'column_name) ->) (imzasız;
    $ Tablo-> yabancı ( 'column_name) -> referanslar ( 'pk_of_other_table') -> üzerinde ( 'other_table');

3

i bu eski bir soru biliyorum ama referanslarla çalışıyorsanız uygun destek motoru tanımlanmış olduğundan emin olun. her iki tablo için innodb altyapısını ve başvuru sütunları için aynı veri türünü ayarlama

$table->engine = 'InnoDB';

2

Orijinal sorudan birkaç yıl sonra burada, laravel 5.1 kullanarak, göçlerimin aynı tarih koduyla bilgisayar tarafından oluşturulduğu gibi aynı hatayla karşılaştım. Önerilen tüm çözümlerden geçtim, sonra hata kaynağını bulmak için yeniden baktım.

Aşağıdaki laracasts ve bu mesajları okurken, ayrı bir şema çağrısı eklemeniz gerekmemesi dışında, doğru cevabın Vickies cevabına benzer olduğuna inanıyorum. Masayı Innodb'a ayarlamanıza gerek yok, laravel'in bunu yaptığını varsayıyorum.

Taşıma işlemlerinin doğru bir şekilde zamanlanması gerekir; bu, yabancı anahtarlara ihtiyacınız olan tablolar için dosya adında tarih kodunu (daha sonra) değiştireceğiniz anlamına gelir. Alternatif olarak veya ek olarak, yabancı anahtar gerektirmeyen tablolar için tarih kodunu düşürün.

Tarih kodunu değiştirmenin avantajı, geçiş kodunuzun okunması ve bakımı daha kolay olacaktır.

Şu ana kadar kodum, yabancı anahtarlara ihtiyaç duyan geçişleri geri almak için zaman kodunu ayarlayarak çalışıyor.

Ancak yüzlerce tablo var, bu yüzden en sonunda sadece yabancı anahtarlar için son bir tablo var. Sadece işleri akıtmak için. Bunları doğru dosyaya çekeceğim ve onları test ederken tarih kodunu değiştireceğim varsayıyorum.

Yani bir örnek: dosya 2016_01_18_999999_create_product_options_table. Bunun için ürünler tablosunun oluşturulması gerekir. Dosya adlarına bakın.

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

ürünler tablosu: bunun önce taşınması gerekir. 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');
}

Ve son olarak sorunları çözmek için geçici olarak kullandığım dosya, 9999_99_99_99_999999_create_foreign_keys.php adlı modeller için testler yazarken yeniden düzenleyeceğim. Bu anahtarlar, onları çıkardığımda yorumlanıyor, ama anladınız.

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

2

Çok basit !!!

senin ilk oluşturursanız 'priorities'göç dosyasını, laravel ilk çalıştırmak 'priorities'iken 'users'tablo yok.

var olmayan bir tabloya nasıl ilişki ekleyebilir !.

Çözüm: dışarı çekme yabancı anahtar kodlarının gelen 'priorities'masaya. taşıma dosyanız şu şekilde olmalıdır:

resim açıklamasını buraya girin

ve yeni bir taşıma dosyasına ekleyin, işte adı create_prioritiesForeignKey_tableve şu kodları ekleyin:

public function up()
{        
    Schema::table('priorities', function (Blueprint $table) {          
        $table->foreign('user_id')
              ->references('id')
              ->on('users');                        
    });
}

2

karşı taraftaki sütunun, karşı taraftaki anahtar sütununun öfkesinin üzerinde olduğundan emin olun

Yani yabancı anahtarınız (ikinci tabloda) ponter fiyat anahtarınızla aynı tür olmalıdır (ilk tabloda)

işaretçi asıl anahtarınız imzasız yöntem eklemeli, göstereyim:

İLK taşıma tablonuzda:

$table->increments('column_name'); //is INTEGER and UNSIGNED

SECOND taşıma tablonuzda:

$table->integer('column_forein_name')->unsigned(); //this must be INTEGER and UNSIGNED
$table->foreign('column_forein_name')->references('column_name')->on('first_table_name');

FARKI GÖRMEK İÇİN BAŞKA BİR ÖRNEK

İLK taşıma tablonuzda:

$table->mediumIncrements('column_name'); //is MEDIUM-INTEGER and UNSIGNED

SECOND taşıma tablonuzda:

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

MYSQL SAYISI TÜRLER TABLOSU ARALIKLARINI GÖR


2

Fark ettiğim bir şey, tabloların yabancı anahtar kısıtlamasından farklı bir motor kullanması durumunda çalışmaz.

Örneğin, bir tablo aşağıdakileri kullanıyorsa:

$table->engine = 'InnoDB';

Ve diğer kullanımlar

$table->engine = 'MyISAM';

bir hata oluşturur:

SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint

Bunu, tablo oluşturma işleminizin sonuna şu şekilde InnoDB ekleyerek düzeltebilirsiniz:

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

1

Benim durumumda, bir dize sütununda bir tamsayı id sütun atıfta . Değiştim: user_id

$table->string('user_id')

için:

$table->integer('user_id')->unsigned();

Umarım birine yardım eder!


1

Burada önemli olan, yabancı yöntemin ALTER_TABLEönceden var olan bir alanı yabancı anahtar haline getirmek için kullandığı . Yabancı anahtarı uygulamadan önce tablo türünü tanımlamanız gerekir. Ancak, bunun ayrı bir Schema::çağrıda olması gerekmez . Her ikisini de create içinde şöyle yapabilirsiniz:

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

Ayrıca türünün user_idyabancı anahtarla eşleşecek şekilde işaretsiz olarak ayarlandığını unutmayın .


1

Boolean parametresini doğrudan tamsayı sütununa, işaretsiz veya işaretsiz olması gerektiğini söyleyerek iletebilirsiniz. Laravel 5.4 aşağıdaki kodu sorunumu çözdü.

        $table->integer('user_id', false, true);

Burada false ikinci parametresi , otomatik olarak artırılmaması gerektiğini ve üçüncü true parametresi ise imzasız olması gerektiğini gösterir. Yabancı anahtar kısıtlamasını aynı geçişte tutabilir veya ayırabilirsiniz. Her ikisinde de çalışır.


1

Yukarıdaki çözümlerin hiçbiri yeni başlayanlar için işe yaramıyorsa, her iki kimliğin de aynı tipte olup olmadığını kontrol etmeyin: her integerikisi debigInteger , ... Böyle bir şeye sahip olabilirsiniz:

Ana Masa (örneğin kullanıcılar)

$table->bigIncrements('id');

Çocuk Masası (örneğin öncelikler)

$table->unsignedInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');

Bunun nedeni sorgu başarısız olacak users.idbir olduğunu BIG INTEGER, oysa priorities.user_idbir olduğunu INTEGER.

Bu durumda doğru sorgu şudur:

$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');

1

Benim durumumda, komut çalıştırılana kadar işe yaramadı

composer dump-autoload

bu şekilde yabancı anahtarları şema oluşturma içinde bırakabilirsiniz

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

1

Bu aynı zamanda yaratım göçü siparişiniz de olabilir. Öncelikle öncelikler tablosu oluşturursanız ve sonra kullanıcılar tablosundan sonra yanlış olur. İlk taşıma nedeniyle kullanıcı tablosu aranıyor. Bu nedenle, geçiş sırasını

app/database/migrations

rehber


1

Benim için alt tablomun başvurduğu tablo sütunu dizine eklenmedi.

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

Korkunç isimleri görmezden gelin, bu korkunç bir şekilde tasarlanmış başka bir sistemden.


1

Bazı durumlarda bu hata, geçiş sırası nedeniyle gelebilir.

Kullanıcılar ve Sipariş gibi iki tablodur

Sipariş tablosunda kullanıcıların ön anahtarı var (Sipariş tablosu önce taşınırsa taşıma sırasında soruna neden olur, çünkü yabancı anahtarla eşleşen kullanıcı olmadığı için soruna neden olur)

Çözüm: Sipariş Güncelleme tablonuzu güncelleme için kullanıcıların altına koyun

Örnek: Benim durumumda Eğitim ve Üniversite masaları Eğitim Masası

public function up()
{
    Schema::create('doc_education', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('uni_id')->unsigned()->nullable();
        $table->timestamps();
    });
}

Üniversitede

    Schema::create('doc_universties', function (Blueprint $table) {
        $table->increments('id');
        $table->string('uni_name');
        $table->string('location')->nullable();
        $table->timestamps();

        //
    });



Schema::table('doc_education', function(Blueprint $table) {
        $table->foreign('uni_id')->references('id')
        ->on('doc_universties')->onDelete('cascade');
    });

0

Düşündüğüm bir şey buradaki cevaplardan eksik ve lütfen yanılıyorsam beni düzeltin, ancak yabancı anahtarların pivot tabloda dizinlenmesi gerekiyor. En azından mysql'de durum böyle görünüyor.

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

}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.