MySQL PHP插入新行,其中rowNum列值始终按日期和时间按时间顺序排列

Posted

技术标签:

【中文标题】MySQL PHP插入新行,其中rowNum列值始终按日期和时间按时间顺序排列【英文标题】:MySQL PHP insert new row where rowNum column values always remain chronological by date and time 【发布时间】:2021-11-19 16:51:57 【问题描述】:

我正在尝试创建一个 SQL 查询(或 php 中的多个查询和逻辑)以将新行插入 mysql 数据库表(例如表名是学生),其中 rowNum 列值始终保持按时间顺序排列,具体取决于单独的日期/时间柱子。这意味着如果我插入的行具有最大/最大/最新日期/时间,则应该正常插入它,并且 rowNum 值只会增加一。我已经实现了。问题是当我插入的行的日期/时间值介于两个现有行之间时。然后我要插入的行的 rowNum 值需要设置为与我试图在“之间”插入的两行中的第二行的 rowNum 值相同(注意:我知道该表是无序列表/set; 但是,rowNum 需要调整,因为它正在插入“之间”)。然后,(按时间顺序)这个新插入的行之后的其余行需要将它们的 rowNum 值增加一。请参阅以下示例以获得进一步说明:

id 是自增的 id 列和主键。 rowNum 是一个“参考”id,它不一定是唯一的,但每次新插入都会增加。如果您遍历每个 rowNum 值,它们应该始终根据日期/时间列按时间顺序排列。 dateTime 不是默认的 datetime 时间戳,而是如下所示格式的 varchar 字段。

表:学生

id rowNum dateTime
1 4 09-17-2021 14:00
2 5 09-17-2021 16:32
3 6 09-18-2021 19:11
4 7 09-22-2021 13:01

那么,当插入一个新的 dateTime: 09-17-2021 15:21 的行时,表格应该如下:

表:学生

id rowNum dateTime
1 4 09-17-2021 14:00
5 5 09-17-2021 15:21
2 5 09-17-2021 16:32
3 6 09-18-2021 19:11
4 7 09-22-2021 13:01

然后,插入行之后的 rowNum 值应按如下方式递增:

表:学生

id rowNum dateTime
1 4 09-17-2021 14:00
5 5 09-17-2021 15:21
2 6 09-17-2021 16:32
3 7 09-18-2021 19:11
4 8 09-22-2021 13:01

最后,我明白这是一件很奇怪的事情。我已经明确表达了这种担忧,并建议应该以不同的方式进行;但是,由于独特的限制,我必须这样做,其中 rowNum 值是按时间顺序排列的。

【问题讨论】:

"rowNum 是一个“引用”id" 对什么的引用?它是干什么用的?它必须存储在数据库中吗?你有什么问题? 为什么不使用ROW_NUMBER()? (虽然它需要 MySQL 8.0。) @brombeer "rowNum" 只是对该行记录的引用。它必须存储在数据库中。如果有意义的话,它本质上是在现实世界中用来讨论该行数据的记录“名称”。例如,“Bill”可能会问,rowNum 100 处的记录发生的日期和时间是什么?我的实际表有多个其他列填充了其他数据。我只是为了提问而简化了表格。 另外,您的 DATETIME 数据格式无效。 MySQL 对日期使用 YYYY-MM-DD 格式。所以你的日期实际上是字符串,这意味着它们可能根本不会作为日期插入。是什么阻止某人使用dateTime='banana' 插入一行? @brombeer 至于我的问题,我正在寻找有关如何创建这样的 SQL 插入语句的建议,或者是否有现有的简单方法来完成此操作。在我的研究中,我没有发现任何其他情况与我相同的情况。 【参考方案1】:

INSERT 不能修改它插入的行以外的其他行。你也不能使用触发器,因为触发器不能更新同一个表(它可能导致无限循环)。

因此,您必须在完成 INSERT 后执行 UPDATE 语句。最好在事务中执行此操作。

但实际上先进行 UPDATE 更容易:

START TRANSACTION;

UPDATE student SET rowNum=rowNum+1 WHERE rowNum >= 5;

INSERT INTO student SET rowNum=5, dateTime='09-17-2021 15:21';

COMMIT;

最好先执行 UPDATE,因为如果您先 INSERT 新行,那么它将包含在 UPDATE 的条件中。

如果有多个客户端同时插入一行,这仍然存在问题。它可能导致锁冲突或死锁。您可能需要先使用 LOCK TABLES 来防止这种情况。但这会阻止您进行并发插入的机会。换句话说,每个执行 INSERT 的事务都需要等待其他事务提交。

您还应该考虑:

如果删除一行,rowNum 值会发生什么变化?

如果 dateTime 更新,rowNum 值会发生什么变化?

是什么阻止了客户端直接更新 rowNum 值并丢弃完整的序列?

【讨论】:

并发插入已经通过只允许一个用户一次登录来处理——我知道,这是一种过时的解决方案,但它可以工作,并且适合我的用例。如果它对我有用,我将研究您的解决方案并将其标记为答案。感谢有关考虑行删除/更新的建议。 我不想考虑你的应用的WTFPM。 哈哈,不幸的是,这让我们两个人...... 所以我能够在使用事务、更新语句和插入语句的地方使用这种格式。我能够类似地处理删除和更新情况。为了找到从哪里开始增加rowNum,我做了另一个查询:SELECT * FROM student WHERE event_date>='$userInputtedDatetime' ORDER BY rowNum ASC LIMIT 1。然后我将此查询中的 rowNum 保存在 phpVariable 中以用于我的事务更新查询(...WHERE rowNum >= phpVariable)。 此外,我更改了我的数据库,因此它现在使用 datetime 数据类型而不是 varchar,并且正在研究锁定表以处理并发,以查看这是否有意义,或者它是否对我的应用程序来说是一个更好的解决方案.

以上是关于MySQL PHP插入新行,其中rowNum列值始终按日期和时间按时间顺序排列的主要内容,如果未能解决你的问题,请参考以下文章

PHP 将新行插入mysql

使用php通过wordpress在mysql数据库中添加新行

如何仅将列值插入前一千行

插入表格并将另一列设置为自动递增的列值

向mysql插入新行

PHP fwrite()如何在某些特定行之后插入新行