MariaDB“更新级联”约束没有按预期工作?

Posted

技术标签:

【中文标题】MariaDB“更新级联”约束没有按预期工作?【英文标题】:MariaDB "ON UPDATE CASCADE" CONSTRAINT not working as expected? 【发布时间】:2021-05-30 21:14:13 【问题描述】:

我期待 ON UPDATE CASCADE 约束可以让我更新引用的外键的值并将其级联到它的裁判(就像它在 PostgreSQL 中所做的那样),但情况似乎并非如此。

我错过了什么吗?

这里使用 MariaDB 10.3.29-MariaDB-0ubuntu0.20.04.1

CREATE TABLE category (
  id int(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  parent_id int(11) UNSIGNED DEFAULT NULL,
  slug varchar(255) NOT NULL,
  title varchar(255) NOT NULL,
  content longtext NOT NULL,
  created_at datetime NOT NULL DEFAULT current_timestamp(),
  updated_at datetime DEFAULT NULL,
  CONSTRAINT fk_category_parent_id FOREIGN KEY (parent_id) REFERENCES category (id) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;


INSERT INTO `category` (`id`, `parent_id`, `slug`, `title`, `content`, `created_at`, `updated_at`) VALUES
(1, NULL, 'non-classe', 'Non Classé', '', '2021-05-30 16:46:52', NULL),
(2, NULL, 'cours', 'Cours', '', '2021-05-30 16:47:38', NULL),
(3, 2, 'mysql', 'MySQL', '', '2021-05-30 16:48:18', NULL),
(4, 3, 'initiation-mysql', 'Cours initiation MySQL', '', '2021-05-30 16:49:09', NULL);

UPDATE category SET id = 12 WHERE id = 2;
-- ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`cours_cms`.`category`, CONSTRAINT `fk_category_parent_id` FOREIGN KEY (`parent_id`) REFERENCES `category` (`id`) ON UPDATE CASCADE)

【问题讨论】:

Id 3 想要保留 2 作为父母。 @jarlh 但是 ON UPDATE CASCADE 在那里,所以 id:3 parent_id 在级联中更新......这就是它的用途! (这就是它在 PostgreSQL 或 Oracle 中的工作方式) 糟糕,我没有仔细阅读... 【参考方案1】:

查看本页评论:

https://mariadb.com/kb/en/foreign-keys/

如果 ON UPDATE CASCADE 递归更新它之前在级联期间更新的同一个表,它的行为类似于 RESTRICT。这意味着您不能使用自引用的 ON UPDATE CASCADE 操作。这是为了防止级联更新导致无限循环。

换句话说,如果 ON UPDATE CASCADE 是分层数据类型的表,则它不起作用。

【讨论】:

我认为这回答了我的问题...... MySQL 部分实现概念让我抓狂! 那你为什么不用PostgreSQL呢? Postgres 有自己的 percs @BillKarwin 因为我被要求在 MySQL 上上课:'( @nbk 但 PostgreSQL 从来没有像 mysql 每天那样欺骗我【参考方案2】:

只是确认这在没有“无限循环”的 PostgreSQL 中有效

CREATE TABLE category (
  id SERIAL PRIMARY KEY,
  parent_id int DEFAULT NULL,
  slug varchar(255) NOT NULL,
  title varchar(255) NOT NULL,
  content text NOT NULL,
  CONSTRAINT fk_category_parent_id FOREIGN KEY (parent_id) REFERENCES category (id) ON DELETE RESTRICT ON UPDATE CASCADE
);

INSERT INTO category (id, parent_id, slug, title, content) VALUES
(1, NULL, 'non-classe', 'Non Classé', ''),
(2, NULL, 'cours', 'Cours', ''),
(3, 2, 'mysql', 'MySQL', ''),
(4, 3, 'initiation-mysql', 'Cours initiation MySQL', '');

UPDATE category SET id=12 WHERE id=2;

SELECT * FROM category;
 id | parent_id |       slug       |         title          | content 
----+-----------+------------------+------------------------+---------
  1 |           | non-classe       | Non Classé             | 
  4 |         3 | initiation-mysql | Cours initiation MySQL | 
 12 |           | cours            | Cours                  | 
  3 |        12 | mysql            | MySQL                  | 

【讨论】:

以上是关于MariaDB“更新级联”约束没有按预期工作?的主要内容,如果未能解决你的问题,请参考以下文章

BroadcastReceiver在Android上没有按预期工作

程序约束未按预期工作

自动布局约束未按预期工作

IOS 8 高度约束动画未按预期工作

空 UIView 上的自动布局约束无法按预期工作

UItextview 没有按预期扩展约束