试图
创建对INSERT&sets调用的触发器originId = id (AUTO_INCREMENT)
我使用了建议的SQLhere in 1st block

  CREATE TRIGGER insert_example
  BEFORE INSERT ON notes
  FOR EACH ROW
  SET NEW.originId = (
        SELECT AUTO_INCREMENT
        FROM information_schema.TABLES
        WHERE TABLE_SCHEMA = DATABASE()
        AND TABLE_NAME = 'notes'
  );

由于information_schema缓存,我还设置了
information_schema_stats_expiry = 0

my.cnf文件中。现在,我注意到,每次插入都会立即更新信息。。
但是,通过控制台以大约2分钟的间隔执行“直接”插入,我一直没有更新AUTO_INCREMENT中的originId值。
mysql - MySQL 8-在INSERT上触发-VCS的重复AUTO_INCREMENT ID-LMLPHP
(它们应该等于id字段)
显式查询时,获取AUTO_u)将导致更新的正确值。
因此我怀疑SELECT AUTO_INCREMENT...子查询的结果会以某种方式。。什么?缓存?
怎么能避开这个?
谢谢您。
编辑1
我打算用这种方式实现某种风险投资:
用户创建新便笺,app将其标记为“new”,并在MySQL表中执行插入操作。这是“原点”的音符。
然后用户可以在UI中(完全)编辑这个注释,app将其标记为“update”,并再次将其作为新行插入MySQL表中。但这次originId应该用id的“origin”注释(通过app logics)填充。等等。
这允许在选择上按originId分区,只将最新版本获取到UI。
初始问题:
如果“origin”注释的originId为空,则MySQL 8窗口函数默认为(且仅限于?)尊重空模式执行的帧不像预期的那样(“好吧,对了,这都是关于按列分组中的空值”)。
假设解决方案:
将“origin”注释的originId设置为id在其初始且仅插入时,预期有两个好处:
通过originId=id轻松获取“原始”注释,
originId执行正确的分区。
产生的问题:
id是自动递增的,所以在通过后端(即PHP)插入时(对于新行)不可能(我知道)获得它的新值。
假设解决方案:
所以,我希望找到一些MySQL机制来解决这个问题(避免使用id字段进行操作),触发器似乎是一种正确的方法。。。
编辑2
我相信在MySQL中自动复制自动递增字段(或任何字段)是非常快速和非常容易的,但现在看来完全不是这样。。
所以,可能更好的方法是让id字段负责“关联”注释的版本:
在创建和“原点”插入时-用vcsGroupId UNSIGNED INT填充它,
在“编辑”和“版本”中插入-用“同级/原始”值填充它(用CTE获取),
在“视图”和“正常”中选择-通过MAX(vcsGroupId) + 1vcsGroupId或timestampPARTITION BY vcsGroupId执行带窗口功能的成帧,然后仅使用第一行(或升序并使用最后一行),
在视图和“原点”选择-几乎相同,但相反。。
看起来比较容易,不是吗?

最佳答案

你在玩火。我不知道你的扳机到底会出什么问题(除此之外,它对你已经不起作用了),但我有一种强烈的感觉,很多事情都会出问题。例如:如果在一个语句中插入多行,会怎么样?我不认为引擎会为每一行更新information_schema。如果运行INSERT ... SELECT语句,情况会更糟。因此,将information_schema用于此任务是一个非常糟糕的主意。
然而,第一个问题是:你为什么需要它?如果需要保存“origin ID”,那么您可能计划更新id列。这已经是个坏主意了。假设你能找到解决问题的方法-什么能保证你,触发器之外的originId不会改变?
但是-另一种方法是在插入时保持originId列为空,并在更新触发器中更新它。
假设这是你的桌子:

create table vcs_test(
  id int auto_increment,
  origin_id int null default null,
  primary key (id)
);

第一次更改原始ID时,使用更新触发器保存原始ID:
delimiter //
create trigger vcs_test_before_update before update on vcs_test for each row begin
  if new.id <> old.id then
    set new.origin_id = coalesce(old.origin_id, old.id);
  end if;
end;
delimiter //

然后,您的选择查询将如下所示:
select *, coalesce(origin_id, id) as origin_id from vcs_test;

demo on db-fiddle
您甚至可以使用以下架构保存完整的id历史记录:
create table vcs_test(
  id int auto_increment,
  id_history text null default null,
  primary key (id)
);


delimiter //
create trigger vcs_test_before_update before update on vcs_test for each row begin
  if new.id <> old.id then
    set new.id_history = concat_ws(',', old.id_history, old.id);
  end if;
end;
delimiter //

以下测试
insert into vcs_test (id) values (null), (null), (null);

update vcs_test set id = 5 where id = 2;
update vcs_test set id = 4 where id = 5;

select *, concat_ws(',', id_history, id) as full_id_history
from vcs_test;

会回来的
| id  | id_history | full_id_history |
| --- | ---------- | --------------- |
| 1   |            | 1               |
| 3   |            | 3               |
| 4   | 2,5        | 2,5,4           |

View on DB Fiddle

关于mysql - MySQL 8-在INSERT上触发-VCS的重复AUTO_INCREMENT ID,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58122151/

10-13 00:47