【问题标题】:Advanced use of auto-increment?高级使用自增?
【发布时间】:2011-11-10 21:32:12
【问题描述】:

我会尽量让这个问题尽可能简短。我想知道是否有办法通过 PHP 和 MySQL 编码执行以下操作:

  1. 删除一个自动递增的 id 条目(例如条目 12 of 20),同时将其余条目降低 1。(例如:删除条目 12 == 条目 13 变为 12,14 变为13等)

  2. 手动(即通过表单)插入一个带有 ID 的条目,以便在用户指定时将其余条目向上推(如果未指定,则默认为正常行为。(例如:用户指定他想要他的条目是 ID 14,但数据库中已经有一个 ID 14。应该发生的是用户输入将已经存在的条目推送到 15,其余现有条目遵循类似的方式。如果用户不指定 ID,默认为正常行为。)

我还在学习 MySQL 和 PHP,我需要的代码是用于我已经构建了一段时间的图库系统。

有可能吗?

【问题讨论】:

  • 出于参照完整性的原因,您通常不希望对主键执行此操作。您确定用户首先需要能够编辑 ID 吗?为什么?是为了美观吗?
  • 它应该是一种紧急按钮,如果已经存在的条目损坏或出现问题,并且无法使用 UPDATE 命令修复。我的女朋友将在网站上提交大部分内容,但有时我不在身边修复这些错误,而且她不精通代码。我正在努力解决乔的恐慌问题。如果你明白我的意思?
  • ID 必须是连续的有什么原因吗?例如,如果记录 12 被删除,如果在 11 和 13 之间有一个“洞”,会不会有问题?
  • 是的;我在那里提取所有条目的列表并按 ID 排列它们。由于它是漫画管理系统的一部分,所以我还使用递增的 ID 来显示页码。因此,如果第 12 条记录被删除,就会从第 11 页跳转到第 13 页,这将很难修复。我这样做的原因是尝试保存一些代码并尽可能保持干净。

标签: php mysql database edit


【解决方案1】:

这确实不是使用自动递增列的有效方法(数据库不是为此而设计的)。每次插入或删除项目时,您都会有效地进行表扫描。

如果您想要一个可以随意插入的排序,最好维护一个单独的映射(例如,有一个单独的条目来存储您可以随意操作的 ID 列表)。

【讨论】:

  • 这并不是真正的主要处理方式,更多的是紧急情况。我认为我对 Pekka 说的话最好地解释了这一点:“它应该是一种紧急按钮,如果已经存在的条目出现损坏或出现问题,并且无法使用 UPDATE 命令修复。我的女朋友将完成大部分内容在网站上提交,但有时我不在身边修复这些错误,而且她不精通代码。我正在尝试修复 Joe 的一般恐慌问题。如果你明白我的意思吗?”
【解决方案2】:

对于任务 1,您需要在修改所有 ID 后手动设置该表的 AUTO_INCREMENT 值,以便在下一次插入发生时没有间隙。更好的方法是根本不使用自动增量 ID - 有一个 ID 列,并在插入记录时使用 MAX(id)+1 查找所需的 ID。

这是我的伪代码:

删除:

$n = 12;
DELETE from items where id='$n';
UPDATE items SET id=id-1 WHERE id > '$n'

对于指定的插入:

$n = 15;
(if there is a record with id = 15)
   UPDATE items SET id=id+1 WHERE id >= '$n'
INSERT into items (id,..) values ('$n',...)

对于未指定的插入

$n = SELECT MAX(id)+1 FROM items
INSERT into items (id,..) values ('$n',...)

【讨论】:

  • 我认为这将是最好的解决方案,尽管这需要我重写一些代码。我明天就开始工作。非常感谢
【解决方案3】:

对于#1,试试这个 SQL 命令:

DELETE FROM table WHERE id=12;
UPDATE table set id=id-1 WHERE id > 12;
ALTER TABLE table AUTO_INCREMENT=AUTO_INCREMENT-1;

但是像这样使用 ID 字段是个坏主意。将行插入表后,您不应该修改它的值。

【讨论】:

    【解决方案4】:

    您可以将其用于您的 1) 问题。一起运行整个块。 @id 应该设置为您要删除的行。

    SET @id = 12;
    DELETE FROM tbl WHERE id = @id;
    UPDATE  tbl set id = id-1 WHERE id > @id;
    ALTER TABLE tbl AUTO_INCREMENT = 0;
    

    MySQL 免责声明:您不能将计数器重置为小于或等于任何已使用的值。对于 MyISAM,如果该值小于或等于 AUTO_INCREMENT 列中当前的最大值,则将该值重置为当前最大值加一。对于 InnoDB,你可以使用 ALTER TABLE ... AUTO_INCREMENT = value as of MySQL 5.0.3,但是如果 value 小于列中当前的最大值,则不会发生错误,并且当前序列值不会改变。

    【讨论】:

      猜你喜欢
      • 2011-05-12
      • 2014-01-06
      • 1970-01-01
      • 2020-02-11
      • 2018-09-02
      • 1970-01-01
      • 1970-01-01
      • 2020-11-20
      • 2012-12-01
      相关资源
      最近更新 更多