如果您正在處理錯誤:“違反完整性約束:無法添加或更新子行:外鍵約束失敗”,那麼您閱讀的是正確的文章。
通常,當您在表中新增列並將其聲明為外鍵時,您會遇到此錯誤。
在 SQL 資料庫中,外鍵是表中的一個字段,用於在另一個表中的資料之間建立連結。考慮下面的客戶表。
CREATE TABLE customers ( id INT PRIMARY KEY, name VARCHAR(255), email VARCHAR(255) );
現在您想要將您的客戶連結到一個群組。首先,您應該將新欄位新增至包含對組表的引用的客戶表:
# Create the new column "group_id" ALTER TABLE customers ADD COLUMN group_id INT NOT NULL;
您可以新增外鍵約束來啟動與組表的關係:
# Add the FK constraints ALTER TABLE customers ADD CONSTRAINT fk_group_id FOREIGN KEY (group_id) REFERENCES customers(id);
當您對customers表執行此變更操作時,資料庫將驗證group_id欄位中的ID是否存在於groups表中。
在此檢查期間,資料庫將引發“完整性違規錯誤”,因為 group_id 欄位仍然為空,因此它不包含 groups 表中的任何有效參考。因此 SQL 引擎無法嘗試套用外鍵約束。這是因為空值不是組表的有效外鍵。
最簡單的操作是將新列宣告為可為空。
您可以從alter查詢中刪除「NOT NULL」指令,以允許group_id列包含空值。
這個簡單的更改將首先解決問題,因為現在外鍵也可以為空。您可以執行資料移轉以最終填入客戶表中的新 group_id 資料列,並規劃新版本以重新引入「NOT NULL」約束。
如果在您的應用程式中,如果沒有特定的群組,客戶就不能存在,您應該記住,如果 group_id 可以為空,您的資料庫將不知道此約束。
如果您在應用程式中建立實體時犯了錯誤,資料庫不會提醒您。
另一個解決方案是在用於新增列的alter查詢和用於新增外鍵的alter查詢之間新增資料遷移作業。
在客戶表中取得新的 group_id 欄位後,您可以執行腳本,使用 groups 表中的有效 ID 填入現有行的此列。
這是執行此任務的查詢範例:
UPDATE customers, groups SET customers.group_id = groups.id Where customers.user_id = groups.user_id;
在現代應用程式中,所有這些任務都是使用遷移工具執行的。它通常在大多數常見的應用程式開發框架中可用。
在下面的範例中,我將向您展示如何使用 Laravel 遷移處理完整性約束違規問題。
創建遷移:
php artisan make:migration add_goup_id_fk_to_customers –table=customers
您可以將遷移分為兩部分,如下所示:
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Schema; return new class extends Migration { /** * Run the migrations. */ public function up(): void { Schema::create('customers', function (Blueprint $table) { $table->unsignedBigInteger('group_id')->nullable(); }); // Insert default data into the new column DB::raw('UPDATE customers, groups SET customers.group_id = groups.id WHERE customers.user_id = groups.user_id'); Schema::table('customers', function (Blueprint $table) { // Add the FK constraint $table->foreign('group_id')->references('id')->on(groups)->onDelete('cascade'); // Remove the nullable condition eventually; $table->unsignedBigInteger('group_id')->change(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::table('customers', function (Blueprint $table) { $table->dropForeign('group_id'); $table->dropColumn('group_id'); }); } };
如果您對提高資料庫效能感興趣,可以看看下面關於「智慧型資料庫查詢」的文章:
https://inspector.dev/how-to-accelerate-application-performance-with-smart-sql-queries/
Inspector是專為軟體開發人員設計的程式碼執行監控工具。您無需在伺服器層級安裝任何內容,只需安裝 composer 軟體包 即可開始使用。
與其他複雜的一體化平台不同,Inspector 非常簡單,並且對 PHP 友好。您可以嘗試我們的 Laravel 或 Symfony 套件。
如果您正在尋找有效的自動化、深入的見解以及將警報和通知轉發到您的訊息傳遞環境的能力,請免費嘗試 Inspector。註冊您的帳戶。
或在網站上了解更多:https://inspector.dev
免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。
Copyright© 2022 湘ICP备2022001581号-3