Live data from Hacker News

Good system design

seangoedecke.com

371–380 of 400 posts

Re: Good system design

#371
post #346

Earlier quoted context omitted.

> Audit tables are a dumb concept because they imply bolting on an actual source of truth in addition to the regular not so source of truth tables, The regular table is the source of truth, the audit table is just a historical record of what changed and when.

So what do you do if a balance has $30 and the audit table shows two deposits of $20?

If you’re recording events as intent, then the event table is the source of truth and the state of the database is effectively snapshot of the state. In principle, you should be able to replay the events to produce the current state. If it calculates wrong, go fix your calculator, assume your events table isn’t wrong, and replay.

If you’re storing a log of database changes (what’s usually meant by an audit table), as in

(Table_Name, Column_Name, Old_Value, New_Value, Timestamp)

Then the database state is the source of truth, and the audit table is simply a record of changes ever occurred that reached that state.

In either case, there’s a single source of truth.

Re: Good system design

#372

I wonder why the author views CQRS negatively and then later gives this classic CQRS advice: >What this means in practice is having one service that knows about the state - i.e. it talks to a database - and other services that do stateless things. Avoid having five different services all write to the same table. Instead, have four of them send API requests (or emit events) to the first service, and keep the writing l…

Because you dont need CQRS to achieve that.

Re: Good system design

#373

Earlier quoted context omitted.

Only places that are making good money can afford to have overengineering. Overengineering is more prevalent the more money a company makes and companies who overengineers will pay good money to keep the overengineering working.

Something about my old CTO and VP of Eng I respected is they were still technical enough to call out this kind of thing. For as big as that company was they really held down complexity and overengineering to a real minimum. Unfortunately the rest of the executive has leaned on them so hard about AI boosting productivity they aren’t able to avoid thst becoming a mess

In other words they believed in principles other than increasing personal power

Re: Good system design

#374

> But in most cases replication lag can be worked around with simple tricks: for instance, when you update a record but need to use it right after, you can fill in the updated details in-memory instead of immediately re-reading after a write. I found myself truly confused by this one - does this actually need stating? Do people actually re-read immediately after a write? Provided you got confirmation that a write was…

At the very least you need to read the DB-generated ID, otherwise how do you provide stuff like editing?

Simply reading after a write is a perfectly adequate solution for I'd say most systems.

If you have performance issues and a change like this may solve them, sure. Switch to app-generated IDs and add workarounds for whatever other issues arise, and skip the read. But if you don't need to I don't see why you'd go through this trouble.

Re: Good system design

#375

This is nonsense masquerading as advice. "Add indexes ... but don't add too many" is a perfect example. It's 100% correct ... and also 100% something no one can actually change their actions based on ... which means it's also 100% worthless advice.

An intelligent reader might read that advice, realize they don't really know what indexes are nor how to use them, then do some research and learn what they need so that they can use indexes to their advantage.

It would be a extremely long article it it went into detail on everything.

Re: Good system design

#376

Earlier quoted context omitted.

Yeah, need a bit of imagination to walk there with me, but you are saying just use `saw_eclipse_at`. That would require having knowledge of the entity's birthday, the date that the event occurred on, and so on, which in this imaginary scenario, we do not.

I would not store that in a schema, storing bday and date seen is much more useful so that when the business inevitably asks for saw eclipse at 50 too you can answer the question without adding a saw at 50 boolean. Bday is also super useful info for a business that cares how old someone is (as your hypothetical one clearly does). Often the stated requirements of a problem are far too specific. Part of the job is syst…

[deleted]

Re: Good system design

#377

Earlier quoted context omitted.

Yeah, need a bit of imagination to walk there with me, but you are saying just use `saw_eclipse_at`. That would require having knowledge of the entity's birthday, the date that the event occurred on, and so on, which in this imaginary scenario, we do not.

I would not store that in a schema, storing bday and date seen is much more useful so that when the business inevitably asks for saw eclipse at 50 too you can answer the question without adding a saw at 50 boolean. Bday is also super useful info for a business that cares how old someone is (as your hypothetical one clearly does). Often the stated requirements of a problem are far too specific. Part of the job is syst…

[deleted]

Re: Good system design

#378

Earlier quoted context omitted.

Only places that are making good money can afford to have overengineering. Overengineering is more prevalent the more money a company makes and companies who overengineers will pay good money to keep the overengineering working.

Something about my old CTO and VP of Eng I respected is they were still technical enough to call out this kind of thing. For as big as that company was they really held down complexity and overengineering to a real minimum. Unfortunately the rest of the executive has leaned on them so hard about AI boosting productivity they aren’t able to avoid thst becoming a mess

It is a shame that so many companies try to scale by just hiring a lot of people, the more people you have in a single project the more overengineering you will end up with.

Some of it is consequence of managing so many individual contributors, I still believe a lot of companies use microservice stuff as a way to scale to more teams than to more scalability/reliability/observability.

Some of it is just people coming up with clever solutions (and leaving after the fact) and a lot from resume-driven development.

Re: Good system design

#379
post #374

> But in most cases replication lag can be worked around with simple tricks: for instance, when you update a record but need to use it right after, you can fill in the updated details in-memory instead of immediately re-reading after a write. I found myself truly confused by this one - does this actually need stating? Do people actually re-read immediately after a write? Provided you got confirmation that a write was…

At the very least you need to read the DB-generated ID, otherwise how do you provide stuff like editing? Simply reading after a write is a perfectly adequate solution for I'd say most systems. If you have performance issues and a change like this may solve them, sure. Switch to app-generated IDs and add workarounds for whatever other issues arise, and skip the read. But if you don't need to I don't see why you'd go t…

> At the very least you need to read the DB-generated ID, otherwise how do you provide stuff like editing?

Most of my career has been with MSSQL, but it can provide that after an insert as a part of the confirmation that the insert was successful.

No explicit separate read required.

Re: Good system design

#380

Earlier quoted context omitted.

I beg you to write an article expanding on this points. I'll pay to read this article.

Really! I've written about this in my comments here... Here's a brief summary: - typical thread-per-client programming is terribly wasteful because it needs large stacks that must be able to grow (within reason), and this leads programmers to smear client state all over the stack, which then means that the memory and _cache_ footprint of per-client state is huge even though the state is highly compressible, and this…

Good summary of the theory, but the weird thing is that every time I’ve rewritten code to use async the total throughout went down by about 10%… which is what I estimate is the overheads introduced by the compiler-generated async state machinery.

I’m yet to see a convincing set of A/B comparisons from a modern language. My experiences don’t line up with the conventional wisdom!

Post reply on HN