首頁  >  文章  >  後端開發  >  [已解決] 完整性約束違規 – 快速提示

[已解決] 完整性約束違規 – 快速提示

WBOY
WBOY原創
2024-08-17 22:50:091003瀏覽

如果您正在處理錯誤:“違反完整性約束:無法新增或更新子行:外鍵約束失敗”,那麼您閱讀的是正確的文章。

通常,當您向表格新增列並將其聲明為外鍵時,您會遇到此錯誤。

在 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 遷移

在現代應用程式中,所有這些任務都是使用遷移工具執行的。它通常在大多數常見的應用程式開發框架中可用。

在下面的範例中,我將向您展示如何使用 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

[Resolved] Integrity constraint violation – Fast tips

以上是[已解決] 完整性約束違規 – 快速提示的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn