MySQL中内置的自动增量不符合我的要求,所以我正在考虑制作一个新的。这是我的要求:
1.创建增量序列号
1.能够将行(记录)插入缺失的编号。例如,我有5行,然后删除第3行。之后,我又插入了2行。我希望其中一个将插入到第三行位置。
我的想法是使用循环检查表中的所有行。如果它找到了丢失的位置,它将在丢失的位置添加(a)新行。否则,它将继续在表的末尾添加新行。
正如你所见,这个想法只适用于非常小的table。如果表扩展到,比如10MB。然后服务器会遇到很大的麻烦。
我想知道是否有人有更好的算法,请告诉我。
4条答案
按热度按时间zkure5ic1#
在自动增量列中填充空白通常是不必要的,而且比实际情况更麻烦。自动增量不是行号。它不需要是连续的,它只需要是唯一的。
如果你想填补空白,你会发现的一个问题是race condition。也就是说,在你的PHP脚本找到要使用的空白并插入该空白之间的毫秒内,另一个PHP请求可能正在做同样的事情,找到相同的空白,然后去填补它。
为了解决这个问题,PHP脚本必须在搜索要使用的间隙之前锁定整个表。由于您正在搜索间隙,其中没有具有给定值的行,因此无法锁定任何行。您必须锁定整个表,因为您在搜索差距之前不知道差距在哪里(如果存在差距)。
使用表锁定是一种代价高昂的牺牲,因为这意味着一次只能插入一个PHP请求。这将成为应用程序可伸缩性的瓶颈。
现在谈谈您的实现。如何找到丢失的号码?这些数字在数据库中,因此您可以查询查找表中没有前面的id的任何id。
另一种方法是在应用程序中保留所有id的某种缓存。但这也意味着每个并发的PHP请求都需要访问缓存,以及锁定缓存的能力,这样一次只能有一个PHP请求搜索和更新缓存。
不管怎样,您都为您的应用程序创建了一个瓶颈。
我在我的书《SQL Antipatterns Volume 1: Avoiding the Pitfalls of Database Programming》的一章中写了更多关于这一点的内容。
isr3a4wc2#
在实践中,您必须非常小心并真正知道自己在做什么,因为以这种方式填充id列中的“空白”可能会破坏整个数据库或系统的引用完整性,因为该表中的id被其他表引用。
否则,一种快速的方法是先使用mysql通过现有行填充这些“空”id,例如使用phpmyadmin,在确保表在id列上按升序排序后,使用如下内容:
上面的操作将按顺序更新所有现有的id,并且您插入的项将被自动增加为等于表中总行数的id。
但是如果你想保留已经非空的id,那么你可以在PHP中这样做:
rxztt3cl3#
你可以使用二进制搜索算法。
首先将所有ID插入数据库。然后将最大id与列表长度进行比较。如果两者相同,则插入具有下一个id的行。如果不是,则比较列表一半的id和length/2。现在,如果两者相同,则表示缺少的id位于列表的前半部分之后,否则它位于列表的上半部分。希望你能理解我想说的话。
bf1o4zei4#
不要删除行。在插入时包含一个布尔字段“reuseflag”=false。
要“删除”行,请将重用标志设置为true,并将行选择更改为仅包含一行(如果重用标志为false)
然后,当您想重用一行时,首先找到reuseflag=true的位置,插入新值并在更新行之前将reusefla更改为false。
这将比你能做的任何其他方法都快。