Reputation: 1685
In my DB, I need to have unique reference ids to orders, to show the end users.
My schema includes many accounts that can potentially have many customers, which can make many orders (occasionally at the same time - both different customers, and a single customer with many orders)
I've decided to use Hashids in order to solve this. I came up with this:
//create a unique salt using the account id + current timestamp:
var hashids = new Hashids(accountId + '-' + new Date().getTime(), 8,
'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ')
//Then, generate a unique id for every order using:
for(var i = 0; i < orders.length; i++ ) {
orders[i].ref_number = hashids.encode(i, a.date.getTime())
}
How random would this be? How can I validate that?
Thanks
Upvotes: 0
Views: 3045
Reputation: 241
It's simpler than you think. From the documentation of Hashids:
There are no collisions because the method is based on integer to hex conversion. As long as you don't change constructor arguments midway, the generated output will stay unique to your salt.
Additionally, we encourage you to pre-generate a large number of ids for testing purposes — to analyze their uniqueness, whether they look random enough for your project and what your upper integer limit is (which usually depends on your system/language).
Here you have an example of how to pre-generate a large number of ids:
const salt = 'my salt'
const idsLength = 10
const hashids = new Hashids(salt, idsLength)
let idsCollector = []
for (let i = 0; i < 1000; i++) {
idsCollector.push(hashids.encode(i))
}
console.log(idsCollector)
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/hashids.min.js"></script>
REMEMBER! When defining the salt
variable, it has to remain the same for all users and sessions, if not every user will have a different hash id making link sharing impossible. The same goes for the length!
Upvotes: 1
Reputation: 562270
same-length, unique id string that I can show to end users so they can reference their orders
How about a concatenation of the customer id and the auto-increment order id?
Suppose your table is:
CREATE TABLE `orders` (
`order_id` int(11) NOT NULL AUTO_INCREMENT,
`cust_id` int(11) DEFAULT NULL,
PRIMARY KEY (`order_id`)
);
With this data:
insert into orders values (8675309, 123);
You can create a VIEW to produce the customer reference to the order:
CREATE OR REPLACE VIEW cust_orders_ref AS
SELECT CONCAT(LPAD(cust_id, 4, '0'), '-', LPAD(order_id, 11, '0')) AS order_ref
FROM orders;
Output:
select * from cust_ref;
+------------------+
| order_ref |
+------------------+
| 0123-00008675309 |
+------------------+
Upvotes: 1