我有一个字段,取值从0到6,00,000
对于该字段,数据库中的值为5,6,7,8,45,91,92,93,94
我必须获得此字段的免费值和使用价值建议
1.适用
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 maxvalue = 600000(来自字段定义)
我在这里也有相同的循环概念,所以循环运行5lac次。输出永远不会耗费太多时间
我希望输出像
自由值:
0到4
9至44
46至90
95-600000
任何减少循环执行或使用其他逻辑的方法?
答案 0 :(得分:3)
不要那样做。
如果可能,请将此数据库列设置为AUTO_INCREMENT
(或您的SQL引擎最接近的替代方案),以便自动分配新值。如果无法做到这一点,您可以改为SELECT MAX(col) + 1 FROM table
来确定下一个可用值(但请注意,这很容易出现竞争)。
在任何一种情况下,都不用担心会留下空白。在大多数应用程序中,它不是问题。如果您的应用程序中存在域名要求,这会给您留下有限数量的ID(为什么?),那么当您分配所有ID时,您可能会遇到最终问题,因此您需要为此做好计划。
如果您处于一些非常不寻常的情况,即您需要有效分配少量可用值,那么您应该明确地跟踪这些值。为每个可用值创建一个表,并指定一个表示分配内容的字段,并使用SELECT id FROM id_table WHERE inuse = 0 LIMIT 1
之类的内容搜索该表。
答案 1 :(得分:0)
如果数据库表中有 N 行,那么0和 N 之间的值中至少有一个必须是未使用的,因此您只需要循环< em> 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
答案 2 :(得分: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";
}