Here is one way to do it:
use Time::HiRes qw(time);
my $id_number = time;
$id_number =~ s/\.//;
$id_number =~ s/(.{12}).*/$1/;
Simply assign an id-number to a record every 1/100
th of a second and you should be fine via this strategy for about 150 years with unlimited flexibility.
Now the "actual" answer to your "actual" question (without high resolution timer hacking) depends on two things:
1) the number of characters that you allow to into your records. For example, you could set up your database to only allow the 97 ascii characters that appear on generic western keyboards.
2) the maximum
information entropy that
you allow into the record set
via your data model (for example, would you allow some stranger to introduce pseudo-random text into the rows? probably not). This is also known as the
Kolmogorov complexity
Of course, you can generate about 2.8 x 10
14 12-digit hex ids which is far greater than the number of records you currently have and is still far greater than 50,000,000.
However, you stated your real question in passing "
But it looks not flexible for new input in the future.".
Consider this code, which for an n-digit id on m characters (like 12 and 16), will tell you the upper and lower bounds of strings of some length (like 5 and 50) on k letters (like 97) that can be guaranteed unique ids given a uniform distribution of input data (maximal entropy).
my $id_length = 12;
my $id_char_set = 16;
my $min_data_length = 5;
my $max_data_length = 50;
my $tiny_alphabet_size = 26; # a-z
my $small_alphabet = 37; # a-z, 0-9 and \s
my $medium_alphabet_size = 97; # generic western keyboards
my $big_alphabet_size = 65536; # utf8
my $world_alphabet_size = 100713; # unicode standard 5.1
my $counter = 0;
for my $i($tiny_alphabet_size..$world_alphabet_size){
for my $j($min_data_length..$max_data_length){
for my $k($j..$max_data_length){
my $total_size = geometric_series($i,$j,$k);
if($total_size < $id_char_set ** $id_length){
printf " %-5s %-5s %-5s %-5s %-30s\n",
$counter++,$i,$j,$k,$total_size;
}
}
}
}
sub geometric_series {
my($base,$min,$max) = @_;
my $x;
for my $i($min..$max){
$x += $base ** $i;
}
return $x;
}
You will find that the answer to your "actual" question, regarding assigning unique ids with the flexibility of unknown inputs via a
functional form, and without collision is a resounding
no.
If you would consider enforcing integrity on the input data, and limiting the input character set, then finding a functional form of generating 12-digit hex id numbers on-the-fly would become a more well formulated idea.
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.