GTHell's avatar

How to generate a unique but simple id for ticket?

The client want the ticket id that is simple in human readable term. Something like timestamp, 12945845 . The things is, I can't use timestamp as the their could be same occurrent. UUID is great but it's too long. Well, I don't want to use ID from the database as it could grow into millions of row.

0 likes
11 replies
Sergiu17's avatar

I've found something on stackoverflow

hexdec(uniqid())

You can use this

1 like
jlrdw's avatar

it could grow into millions of row.

Don't let it, start a new table and simply back up the old table into an archive.

Then you could use the ID and part of a date or something to indicate that Year's unique ticket.

2 likes
ts's avatar
ts
Best Answer
Level 6

I use random_bytes and bin2hex:

bin2hex(random_bytes(5)).

The amount you give to random bytes is doubled when you pass it to bin2hex. So in this instance you'll get a ten character string.

Or, just generate a UUID and trim it to eight characters or something?

5 likes
click's avatar

Or try the Laravel helper str_random(8) or KeyGen. You do need a "unique" check before you enter it in the database though.

cmdobueno's avatar

I mean generally speak for a easy solution, you can always do this:

public setIDFIELDattribute(){
    $uuid = str_random(10);

    //Just do the query how ever you want, this is totally generic
    while( $this->query()->where('id_field','=',$uuid)->first() ){
        $uuid = str_random(10);
    }

    $this->attributes['id_field'] = $uuid;
}

Given you could totally do some optimization here to make things more clean, but its the basic concept. You could even convert this to a helper function like this:

public function generateUniqueString($model,$column,$length=10){
    /*
    I would consider a check to make sure length works with the total records 
    in the table as a safe-guard. 
    For example, if the
        length = 1
        total_records = 100
        This will loop forever... or you just leave out the ability for them to enter a length
        Again this is just a suggestion/example
    */
    

    $model = new $model;
    $uuid = str_random($length);

    while($model->where($column,'=',$uuid)->count() > 0 ){
        $uuid = str_random($length);
    }

    return $uuid;
}
1 like
GTHell's avatar

Why are there no standardize way of doing this?

3 likes
Cronix's avatar

There are, but you don't want to use them. You say uuid is "too long", but you're wanting it to be unique among potentially millions of rows using a short string. Shorter strings will obviously have the potential for more duplicates, especially with millions of them.

An alternative is to do what @cmdobueno suggested above and that is to generate a random string and query the db to see if it already exists. If it doesn't, it's unique and use it. If it does, generate a new string and check it in the db again...until you get something unique. That will work, but will become slower and slower as your table grows and is pretty inefficient, but it will work and do what you're asking.

1 like
jlrdw's avatar

Have you looked around, how about a combination of Julian date plus maybe a current millisecond in the current day, that's just one idea. Or even current week with a millisecond.

Any thing shorter would not have that many combinations anyway.

In an accounting package I did, I used current receipt number from a receipt book, a dash, and current date. End of year it's closed out for IRS, archived, and table wiped for new year, that's the best way.

Even if a new receipt book repeats numbers, the added date made them unique.

2 likes
eriktobben's avatar

I am using this:

public function reference()
    {
        
        $unique = str_random(6);

        $check = Model::where('reference', $unique)->first();

        if ($check) {
            return $this->reference();
        }

        return $unique;
    }

Please or to participate in this conversation.