Mariadb

如何定義循環參照完整性約束?

  • December 5, 2021

我有兩個相互引用的表,在嘗試插入其中一個時出現此錯誤:“外鍵約束的格式不正確”。

在此處輸入圖像描述

我在這個任務中被困了三個星期,似乎無法到達任何地方或找到有數據庫經驗的人來幫助。

我已附加所有三個查詢,但僅在創建表“DEPARTMENTS”的最後一個查詢中收到錯誤

CREATE DATABASE k0310855_AMAZON;

USE k0310855_AMAZON;

我的桌子:

CREATE TABLE EMPLOYEE (
EMP_ID int PRIMARY KEY,
EMP_SALARY int,
EMP_PHONE varchar(255),
EMP_DEPARTMENT varchar(255)
);

和:

CREATE TABLE CHILDREN (
   CHI_NAME int,
   CHI_AGE int,
   EMP_ID int,
   CONSTRAINT CHILDREN PRIMARY KEY (EMP_ID, CHI_NAME)
);

和:

CREATE TABLE DEPARTMENTS 
(
 EMP_DEPARTMENT int PRIMARY KEY,
 DEP_NAME varchar(255),
 DEP_BUDGET int,
 DEP_MANAGER varchar(255),
 CONSTRAINT FOREIGN KEY (DEP_MANAGER) REFERENCES EMPLOYEE 
(EMP_DEPARTMENT) 
);**

我收到以下錯誤:

ERROR 1005 (HY000): Can't create table `k0310855_AMAZON`.`DEPARTMENTS` (errno: 150 "Foreign key constraint is incorrectly formed")

我要解決你的問題的方法是這樣的(下面的所有程式碼都可以在這裡的小提琴上找到):

CREATE TABLE department
(
 dept_id      int PRIMARY KEY,
 dep_name     varchar(255),
 dep_budge    int,
 dep_manager int NOT NULL
);

進而:

CREATE TABLE employee 
(
 emp_id      int PRIMARY KEY,
 emp_salary  int,
 emp_phone   varchar(255),
 emp_dep    int NOT NULL,
 
 CONSTRAINT emp_dep_fk FOREIGN KEY (emp_dep) REFERENCES department (dept_id)
);

最後,

CREATE TABLE children 
(
   child_name VARCHAR(10) NOT NULL,
   child_dob  DATE        NOT NULL,
   emp_id     int         NOT NULL,

   child_age INT GENERATED ALWAYS AS (TIMESTAMPDIFF(YEAR, child_dob, NOW())) VIRTUAL,

   CONSTRAINT kid_pk PRIMARY KEY (emp_id, child_name),
   CONSTRAINT kid_emp_fk FOREIGN KEY (emp_id) REFERENCES employee (emp_id)
);

我們先從孩子開始!

您不應該數據儲存ageage隨時間變化的數據,因此儲存年齡意味著您必須設置觸發器以每年更新此欄位 - 一個壞主意

將孩子的生日儲存為a DATE,然後將其年齡儲存為GENERATED VIRTUAL欄位,然後每次選擇記錄時都會即時計算孩子的年齡!

例子:

INSERT INTO children (child_name, child_dob, emp_id)
 VALUES ('Seán', '2015-12-05', 200);

SELECT * FROM children;- 結果:

child_name  child_dob   emp_id   child_age
     Seán  2015-12-05     200           6

現在,對於您更嚴重的問題 - 表聲明中的循環引用 - 您FOREIGN KEY來回指出。

AFAIK,MariaDB 不支持DEFERRED CONSTRAINTs. 解決此問題的方法是輸入具有較少約束的數據,然後**ADD**按如下方式輸入約束(參見小提琴):

ALTER TABLE department ADD CONSTRAINT dep_man_fk
FOREIGN KEY (dep_manager) REFERENCES employee (emp_id);

或者你可以使用像 PostgreSQL 這樣支持DEFERRED CONSTRAINTs 的體面的 RDBMS。

計劃A:

創建兩個沒有FK 的表。然後做兩個ALTER TABLEs來添加 FK。

計劃 B:圓形約束通常是設計錯誤。重新考慮架構。無論如何,FK不需要有一個可以工作的數據庫。

引用自:https://dba.stackexchange.com/questions/303528