【发布时间】:2019-09-26 17:45:52
【问题描述】:
尝试
创建在 INSERT 上调用的触发器并设置 originId = id (AUTO_INCREMENT),
我用过SQL建议here 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 文件中。正如我所注意到的,现在信息几乎在每次 INSERT 时都会立即更新..
但是,通过控制台以大约 2 分钟的间隔执行“直接”插入,我一直没有更新 originId 中的 AUTO_INCREMENT 值。
(它们应该等于id 字段)
在显式查询时,获取 AUTO_) 会导致更新的正确值。
因此我怀疑SELECT AUTO_INCREMENT... 子查询的结果不知何故......什么?缓存?
如何解决这个问题?
谢谢。
编辑 1
我打算以这种方式实现某种 VCS:
- 用户创建新注释,应用程序将其标记为“新”并在 MySQL 表中执行 INSERT。这是“原点”注释。
- 然后用户可以在 UI 中编辑此注释(完全),应用程序会将其标记为“更新”,并在 MySQL 表中再次将其插入为新行。但是这一次
originId应该用“原点”注释的id填充(通过应用程序逻辑)。等等。 - 这允许通过
originId对SELECT 进行分区,仅获取最新版本的UI。
最初的问题:
如果 originId of "origin" Note 为 NULL,默认情况下 MySQL 8 窗口函数(并且仅?) RESPECT_NULL 模式执行的框架不符合预期(“嗯,duh,这都是关于分组中的 NULL -按列”)。
假设的解决方案:
在他们的initial and only INSERT 上将originId of "origin" Notes 设置为id,期望有两个好处:
- 通过
originId=id轻松获取“来源”便笺, - 通过
originId执行正确的分区。
导致的问题:id 是 AUTO_INCREMENT,因此(我知道)无法通过后端(即 PHP)在 INSERT 上获取其新值(对于新行) )。
假设的解决方案:
所以,我希望找到一些 MySQL 机制来解决这个问题(避免使用 id 字段进行操作),TRIGGER 似乎是正确的方法......
编辑 2
我相信在 MySQL 中自动复制 id AUTO_INCREMENT 字段(或任何字段)会非常快速且超级简单,但现在看来完全不是这样......
因此,可能更好的方法是拥有vcsGroupId UNSIGNED INT 字段,负责“关联” Note 的版本:
- 在创建和“原点”插入 - 用
MAX(vcsGroupId) + 1填充它, - 在编辑和“版本”插入 - 用“兄弟”/“原点”
vcsGroupId值填充它(使用 CTE 获取), - 在 view 和“正常”SELECT 中 - 通过
PARTITION BY vcsGroupId、ORDER BY id或时间戳DESC使用窗口函数执行框架,然后只使用第一个(或使用最后一个升序)行, - 在 view 和“origin” SELECT - 几乎相同,但相反..
这似乎更容易,不是吗?
【问题讨论】:
-
有什么好的理由,你为什么要尝试“复制” id?
-
@PaulSpiegel,尝试实现 VCS 排序,我需要复制
id以获取“原点”注释.. -
如果版本控制是由应用程序管理的,那为什么不在初始 INSERT 之后的 UPDATE 语句中复制 id 呢?
-
@PaulSpiegel,我不确定用链式查询来实现这个我必须执行(INSERT - SELECT id - UPDATE),就像我最近想的那样。就性能而言,三倍查询似乎非常无效。让我感到羞耻,因为我忘记了 PHP 允许 getting
idon every INSERT using Mysqli class,而不是 Mysqli_stmt 作为准备好的查询.. 尽管如此,仍然存在加倍查询.. 另一方面,通过WHERE id = originId获取“原始”行似乎更容易和更快,而不是分区、排序和挑选……不是吗? -
您的设计(每个版本一行)对性能不太友好。所以我不太关心初始插入的两个查询。
标签: mysql sql-insert database-trigger mysql-8.0