News for hackers. Stuff that matters.
Re:Data-Oriented Design by inopinatus on Monday July 03, 2023 @08:48AM (#36572155)
Some of the best advice I ever got for writing composable, high-performance code was “work on structs of arrays, not arrays of structs”. I hear many echoes of that advice in this text. Turns out that entity-component architectures work well in line-of-business applications too, not just games.

Alas, many developers in enterprise are rusted onto a record-keeping CRUD model and struggle to think in columns rather than rows. The idea of inserting an entity id into a “published” table, instead of setting a boolean “published” field to true, doesn’t always come naturally. Yet once you realise how readily polymorphic this is, you may start wanting to use such approaches to data for everything. Rich new opportunities then arise from cross-pollinating entity data. Some may question why it is structurally permissible that, say, a network interface can have a birthday, or why an invoice has an IPv6 address, why my sister is in the DHCP pool, whilst limegreen is deleted and $5 on Tuesdays. This of course is half the fun.

I don’t accept that it’s wholly incompatible with OO, though, a thesis you’ll see dotted around the place. I’ve even taken this approach with Ruby using Active Record for persistence; not normally a domain where the words “high performance” are bandied about. That worked particularly because Ruby’s object system, being more Smalltalk-ish than C++/Java-ish, strongly favours composition over inheritance.

Re:Data-Oriented Design by m_mueller on Monday July 03, 2023 @09:28AM (#36572585)
> I don’t accept that it’s wholly incompatible with OO

I don't think it is, not even in Java. If you use its primitive array and value types, you can easily wrap this in a data wrapper class with functional interfaces, which then can be used quite elegantly in the rest of your code in an OO way - you just don't box all the records into objects.

Re:Data-Oriented Design by inopinatus on Monday July 03, 2023 @09:57AM (#36572938)
Agreed. Honestly I think the hardest part here is programmer mindset - when you suggest that identity is fluid and records don’t have to correspond to a class hierarchy some folks get a panicked look going on, like you just claimed to eat their pets
Re:Data-Oriented Design by m_mueller on Monday July 03, 2023 @12:11PM (#36575004)
Yep. Funny story, this was actually a coding interview homework for a question with order of millions of data rows from a file. The exercise required 10s timing requirement, so I decided to do it data centric from start. Interviewers found my style ‚non idiomatic‘, but probably never thought about why my version was done in fractions of a second.
Re:Data-Oriented Design by zx8080 on Tuesday July 04, 2023 @12:25AM (#36582219)
Did you pass the interview?
Re:Data-Oriented Design by m_mueller on Tuesday July 04, 2023 @03:14AM (#36583280)
I did and got the offer. In the end it didn't work out however (better offer elsewhere).
Re:Data-Oriented Design by whstl on Monday July 03, 2023 @10:05AM (#36573046)
"I don’t accept that it’s wholly incompatible with OO, though, a thesis you’ll see dotted around the place."

Agreed. Arrays of Structs is not the part that is really incompatible.

The part that clashes a bit with traditional OOP is ECS, where data and code are meant to be kept separate. But of course I'm talking about very traditional OOP. It is entirely possible to use an OOP languages + classes to implement ECS. It's just not gonna be "traditional".

EDIT: To quote your other reply: "records don’t have to identify strongly with a class hierarchy".

Re:Data-Oriented Design by loup-vaillant on Monday July 03, 2023 @06:25PM (#36579619)
Not sure what you all mean by OOP to be honest. Is this a case of OOP actually meaning "good programming", then morphing into the most fashionable (and hopefully best) practices of the day?

It wouldn't be the first time… https://loup-vaillant.fr/articles/deaths-of-oop

Re:Data-Oriented Design by whstl on Tuesday July 04, 2023 @04:00AM (#36583616)
Well, I made the case to emphasize the word traditional. By "traditional" I mean OOP that follows the popular practices and pedagogy.

Using ECS means totally eschewing things like encapsulation and inheritance. You stop grouping functions and methods together. You basically have "free records" and "free procedures" (or "free methods" if the language requires classes, Kingdom of Nouns style). ECS is a procedural/functional paradigm.

You can argue that this is not OOP anymore, and guess what: I'll probably support you on that! :)

Re:Data-Oriented Design by galaxyLogic on Tuesday July 04, 2023 @04:24AM (#36583771)
Working with JavaScript has caused me to ask the question: "When should I create a Class, and when a Function?"

This is not a trivial question because class-instances are basically collections of Functions, and Functions can return class-instances. So a trivial answer would be: "It does not matter, you can do everything with either one".

No, you shouldn't do everything with both, you should do some specific types of things with classes and other types of things with functions. But what?

I've come to this rule-of-thumb: Use classes only to represent and encapsulate data, use functions to process and transform class-instances.

In practice this means classes should not have methods which take arguments!

Classes are still truly useful over plain records, because a class abstracts over what data is stored, and what are the names by which it is accessed, and whether the methods return a stored field or a calculated one.

The idea that "Everything is an instance of a Class" as in Smalltalk is a bit flawed, or at least too trivial. Except of course it is also true that Functions are objects. (And in Smalltalk you can use BlockClosures, which really are "functions").

This division of design makes it easier for me to think about the structure of the whole application. I no longer have classes for everything. Instead I have classes which represent data, and a set of functions which do the processing of those class-instances.

Why is this good? Because classes are, and easily become complicated, since they can have many methods, they can have static vs. instance-methods, and methods can be inherited and you can even use the 'super' to add to the confusion. So therefore if you can find a way to force your classes to be as simple as possible, this is it. Don't make them do complicated things since they are complicated to start with.

Dividing the design into two parts, classes + functions, divides the complexity of the whole app into two parts, each of which contains about 1/2 of the complexity of the whole app. The complexity is now data-complexity PLUS function-complexity whereas with use-only-classes -approach the app-complexity would be more like data-complexity TIMES function complexity.

Keep data (= classes) and functions separate. Divide and conquer complexity.

Re:Data-Oriented Design by whstl on Tuesday July 04, 2023 @05:40AM (#36584300)
Oh, yes. I totally agree with that philosophy.

The part about classes only acting on themselves resonates heavily with me. To me it's the same with components in frontend apps: the more independent they are, the better.

I'm probably never going to be copy-pasting my classes and components into other apps, but a good class/component should be copy-paste-able without needing many dependencies. This avoids the "banana gorilla jungle problem", as named by Joe Armstrong.

"Free Functions" also help with keeping those classes even more self-contained and decoupled: you can use Function types for callbacks and things like that, instead of having to couple the class to some other class or interface. The only thing the class has to worry about is that the function conforms to the type.

-

"Keep data (= classes) and functions separate. Divide and conquer complexity."

Yep, 100% agree. Amen to that.

Re:Data-Oriented Design by galaxyLogic on Tuesday July 04, 2023 @01:47PM (#36590135)
Right. Functions and data can not be decoupled because functions must know what properties of data they need to access. So functions by necessity depend on data. BUT data, if it is really "data" should NOT depend on functions. So we have reduced what would be bi-directional dependency problem into one directional one.

In a typical OOP design there would be no clear rules as to who can depend on whom and whom not.

Re:Data-Oriented Design by DeathArrow on Monday July 03, 2023 @10:10AM (#36573107)
As I see it, there are two types of DOD, one that you've mentioned and where you “work on structs of arrays, not arrays of structs”.

The other one means just giving up of encapsulation, separate the data from the methods that work with the data, think the whole app in terms on how the data flows through it and model it so everything is easy to understand and change. For added correctness, you can use immutable data structures and pure functions.

Re:Data-Oriented Design by hohohmm on Monday July 03, 2023 @10:31PM (#36581483)
This is exactly right. Good summary.
Re:Data-Oriented Design by butterNaN on Tuesday July 04, 2023 @03:44AM (#36583516)
Isn't this the very definition of functional programming?
Re:Data-Oriented Design by tsss on Tuesday July 04, 2023 @05:53AM (#36584407)
No. Functional programming is programming with functions as values. It is not incompatible with data hiding (for example through modules).
Re:Data-Oriented Design by butterNaN on Sunday July 09, 2023 @07:19AM (#36653550)
"Programming with functions as values" is merely one of the side effects, a feature, of writing your programs functionally. It does not define the paradigm.
Re:Data-Oriented Design by marcosdumay on Monday July 03, 2023 @10:12AM (#36573139)
The entire advice is context-dependent.

Games just happen to have a lot of operations that need column-based access; but that's not true for all domains. When you go and blindly push the game best practices into other domain, you are just making everybody's life hard and most systems worse.

Re:Data-Oriented Design by GartzenDeHaes on Monday July 03, 2023 @11:22AM (#36574194)
It's for high-performance computing with current CPU designs that are dependent on data locality for performance.

I agree that it's a harmful design for business data. Programmers want to push their runtime data model into the database and they have no interest in the operational, maintenance, and performance problems this causes. When someone suggests this kind of thing, I'll ask them "how do we diagnose performance problems with this technology when there are 100,000 concurrent users and millions of data elements?" The rows-and-columns people can answer this question.

Re:Data-Oriented Design by feoren on Monday July 03, 2023 @02:11PM (#36576764)
> When someone suggests this kind of thing, I'll ask them "how do we diagnose performance problems with this technology when there are 100,000 concurrent users and millions of data elements?"

I don't understand; the exact same performance diagnostics work in both cases. Why is this different? There's nothing intrinsically less performant about this approach. You really think your checkerboard tables and long lists of columns with names like "VALUE12" and "VALUE13" and multiple different kinds of key/value pairs you jammed in there for different clients -- you think those are better performance!?

> 100,000 concurrent users Do you actually have 100,000 concurrent users? Really? You don't, do you? You just kinda hope you will eventually. And again: this approach is not worse for that.

> millions of data elements

This is absolute peanuts for any modern database system. It's weird that this is your extreme example.

Re:Data-Oriented Design by flohofwoe on Monday July 03, 2023 @11:49AM (#36574625)
> Games just happen to have a lot of operations that need column-based access.

And that's not even true for many code areas in typical games, only where there's at least a few thousands 'things' to process (e.g. particle systems or navigation/collision systems).

DOD makes a lot of sense within specific subsystems, but not necessarily in high level gameplay code (outside specific genres at least).

Re:Data-Oriented Design by lyu07282 on Monday July 03, 2023 @10:18PM (#36581405)
You can see that in bevy, it feels like they are slowly reinventing a relational database and query language, every time they discover another limitation in their pure ECS architecture they add another macguffin to make it work.
Re:Data-Oriented Design by GenericCanadian on Tuesday July 04, 2023 @07:26AM (#36585203)
Its true, Bevy is quite limited with only simple parent/child relationships[0] and much of the community is looking for more structured relations.

As it stands its pretty common to hold a `HashMap<Index, Entity>` and manually manage the data structure through derefs or some system that keeps it consistent. Ideally only using it for lists of entities that remain static like a tilemap.

[0] https://taintedcoders.com/bevy/hierarchy/

Re:Data-Oriented Design by jackmott42 on Monday July 03, 2023 @12:15PM (#36575066)
The advice of keeping the data you access frequently contiguous in memory applies to everything on modern hardware. If there is a program where performance is an issue at all, probably this will be one way to make sure performance is good.
Re:Data-Oriented Design by marcosdumay on Monday July 03, 2023 @12:43PM (#36575468)
Well, if you want to generalize, it's about keeping data with correlated accesses close to each other and aligned inside memory pages, and failing that, yes to keep it at least contiguous. It's not exactly about access frequency, except that you want to optimize the things you access more.

Yes, that's a generic advice for high performance applications that is at least generic enough to apply on anything that is close to a normal computer. You will still need further details if you are talking about things like HPC (ironically) or mainframes, but it's general enough to say people should do it without qualifications.

Re:Data-Oriented Design by feoren on Monday July 03, 2023 @01:06PM (#36575872)
But it is true, much much more often than you probably realize. Just look at your tables and think about how repetitive they are. The reason you can't come up with a lot of "column-based" (as you put it, which is still narrow-minded IMO) operations is because you've never looked for them before. Of course you haven't: you've been stuck in the traditional mode where such things are basically impossible.

Do most of your tables have Name / Description type fields? Here's some "column-based operations": Allow translation of everything in your database. Generate natural-sounding text in a report, inserting these names and descriptions (from multiple different tables, of course). Free-text search of all your important database concepts. Detect similar names to the one the user is wanting to add, to prevent duplication. Clean whitespace. That's five off the top of my head.

Do most of your tables have Archived / Status / Soft-delete type fields? Allow a user to archive a record. Choose whether to include archived records in a query or not. Delete archived records after X days.

Do most of your tables have Comments fields? Allow multiple comments. Track who made a comment and when. Track responses to comments.

Do most of your tables track who last modified the record? Track all modifications. Show a list of recent modifications to any records.

The list goes on and on and on. You call these "column-based operations", which again, is short-sighted. They're more like "concern-based operations". And it turns out everything is a cross-cutting concern. You're shooting this idea down without nearly understanding it.

Re:Data-Oriented Design by feoren on Monday July 03, 2023 @01:57PM (#36576555)
Good lord! Imagine being in such a state of mind that you read the above comment and downvote it! Downvoter: if you disagree with me, then give me an example of a domain where concern-based operations aren't important. Remember the original context:

> Games just happen to have a lot of operations that need column-based access; but that's not true for all domains. When you go and blindly push the game best practices into other domain, you are just making everybody's life hard and most systems worse.

There's no reason why "blindly pushing game best practices" is really any more blind than "blindly creating one table per noun in your domain", as the rest of you all do. Yes, you do.

So what is it? What is the domain that is so obviously devoid of important concern-based operations that you silently downvote a comment for mentioning 12 extremely common examples? Obviously your domain has no text, no record archiving, no soft deleting, no commenting, no tracking of changes. What is this domain?

Re:Data-Oriented Design by AdieuToLogic on Monday July 03, 2023 @02:44PM (#36577214)
> Imagine being in such a state of mind that you read the above comment and downvote it!

  Please don't comment about the voting on comments. It never
  does any good, and it makes boring reading.
source: https://news.ycombinator.com/newsguidelines.html
Re:Data-Oriented Design by feoren on Monday July 03, 2023 @04:01PM (#36578031)
I don't see that as disallowing "for those who disagree with me: what do you disagree with, exactly?" Isn't that a reasonable question?

Besides, isn't downvoting someone for nonsensical, petty reasons (and leaving no response as to why, of course) at least as harmful to the overall discussion as referring to those downvotes?

Re:Data-Oriented Design by loup-vaillant on Monday July 03, 2023 @07:00PM (#36579916)
> "for those who disagree with me: what do you disagree with, exactly?" Isn't that a reasonable question?

It's a hopeless one. People who downvote generally think you're not worth actually answering. Also note that heated language often gets automatically downvoted. And with few exceptions ("eating babies is bad"), one sided opinions tend to be less popular than anything that appears "balanced".

It's especially tough if your one sided opinion is attacking a popular practice.

Re:Data-Oriented Design by AdieuToLogic on Monday July 03, 2023 @07:36PM (#36580232)
I have not down-voted any of your submissions. Instead, I replied with the above to help explain why you were experiencing what you have.

> Besides, isn't downvoting someone for nonsensical, petty reasons (and leaving no response as to why, of course) at least as harmful to the overall discussion as referring to those downvotes?

I would imagine so. However, the culture here AFAIK is to down/up vote as one sees fit and not provide an explanation of same.

HTH

Re:Data-Oriented Design by feoren on Monday July 03, 2023 @04:04PM (#36578079)
For those who disagree, please give an example of a domain that is devoid of important "concern-based" operations.
Re:Data-Oriented Design by forrestthewoods on Monday July 03, 2023 @01:12PM (#36575966)
Hrmmm. Not sure this line of thinking makes sense.

Game data access patterns are quite brutal. OOP for games results in extremely inefficient cache use, lots of random access, and lots of pointer chasing.

ECS isn’t a “natural” fit for games. It’s quite difficult and ECS systems are still far from a solved problem.

The two most popular game engines, Unreal and Unity, are decisively non-ECS for almost everything they do.

In any case, I think the underlying principles of DOD apply to all programs. Specific solutions vary, as always.

Re:Data-Oriented Design by marcosdumay on Monday July 03, 2023 @01:48PM (#36576443)
> In any case, I think the underlying principles of DOD apply to all programs.

Yeah, I do agree with that.

Re:Data-Oriented Design by DeathArrow on Tuesday July 04, 2023 @05:59AM (#36584475)
> The two most popular game engines, Unreal and Unity, are decisively non-ECS for almost everything they do.

Unity is promoting Data-Oriented Technology Stack which includes ECS. They even made some tools to help translate between Gameobject based workflows and ECS based workflows.

Re:Data-Oriented Design by meheleventyone on Tuesday July 04, 2023 @07:39AM (#36585332)
Although most of the team has been gutted and it's still not in a great state.
Re:Data-Oriented Design by paulddraper on Monday July 03, 2023 @01:48PM (#36576438)
Databases are another common cause.
Re:Data-Oriented Design by 10000truths on Monday July 03, 2023 @02:17PM (#36576846)
It's not just column-based access. Formatting your data into a struct of arrays exposes opportunites to pack your data more efficiently and greatly reduce your application's memory usage. Boolean struct fields can become bitsets. Nullable struct fields can become sparse (or dense) maps. Pointer/reference struct fields can become arrays of smaller-width integers that index into a pool. And so on. When everything runs on CPUs that frequently stall on memory accesses, the impact of these sorts of changes cannot be understated - the latency difference between L3 cache and RAM can be on the order of ~10x.
Re:Data-Oriented Design by torginus on Monday July 03, 2023 @05:04PM (#36578813)
I feel like this is increasingly the only way to write high-performance code.

With newer hardware, the only thing that's expected to scale is logic density - SRAM (and cache sizes) have stopped scaling with the latest lithographies - and RAM bandwidth hasn't really been scaling for quite a while (I'd think it's even possible that per-core bandwidth has been decreasing) - memory access has been the bottleneck for a while.

Re:Data-Oriented Design by _dain_ on Monday July 03, 2023 @05:05PM (#36578820)
>Games just happen to have a lot of operations that need column-based access; but that's not true for all domains.

This was not at all obvious when ECS first came around. It took a lot of time to convince people away from the OOP way.

Re:Data-Oriented Design by gnuvince on Monday July 03, 2023 @10:22AM (#36573301)
> I don’t accept that it’s wholly incompatible with OO

It's not incompatible with the mechanics of OO, but it does require that programmers change how they approach problems. For instance, a common way to write code in an OO language is to focus solely on the thing you want to think about (a user, a blog post, a money transaction, what have you) and to implement it in isolation of everything else, to hide all of its data, and then to think about what methods need to be exposed to be useful to other parts of the system. The idea of encapsulation is quite strong.

In DOD, it is more common for data related to different domains to be accessible and let the subsystems pick and choose what they need to do their work. Nothing about Java or Ruby would prevent this, but programmers definitely have mental barriers.

Re:Data-Oriented Design by AndrewKemendo on Monday July 03, 2023 @10:28AM (#36573395)
>The idea of inserting an entity id into a “published” table, instead of setting a boolean “published” field to true, doesn’t always come naturally. Yet once you realise how readily polymorphic this is, you may start wanting to use such approaches to data for everything.

Wow thank you for this, it's a heuristic I didn't think about but is really powerful.

I need to think through some of the implications, cause I think there are some risks to this approach - namely co-mingling production and non-production data in the same infra. That means that there are data at rest and in transport that are following the same data pathways but have different production criticality. It puts a lot of risk on the filter working perfectly, rather than not even being available on the same infra.

Just spitballing:

Is the ostensible "prod_live_bool" flag manually set? If not then a bug in any automation would certainly cause a nasty

Are you doing column level security tokens? Wouldn't that need some kind of intra-table RBAC? In other words, it seems like if you want any RBAC within your table, then you have to bring it with you every time from the beginning because you have no idea what level of data sensitivity you'll have eventually, and refactoring an increasingly expanding table to inherit RBAC later ---- omg I can't even think of the amount of work that would be. O(n^2) level of manual work??

Does it lead to a canonical "live or not" lookup table/dict at scale?

I think the data security risks would prevent me from using this design pattern for critical applications in MOST cases, but I do love some of the patterns here and will be exploring this in the future for sure!

Re:Data-Oriented Design by Twisol on Monday July 03, 2023 @12:44PM (#36575479)
I interpreted `published` along the lines of blog posts, in which an article can be either a draft (visible only to the author) or published (visible to the world). This seems different from dev/prod venueing, where having separate databases altogether makes sense.

I understood the column-first approach more as an alternative to putting all columns for an entity in one table, especially when rows often don't populate every column. From that perspective, what's being described is a strong separation of concerns; applying this to dev/prod would be a weakening of this separation, and so probably not what is desired.

Re:Data-Oriented Design by foobarbaz33 on Monday July 03, 2023 @02:06PM (#36576672)
I don't think you're talking about the same thing as the parent comment.
Re:Data-Oriented Design by Capricorn2481 on Monday July 03, 2023 @10:33AM (#36573463)
> Alas, many developers in enterprise are rusted onto a record-keeping CRUD model and struggle to think in columns rather than rows. The idea of inserting an entity id into a “published” table, instead of setting a boolean “published” field to true, doesn’t always come naturally. Yet once you realise how readily polymorphic this is, you may start wanting to use such approaches to data for everything

I don't really understand what's Polymorphic about this, or even beneficial. It seems like everytime I've had a boolean column in a long-standing application, it eventually needed to turn into something else

Re:Data-Oriented Design by andsoitis on Monday July 03, 2023 @10:43AM (#36573617)
> high-performance code was “work on structs of arrays, not arrays of structs”

Wikipedia's article "Array of Structure (AoS) and Structure of Arrays (SoA)" explains the trade off between performance (SoA) and intuitiveness/lang support (AoS): https://en.wikipedia.org/wiki/AoS_and_SoA

They also get into software support for SoA, including data frames as implemented by R, Python's Panda's package, and Julia's DataFrames.jl package which allows you to access SoA like AoS.

Re:Data-Oriented Design by geokon on Tuesday July 04, 2023 @05:27AM (#36584210)
I'd also mention Clojure also has a very performant 'tech.ml.dataset' equivalent to dataframes

Maybe I'm wrong, but AoS VS SoA seems like an old C false dichotomy that's been already effectively resolved

If you need to choose between the two then the answer is probably neither - use an appropriate table datastructure

There is an extra layer of abstraction and software, but I don't really see any downsides. I'd love to hear some arguments against

Re:Data-Oriented Design by meheleventyone on Tuesday July 04, 2023 @06:48AM (#36584880)
The downside is losing the conceptual understanding of why one or the other organization is the fastest for the data in question. From the POV of a general table data structure how does it decide which kind of memory organization is the most performant?

Looking at the examples referenced it looks like sugar over SoA so things look comfortably like normal but SoA isn't necessarily the most performant layout in memory depending on how things are being accessed.

Re:Data-Oriented Design by geokon on Tuesday July 04, 2023 @09:07AM (#36586162)
Isn't SoA basically always more performant though? You're either traversing individual "columns" and leveraging cache locality, or you're not and then you can traverse multiple columns in parallel to rebuild the structs on the fly.

I could only see this degrade or be suboptimal if you have a very small struct that still all in-cache (like an array of 3d coordinates or something)

Re:Data-Oriented Design by gpderetta on Tuesday July 04, 2023 @10:03AM (#36586841)
SOA is optimal only if you are iterating sequentially over many elements on a subset of the columns.

Really the right layout is access dependent.

Re:Data-Oriented Design by meheleventyone on Tuesday July 04, 2023 @10:09AM (#36586914)
If you’re always accessing all the members then no. SoA shines when you want to access a different set of a few members of a struct in different contexts. Then there’s also the option of building temporary arrays of just the data you need then spinning through it which can be faster for some things. For example rendering pipelines. Even more so if you cache the results and can use them next frame due to temporal locality. There’s no silver bullet you’ve got to sit down and look at your access patterns and profile.
Re:Data-Oriented Design by bionhoward on Tuesday July 04, 2023 @07:56AM (#36585482)
I’d push back on this by writing the Pandas and Polars etc of the world could be a lot better if they supported generic types. The fact the DataFrame is not connected to your struct / types is a big problem because everyone everywhere has to write at least two functions and probably more like 14 functions to enable basic CRUD operations on Struct of Arrays correctly given Structs.

For example, you need a StructOfArraysToArrayOfStructs function and ArrayOfStructsToStructOfArrays function and StructToRow and RowToStruct at least. Making sure those work for all the various types of thing in a programming language like python is no easy feat. Not having those functions built in, means everyone has to make sure those functions work on their own.

Re:Data-Oriented Design by rawgabbit on Monday July 03, 2023 @11:03AM (#36573922)
In the data side of the world, "structs of arrays" translate to column based indexes i.e. Snowflake and OLAP. "Arrays of structs" translate to relational databases with its page/row based indexes.

FWIW, I am a big fan of Snowflake and think it will eat everyone else's lunch. I also find it amusing that Snowflake "supports" foreign keys but don't enforce it. In other words, Snowflake is as "nosql" as I care to go.

Re:Data-Oriented Design by nerdponx on Monday July 03, 2023 @11:15AM (#36574078)
Or an in-memory "data frame" like in R, Python's Pandas, and Polars.
Re:Data-Oriented Design by OJFord on Monday July 03, 2023 @08:18PM (#36580581)
> "supports" foreign keys but don't enforce it

As in, you can have a sort of 'link' to another table, that not only mignt be null, but might be a value which doesn't exist over there?

What does the 'support' add over just having a column in which you tell yourself (but not your DBMS) you're storing values which correspond to keys in another table?

(You can take it further - s/keys/values in a column/ - many to one relationships without an intermediary table! Amazing! ...more 'NoSQL' than I care to go I think, for almost anything.)

Re:Data-Oriented Design by rawgabbit on Monday July 03, 2023 @08:30PM (#36580651)
https://docs.snowflake.com/en/sql-reference/constraints-over...

Note Snowflake supports defining and maintaining constraints, but does not enforce them, except for NOT NULL constraints, which are always enforced.

Re:Data-Oriented Design by OJFord on Wednesday July 05, 2023 @05:57AM (#36598124)
I don't understand what it means (and that page doesn't explain) for a 'constraint' not to be enforced? Do you somehow get some sort of warning, but not an error, i.e. the insert/update is allowed to work, everything proceeds as normal, but it's there to check on and correct if you want?
Re:Data-Oriented Design by Ovid on Monday July 03, 2023 @11:05AM (#36573945)
I've tried to push entity-component-systems (ECS) for non-game applications. A financial company in London took that advice to manage the complexity of their system since it was such a good fit.

For those who are curious, here's a very brief introduction to ECS: https://dev.to/ovid/the-unknown-design-pattern-1l64

Re:Data-Oriented Design by F-W-M on Tuesday July 04, 2023 @03:34AM (#36583439)
Would you mind to elaborate a bit on your system? I tried to do something similar for an algo trading system, but in the end I hadn't enough entities to justify the approach.
Re:Data-Oriented Design by meheleventyone on Tuesday July 04, 2023 @06:25AM (#36584684)
I think there's a widespread misconception about the reason ECS exists and what problems it solves. It's a design for a general-purpose game engine where it solves the problem of having some conception of the game world and the things that make it up without knowing in advance what those things will be. This is a common issue with loads of different approaches in game engines.

ECS contrary to popular imagination doesn't have to be implemented with data-oriented principles and there are lots of implementations, particularly in dynamic languages that use the same design without the performance boost you might get once you do follow them. Once you unpick the data-oriented rabbit hole you quickly discover it also largely complicates the original design.

If you have a specific thing in mind then use the data-oriented principles on that and skip building something general purpose. This works for games as well as business applications. It'll be much simpler and easier to make performant.

Re:Data-Oriented Design by ryukoposting on Monday July 03, 2023 @11:56AM (#36574764)
Very insightful. I never thought about it like this, but it's common practice in embedded systems to approach problems in this way. One module may provide a statically-sized pool of like objects, and other modules extend behavior in relation to those objects by carrying buffers of pointers and/or indexes into that pool. It might feel inefficient due to the storage of so many pointers/indexes, but you're optimizing the size of the largest thing: the object pool itself.
Re:Data-Oriented Design by incrudible on Monday July 03, 2023 @12:10PM (#36574987)
> you may start wanting to use such approaches to data for everything

Please, dont. Arrays of structs is more natural for a reason, SOA is not universally faster and it has some of its own performance problems. If you really care about performance, AOSOA may well be your best bet. Again, please dont use it for everything.

> a dhcp pool full of cats is half the fun

Replacing the weird code that the last guy wrote for his own amusement is not fun.

Re:Data-Oriented Design by hu3 on Monday July 03, 2023 @12:32PM (#36575315)
> The idea of inserting an entity id into a “published” table, instead of setting a boolean “published” field to true, doesn’t always come naturally.

It doesn't come naturally because now you need a JOIN in your SQL just to fetch what was before a column. Or two queries instead of one.

Not to mention having closely related data spread in different tables increases cognitive load.

You just added a layer of indirection for what gain precisely?

Re:Data-Oriented Design by xupybd on Monday July 03, 2023 @06:09PM (#36579455)
I think they're arguing that you get a performance gain. Personally the systems if deal with wouldn't gain from such and optimisation as there is too little data. So I'll stick to the simplest approach.
Re:Data-Oriented Design by hu3 on Monday July 03, 2023 @08:41PM (#36580709)
I agree with you. Splitting db tables can be a net positive in very specific cases but it smells like premature optimization.
Re:Data-Oriented Design by inopinatus on Tuesday July 04, 2023 @10:01PM (#36594741)
Reduced column bloat, easy reusability, easy reporting and data extraction, ease of bulk transformation (especially stream processing), but all this is essentially repeating the book, which I recommend as an excellent read.

Contrary to the claim above, there is no additional layer of indirection simply from rotating one’s record-keeping perspective by ninety degrees. I have to reject outright the suggestion that joins are unnatural in a relational database. The opposite is true: there’s nothing more natural to a relational database than a join, and that’s even despite SQL barely paying lip service to Codd’s relational algebra. Heck, using a join instead of a predicate may even be faster, not least because decomposing entity data into recomposable per-component tables means less data to scan. And if it’s instead of an indexed query, well, an index is a relation too, so in terms of schema complexity that’s a wash. As for cognitive burden, how about the nails-down-a-blackboard dissonance of dealing with tables that grow ever further rightwards with each new product manager.

None of this is to downplay the sheer productive rapidity of letting your template generator spit out a bog-standard CRUD app, it’s more to undermine and challenge assumptions about what deserves to be the conventional default, and to suggest that we can safely and reasonably change perspective to allow a little programmer happiness in.

Re:Data-Oriented Design by hu3 on Tuesday July 04, 2023 @11:29PM (#36595222)
> Reduced column bloat, easy reusability, easy reporting and data extraction, ease of bulk transformation (especially stream processing)

Respectufully, this sounds like just a bunch of words with no explanation. To pick one topic from that, reporting is easier when you don't have to JOIN more tables, not harder. Same for data extraction. And how can bulk transformation be harder just because a column is where it would intuitively reside and not in another table who knows where?

> I have to reject outright the suggestion that joins are unnatural in a relational database.

I'm afraid you misunderstood. It's unnatural to me, the developer, not to the database, to spread closely related columns accross different tables.

And "tables that grow indefinetly" is doing a lot of heavy lifting for those arguments. Most tables don't grow indefinetely.

Like I said, smells like premature optimization. I optimize for humans first.

Re:Data-Oriented Design by glun on Monday July 03, 2023 @11:24PM (#36581811)
This architecture completely ruins your write performance. Theres a reason double databases, one OLTP and one OLAP, is the norm.
Re:Data-Oriented Design by winter_blue on Tuesday July 04, 2023 @04:54AM (#36584015)
Wouldn’t structs of arrays affect cache locality adversely, if say you’re say reading and processing the data in sequential order? You’d have to jump between memory addresses that are pretty far apart to read in a single record / set of fields, and potentially trigger cache misses since they’re likely spread out across different memory pages and you end up filling your L1/L2/L3 cache?
Re:Data-Oriented Design by cellularmitosis on Tuesday July 04, 2023 @05:00AM (#36584057)
it depends on the access pattern. If you are performing an operation where you need to access every field on each object, then yes you'd be better off with array of structs. But at least in games, it seems more common that you'd need to e.g. get just the x-y coords of every monster, in which case struct-of-arrays is better.