Fork me on GitHub
#architecture
<
2023-06-16
>
pavlosmelissinos13:06:35

This is more about (relational, postgres in particular) database design than general architecture but here it goes: Let's say you have two services, A and B. A sends measurements to B and B stores these measurements to a database. Part of each measurement is a unique identifier that is produced by A. Would you use this id as a primary key in service B? I don't think it's the end of the world and I can't think of any immediate drawbacks but I have a hunch that it's a bad idea. What do you think? edit: I think I'd rather create two columns; one will be the actual primary key, randomly generated by service B and a second column, <service A name>measurementid with unique (and maybe not null) constraints

pesterhazy13:06:54

Consider using uuids, which are globally unique and avoid conflicts

pavlosmelissinos14:06:09

I agree, UUIDs for the win! That said, if you knew that the measurement id that comes from service A is a UUID, would you use it as a primary key in a database owned by service B? The use case is that service A can't guarantee exactly-once delivery and measurement id is used for deduplication by service B.

pesterhazy14:06:50

Yes, I'd pick a uuid and use it as primary key in both systems. (But I may be missing something about the type of issues you expect)

pavlosmelissinos14:06:09

I don't expect any actual issues to be honest, I'm just concerned it might be a type of coupling if I reuse the same id as a primary key in both systems.

pesterhazy14:06:34

My guess is that this coupling would be of the good kind

👌 2
pavlosmelissinos14:06:42

Thanks, I'll let the thought sink for a bit...

Jorin15:06:39

I would argue for generating the ID as early as possible. And if IDs are globally valid, it's totally fine to rely on them throughout the system. Also see https://www.scattered-thoughts.net/writing/coding/ > we want to assign the id as close as possible to the event that caused it eg if we are clicking the 'new contract' button in a browser then we should assign the id in the browser once and then try (and maybe retry) to submit it to the server. And just as side note: You might also want to consider https://dev.to/harshhhdev/uuidguid-cuid-nanoid-whats-the-difference-5dj1 these days.

👌 2
thom08:06:18

Entities have a lifetime and identity that spans multiple services, that’s a perfectly acceptable form of coupling. You definitely should think about who owns these lifetimes, and it’s also worth reading about Domain Driven Design Aggregates to help think about which types of entities you should be willing to reference by ID in other systems. But your model exists above and outside each individual service and that’s okay!

👀 2
pavlosmelissinos09:06:11

That's quite interesting. Thanks, I'll read up on it. 🙂 I've been meaning to delve into DDD, perhaps now's the time!

Ivan19:06:11

ulid is also an alternative to uuids https://github.com/ulid/spec

👍 2
didibus05:06:31

If B is storing A's measurements, and the ID from A is meant to dedupe measurements, meaning it guarantees no two measurements will share the ID ever. Then there's no problem with making that ID your primary key. Especially if the two services form a common system, and you expect use cases where you might want to join across, or reference from one into the other, it helps for them to use the same ID in that case. My only recommendation is to treat their ID as a string even if it isn't. It's likely they'll one day choose to change their ID scheme, which might change its type or size, and you'll need to be able to adapt your primary key when that happens.

👍 2
didibus05:06:33

The other thing with DB design in general. Think of your read and write use cases. What will you query the measurements by? What will you want to update them by? Is it the service A id which you'll be given most of the time for that? If so, it makes sense as the primary key. But if you'll be searching for things and listing measurements, and people will the refer back using your returned measurements, than it could also easily get away having your own ID for them. Like basically what ID will the users have and want to use to read/write?

👍 2
2
Tulio Rodrigues16:06:19

One drawback is not be able to have a third service (C) sending measurements to service B. So, you will have two tied services.

👍 2