-2

我有一个字段,其值从 0 到 6,00,000

对于数据库中的此字段值,例如 5,6,7,8,45,91,92,93,94

我必须获得该字段的免费值和使用值建议

1.USED
Minvalue= 0 maxvalue=94(来自数据库)

在这种情况下,我使用 for 循环 (i=minvalue;i<=maxvalue;i++) 循环运行 94 次,每次它检查某些内容是否与数据库条目匹配 (5,6,7,45..94)

我打印输出范围,如
使用值:
5 到 8
45 91 到 94

由于值较小,因此它工作得很快。如果数据库中有一个像 490000 这样的条目,那么循环将运行很长时间。

2.FREE
最小值= 0 最大值= 600000(来自字段定义)

我在这里也有相同的 for 循环概念,所以循环运行 5lac 次。而且输出永远不会来,太耗时了

我想要像
自由值这样的输出:
0 到 4
9 到 44
46 到 90
95-600000

有什么方法可以减少 for 循环执行或使用其他逻辑?

4

3 回答 3

3

不要那样做。

如果可能,将此数据库列设置为AUTO_INCREMENT(或您的 SQL 引擎最接近的替代项),以便自动分配新值。如果这不可能,您可以改为SELECT MAX(col) + 1 FROM table确定下一个可用值(但请注意,这很容易出现竞争)。

无论哪种情况,都不要担心留下 gaps。在大多数应用程序中,这不是问题。如果您的应用程序中存在域要求,而您的 ID 数量有限(为什么?),那么当您的所有 ID 都被分配时,您可能最终会遇到问题,因此您需要为此做好计划。

如果您处于某些非常不寻常的情况下,您需要有效分配少量可用值,那么您应该明确跟踪这些值。有一个表,其中每个可用值都有一行,还有一个字段指示分配给它的内容,然后使用类似SELECT id FROM id_table WHERE inuse = 0 LIMIT 1.

于 2013-01-11T05:59:49.507 回答
0

如果数据库表有N行,那么 0 到N之间的值必须至少有一个未被使用,因此您最多只需要循环N +1 次。

在 Perl 中执行此操作的一种有效方法是将使用的值存储为散列键,并在循环中增加一个变量,直到它不再匹配散列中的任何键:

my @values = (5,6,7,8,45,91,92,93,94);

my %hash;
undef @hash{@values};

my $x = 0;
$x++ while exists $hash{$x};

# now $x is the lowest unused value
于 2013-01-11T05:48:26.187 回答
0

无需遍历特定范围内的所有值。只需检查您的值并分别查找连续值(例如,当前值比前一个值大一)或间隙。这会快得多。

打印使用的范围

my @values = (5, 6, 7, 8, 45, 91, 92, 93, 94);
my $start = shift @values;
my $i = $start;
for my $v (@values) {
    if ($v > $i + 1) {
        if ($i == $start) {
            print "$start\n";
        } else {
            print "$start to $i\n";
        }

        $start = $v;
    }

    $i = $v;
}

if ($i == $start) {
    print "$start\n";
} else {
    print "$start to $i\n";
}

并找到自由值的范围

my @values = (5, 6, 7, 8, 45, 91, 92, 93, 94);
my $i = 0;
my $max = 600000;
for my $v (@values) {
    if ($v > $i + 1) {
        print "$i to ", $v - 1, "\n";
    } elsif ($v == $i + 1) {
        print "$i\n";
    }

    $i = $v + 1;
}

if ($i < $max) {
    print "$i to $max\n";
}
于 2013-01-11T09:48:04.037 回答