Live data from Hacker News

YAGRI: You are gonna read it

scottantipa.com

21–30 of 161 posts

Re: YAGRI: You are gonna read it

#21
post #4

One thing I do quite frequently which is related to this (and possibly is a pattern in rails) is to use times in place of Booleans. So is_deleted would contain a timestamp to represent the deleted_at time for example. This means you can store more information for a small marginal cost. It helps that rails will automatically let you use it as a Boolean and will interpret a timestamp as true.

This one little change alone can bring such huge benefits later.

Re: YAGRI: You are gonna read it

#22
post #7

Event-sourcing solves this. And with how cheap storage is, it should be more prevalent in the industry. IMO the biggest thing holding it back is that there isn't a framework that's plug-and-play (say like Next.js is to React) that provides people with that ability. I've been working on one in Typescript (with eventual re-writes in other langs. like Rust and Go), but it's difficult even coming up with conventions.

Event sourcing is an expensive solution and I don't mean from a storage perspective — it burns engineering cognitive horsepower quickly on things that don't matter. Do it if you're in finance or whatever. Having been burned by my own "let's event source" impulse on data change tracking systems, I now prefer less sophisticated solutions. Figuring out how to deal with slow projections, watching a projection rebuild go from minutes to hours to a few days as a system I expected to handle a few events/minute go to 20 events/second. Fancy caches can't save you if you want to use that vaunted ability to reconstruct from scratch. Event schema evolution also presents difficult tradeoffs: when old events stop having meaning or evolve in meaning you either end up adding on new event subtypes and variants leaving old cruft to accumulate, or you do migrations and edit history on really large tables.

I'd counsel anyone considering event sourcing to use more "low power" solutions like audit logs or soft deletes (if really necessary) first if possible.

Re: YAGRI: You are gonna read it

#23
post #12

A little while back, I had a conversation with a colleague about sorting entries by "updated at" in the user interface, and to my surprise this was not added by the backend team. Many of these "we are going to need it"s come from experience. For example in the context of data structures (DS), I have made many "mistakes" that I do correctly a second time. These mistakes made writing algorithms for the DS harder, or ma…

Database schemas being perfect out-of-the gate was replaced by reliable migrations. If it's not data that's essential to serving the current functionality, just add a column later. `updated_at` doesn't have to be accurate for your entire dataset; just set it to `NOW()` when you run the migration.

Sure, migrations are bearable (especially ones that only add columns).

But for the example of the "updated_at" column, or "soft delete" functionality, you only find out you need it because the operations team suddenly discovered they needed that functionality on existing production rows because something weird happened.

Re: YAGRI: You are gonna read it

#24
post #18

Just curious, how do people feel about this general style of soft deletes currently? Do people still use these in production or prefer to just delete fully or alternatively move deleted rows to a separate tables / schema? I find the complexity to still feel awkward enough that makes me wonder if deleted_at is worth it. Maybe there are better patterns out there to make this cleaner like triggers to prevent deletion, s…

If you have a good audit log, it really doesn't matter. You can always restore it if need be. If you have no audit log(or a bad one), like lots of apps, then you have to care a lot. Personally, I just implement a good audit log and then I just delete with impunity. Worst case scenario, someone(maybe even me) made a mistake and I have to run undo_log_audit() with the id of the audit log entry I want to put back. Nearl…

Can you share more about what makes a good audit log? My company doesn’t currently have one and I’m a little lost on where to start.

Should this be at the application code level, or the ORM, or the database itself?

Re: YAGRI: You are gonna read it

#25
post #12

A little while back, I had a conversation with a colleague about sorting entries by "updated at" in the user interface, and to my surprise this was not added by the backend team. Many of these "we are going to need it"s come from experience. For example in the context of data structures (DS), I have made many "mistakes" that I do correctly a second time. These mistakes made writing algorithms for the DS harder, or ma…

Database schemas being perfect out-of-the gate was replaced by reliable migrations. If it's not data that's essential to serving the current functionality, just add a column later. `updated_at` doesn't have to be accurate for your entire dataset; just set it to `NOW()` when you run the migration.

In C#-land, we just have it as a standard that ~every table inherits from `ITrackable`, and we wrote a little EF plugin to automatically update the appropriate columns.

public interface ITrackable { DateTime CreatedOn {get; set;} DateTime ModifiedOn {get; set;} }

Saves so much time and hassle.

Re: YAGRI: You are gonna read it

#26
The perils of UI design wagging the horse.

I like the heuristics described here. However if these things aren't making it into a product spec where appropriate, then I smell some dysfunction that goes beyond what's being stored by default.

Product need (expressed as spec, design, etc) should highlight the failure cases where we would expect fields like these to be surfaced.

I'd hope that any given buisness shouldn't need someone with production database access on hand to inform as to why/when/how 'thing' was deleted. Really we'd want the user (be it 'boss' or someone else) to be able to access that information in a controlled manner.

"What information do we need when something goes wrong?". Ask it. Drill it. Ask it again.

That said, if you can't get those things, this seems a fine way to be pragmatic.

Re: YAGRI: You are gonna read it

#27
> But I've never heard someone complain about a table having too many timestamps.

I do. Each one is 8 bytes. At the billions of rows scale, that adds up. Disk is cheap, but not free; more importantly, memory is not cheap at all.

Re: YAGRI: You are gonna read it

#28
post #4

One thing I do quite frequently which is related to this (and possibly is a pattern in rails) is to use times in place of Booleans. So is_deleted would contain a timestamp to represent the deleted_at time for example. This means you can store more information for a small marginal cost. It helps that rails will automatically let you use it as a Boolean and will interpret a timestamp as true.

This is all well and good until you need to represent something that happened on Jan 1 1970 00:00 UTC.
Post reply on HN