Live data from Hacker News

You'll regret using natural keys

blog.ploeh.dk

561–568 of 568 posts

Re: You'll regret using natural keys

#561

Earlier quoted context omitted.

> For example, the order of query params is free to change but it's still the same URL. Are you sure that's guaranteed by any spec? I thought an end-point would be free to treat `?a=1&b=2` and `?b=2&a=1` differently. I mean, it would be a nightmarish implementation, but I don't think it would be non-conforming?

It's a mere convention: "a querystring of this type is an array of parameters, the order of which is irrelevant" - this is one of the tautological "valid except when it's not" non-rules (a surprising number of cases). Example: ?a=1&b=2&a=3 - will the server treat this to be equivalent as ?a=3&b=2&a=1 , or ?b=2&a=1 , ?b=2&a=3 , or something else entirely? You'd need to check the serverside parsing implementation to be…

The repeated case is something I hadn't thought of when I wrote the original comment since I would never do that so this got me curious. Looks like it _isn't_ guaranteed by any spec, and different frameworks have their own rules as you pointed out. For example, PHP will take the last duplicate param value as the "winner", and others group them into an array.

While I think this would be a bad application design, it looks like swapping the order of params could result in errors in some cases. In practice though I would treat the URLs the same.

Re: You'll regret using natural keys

#562

Earlier quoted context omitted.

It's a mere convention: "a querystring of this type is an array of parameters, the order of which is irrelevant" - this is one of the tautological "valid except when it's not" non-rules (a surprising number of cases). Example: ?a=1&b=2&a=3 - will the server treat this to be equivalent as ?a=3&b=2&a=1 , or ?b=2&a=1 , ?b=2&a=3 , or something else entirely? You'd need to check the serverside parsing implementation to be…

The repeated case is something I hadn't thought of when I wrote the original comment since I would never do that so this got me curious. Looks like it _isn't_ guaranteed by any spec, and different frameworks have their own rules as you pointed out. For example, PHP will take the last duplicate param value as the "winner", and others group them into an array. While I think this would be a bad application design, it lo…

You would never do that, I wouldn't either, but in machine-to-machine API interactions, this tends to crop up - i.e. a SW stack where this implies "an array of `a` values and a scalar `b` value" sends the data to a SW stack where "last `a` wins, last `b` wins", and strange bugs ensue, as both sides insist they're doing The Right Thing :)

Re: You'll regret using natural keys

#563
post #250
post #231

Earlier quoted context omitted.

I think that 0 and 1 are likely to cause problems when customers end up reading their "user ID" back to your employees in Customer Support Country over the phone. "It's one-three-oh-dee-ee-el. Yes, I'm sure, EL as in elephant."

Anything that needs to be read over the phone should probably be written out using something like the NATO phonetic alphabet, split into smaller chunks if needed: "The code? It's kilo eight niner; one three mike; delta echo lima."

*tree :-)

Re: You'll regret using natural keys

#564

Earlier quoted context omitted.

You’ll have to worry about performance tanking instead. If you’re using UUIDv7 then less so, but it’s still (at best) 16 bytes, which is double that of even a BIGINT. Anyone who says UUIDs aren’t a problem hasn’t dealt with them at scale (or doesn’t know what they’re looking at, and just upsizes the hardware).

Most databases with a UUID type store them as 128-bit integers, typically the same as a BIGINT. It's not like 378562875682765 is the bit representation of a bigint either. And if you're not using uuidv7 or some other kind of cluster-friendly id, you'd best be using a hash index, and if you're doing neither, you probably don't care about their size or performance anyway. You don't pick UUIDs blindly, but on balance, t…

128 bits is 16 bytes. BIGINT is a 64 bit int (long or long long).

So there is at least additional storage required, and probably some CPU cost as well. And even UUIDv7 isn't guaranteed to produce sequential IDs, but it's probably good enough to not seriously fragment your table storage.

But yes, UUIDs are usually stored as integers.

Re: You'll regret using natural keys

#565

Earlier quoted context omitted.

> To turn your second part back around: why a natural key? What is the function of minting a natural key if humans are meant to use something else? Because non-natural keys are unnecessary in the presence of a natural key, and unnecessary things bring in complexity. > "Customer ID ### is having an issue with such-and-such." Then you need access to the customer's ID, but the devil here is in the detail you didn't add,…

> Use secure channels… When it comes to PII at my company, secure channels means "encrypted email only". No Slack, no Jira, no chat in video calls. That's just not feasible for 100% of communications.

Then use a time-limited token, you can assign it to a particular role or support engineer too. You could do fancy things like making it pronounceable… there are so many options that do not involve passing around keys (while fearing you might leak an email address, which is less worrying than the key, IMO).

Re: You'll regret using natural keys

#566
post #436

Earlier quoted context omitted.

> To turn your second part back around: why a natural key? What is the function of minting a natural key if humans are meant to use something else? Because non-natural keys are unnecessary in the presence of a natural key, and unnecessary things bring in complexity. > "Customer ID ### is having an issue with such-and-such." Then you need access to the customer's ID, but the devil here is in the detail you didn't add,…

> Because non-natural keys are unnecessary in the presence of a natural key, and unnecessary things bring in complexity. None of the things you've presented are actually "natural" keys, they are pieces of information that you've made assumptions about to shoehorn them into being usable as a "natural key". > Use secure channels… No channel is perfectly secure. As channels become more secure, they become harder to use…

I don’t believe you understand what a natural key is, but aside from that, I’m not the one advocating passing around IDs like that isn’t a security failing. If you wouldn’t put it in a URL then you shouldn’t be passing it around anyway.

Re: You'll regret using natural keys

#567

I've become a fan of unique, relatively short and "human-readable" IDs, such at the ones used by Stripe, e.g. `cus_MJA953cFzEuO1z` for an ID of a customer. Here's a Stripe dev article on the topic: https://dev.to/stripe/designing-apis-for-humans-object-ids-3... If you use JavaScript/TypeScript, you can make them like this: function makeSlug(length: number): string { const validChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcde…

Type safe and unguessable IDs are what I've been using in my projects for the past, oh, 10 years maybe? Inspired by Stripe!

In my databases, I often prefer integer primary keys for performance reasons. On the other hand, I don't want to expose my primary keys because they are easy to guess.

Recently I've been playing with Rust, and ended up publishing a library to encrypt IDs in they way I like:

https://crates.io/crates/cryptid-rs

Re: You'll regret using natural keys

#568

Earlier quoted context omitted.

So use timestamps with sub-second precision, which virtually every SQL database supports (even ones like SQLite that don't have built-in date/time types).

I don't think you know enough about how databases work to even try to be giving advice. The timestamp generated in a transaction is generally the time the transaction started, which means it is always the same within the same transaction.

> I don't think you know enough about how databases work to even try to be giving advice.

That's both incorrect and entirely unwarranted.

Post reply on HN