使行不可变并允许插入

Posted

技术标签:

【中文标题】使行不可变并允许插入【英文标题】:Make rows immutable and allow insert 【发布时间】:2013-05-14 03:19:47 【问题描述】:

我想让 mysql 表中的行不可变,一旦它们被插入,我不想改变它们。我该怎么做?

(如果尝试任何更改,最好返回合适的错误消息)。

我没有授予权限,所以我想了解如何编写引发错误的BEFORE UPDATE 触发器(使用信号或发出总是失败的语句)。

我使用 MySQL v5。

【问题讨论】:

【参考方案1】:

一个非常简单的触发器应该可以做到;

CREATE TRIGGER stop_update BEFORE UPDATE ON table1
FOR EACH ROW
  SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Update not allowed!'
//

An SQLfiddle to test with。您可以添加更新进行测试。

当然,您可能希望对DELETE 执行相同的操作。

编辑:如果您使用的 MySQL 版本低于 5.5 并添加了信号,则可以限制写入(不是很干净)故意导致错误;

CREATE TRIGGER stop_update BEFORE UPDATE ON table1
FOR EACH ROW
  UPDATE UPDATE_OF_TABLE1_IS_NOT_ALLOWED SET value='Update not allowed!'
//

Another SQLfiddle。无法在 DDL 中添加错误并让 SQLfiddle 保存它,因此在左侧窗口中将更新的 id 更改为 1(现有行)将导致更新失败。

【讨论】:

@user2105729 是的,对不起命名,会解决这个问题:) 我试过 vut 我收到 #1064 - 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 3 行的 'SQLSTATE '45000' SET MESSAGE_TEXT = 'Update not allowed!'' 附近使用正确的语法 谢谢,我的 phpmyadmin seeeeeeeeems 说我使用的是 mysql 5.1,但我不确定,有没有我可以发出的命令来检查这个? @user2105729 在 mysql 提示符下键入 status,它应该会显示该信息。 CREATE TRIGGER stop_update BEFORE UPDATE ON buu_properties_products FOR EACH ROW UPDATE UPDATE_OF_TABLE1_IS_NOT_ALLOWED SET value='不允许更新!'【参考方案2】:

如果您使用 InnoDB,另一种不使用触发器的解决方案。

创建另一个与其重复的表。 新列中的列应具有指向相关原始表的列的外键(因此是此解决方案中的 InnoDB 要求)。

为每个键设置一个限制,如ON UPDATE RESTRICT。下面是一列的代码:

CREATE TABLE original (
     ....
     immutable_column ...
     INDEX index1(immutable_column)
     ....
) ENGINE=INNODB;

CREATE TABLE restricter (
     .....
     col1,
     INDEX index2(col1),
     FOREIGN KEY (col1) REFERENCES original (immutable_colum) ON UPDATE RESTRICT ON DELETE CASCADE
) ENGINE=INNODB;

你必须手动插入到这个新表中。

【讨论】:

以上是关于使行不可变并允许插入的主要内容,如果未能解决你的问题,请参考以下文章

当 Row 接受可变参数时,为啥 Scala 编译器会失败并显示“此处不允许 ': _*' 注释”?

Swift可变集:找到重复元素

可变与不可变类型数据,列表的copy方法

为啥 &mut self 允许借用 struct 成员,但不允许将 self 借用到不可变方法?

保留插入顺序的不可变 Scala Map 实现

如何在结构中放置可变大小的 char 数组?