Phases of Database Growth and Cost
crunchydata.com
crunchydata.com
Many tech blogs say you can use NoSQL to solve A, relax your consistency requirements to solve B and use offline pipelines to solve C, but these solutions only alleviate the problem, not solve the fundamental problem, the DB.
Fast-growing companies really need to plan this from day one. It's already 2022 and we have scalable distributed RDBMS like Spanner / TiDB / Cockroach, and some of them can do a bit of analytical workload as well. Plan ahead.
Eh. Use old boring dbs: mysql, etc. Systems with decades of fixes, stackoverflow posts, work arounds, migration tools, etc. Otherwise - you will learn Spanner doesn't support deletes of 100k rows in 2022 and it is discontinued in 2023 (lol made up prediction). New db tech is pretty terrible (excluding vitess db - which is now industry standard). I wouldn't treat it like a JS framework.
Here's some of what's not supported:
Stored procedures and functions
Triggers
Events
User-defined functions
FOREIGN KEY constraints #18209
FULLTEXT syntax and indexes #1793
SPATIAL (also known as GIS/GEOMETRY) functions, data types and indexes #6347
Character sets other than ascii, latin1, binary, utf8, utf8mb4, and gbk.
SYS schema
Optimizer trace
...
Not being able to use FOREIGN KEY constraints makes me distrust the viability of something like that, because in my experience DB schemas and how they're utilized without foreign key end up being dumpsterfires.Then again, at a certain scale you kind of have to look into alternative ways of how to look at working with your data, so there's that.
That said, the idea of giving people something that's compatible (for the most part) with the drivers and syntax that they already utilize is an excellent one!
Picking boring tech for crucial areas of a business is almost always the best plan.
Clearly I am joking, but the selling point was supposed to be that it provided a lean, mean, modernized MySQL replacement.
I think the problem was that replacements under the hood don’t necessarily translate to an improved UX.
An interesting aspect is that the Database is a large part of the data pipe, but it often is insufficient for the product. The key issue being torn writes between the database and a service like twilio or elastic-search. A good way to broker this is via a queue, or to use a tailer via kafka for your data pipeline.
My gut is that so many things are just held together by bail wire, and the complexity is depressing to me. So, here I am, inventing a new thing.
I've invented a language called Adama ( https://www.adama-platform.com/ ) which allow a document to have a schema. Accidentally, I added transformation logic to the schema and then hooked it up to a socket to discover that many things were possible. I had intentions of using this thing to help get my state under control with node.js for a complex board game, but the language took over such that the entire game was eventually built within the language. Kind of neat.
My thesis is that the NoSQL pattern is fantastic for building products quickly if you don't mind the mess that schemaless evolves into, and a key weakness of what I have is that the document is limited in size in memory (which is then made tighter due to the reactive elements). However, I can leverage a logger much like a NoSQL solution to produce many of a stream of changes which I can shred into various solutions. For instance, I could put data changes directly into snowflake to provide massive scale queries.
There are some neat possibilities with this approach, but limits as well. However, I'm not sure if planning ahead is the most effective thing for a startup. I believe a new discipline over the coming decades will emerge regarding how to pick the appropriate level atomic unit of data, and then the skills to break down that unit will be more common place.
Analytical dbs seem to adding transactional workload support to them. Snowflake announced something to that effect this week.
https://siliconangle.com/2022/06/14/snowflake-bids-transacti...
If we design architectures that hide db access (should it exist) behind a service, better yet. A FOO data service for FOO data and callers don't care how it's stored . . . then it's not heavy, is it? Not that the caller cares about.
You're talking actual implementation details before we talk about partitioning responsibility.
That's the dream, but often the answer is "no, not even sort of".
Plenty of companies with super smart and experienced engineers laying the DB foundations for a company early in its life have failed at this goal. A few problems come into effect, two immediately spring to mind:
1. Eventually some engineer comes along with a reasonably compelling business case to either pass by the abstraction layer, or extend it so that it's no longer general (e.g. now it only works for Postgres).
2. As the company scales Hyrum's law comes into effect and a thousand pieces of code come to have subtle dependencies on implementation details of the DB.
(2) is particularly hard to avoid because DBs are often at least the nominal source of performance bottlenecks and engineers will do almost anything to make performance acceptable no matter how horribly it wrecks abstraction layers.
* ORM bypass, for better performance. * Sharding and application level handling of sharding (making DB not transparent) * Replication (and obviously, delays)
And there are always tons of application level code just written because DB just cannot do it efficiently.
Unless you're building a piece of software where database agnosticism is actually a required feature, then I generally find it to be a very poor tradeoff. Databases are incredibly powerful, you should be using them to their fullest extent rather than purposefully handicapping yourself.
Still a good article where the first phase lines up with my experience exactly but I kind of lost the point of the second phase. To me phase 2 is 1) indexes, 2) partioning/sharding (and maybe introducing a Postgres addon or switching Postgres vendors to support this), and 3) rethinking what gets stored in Postgres in the first place or 4) setting up processes to migrate old data out of Postgres into s3 or something.
[1] https://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80...
How do you handle referential data? Like, order lines should have a foreign key linking them to the relevant order "head". Self-referential foreign key on the id table?
Also, how's performance on a single node with a wide-ish "table"? Like, say I need to insert 1k rows x 30 columns, a fairly common, light load for us.
edit: oh yeah, and what about indexing? We have a lot of indexes that touches 3-5 columns, and some even more, and almost all of those mix data types. For example we might have an (varchar, timestamp, varchar) index. Some of these are unique indexes, for consistency. These are crucial for normal operation.
As I refactored the library over the years, I realized more and more that increasing the scope and encompassing an entire content management system actually made things easier (still retaining the ability to INCLUDE any custom php file), as I could do the entirety of every web page in a single MySQL connection (open the database connection as the start of the page, doing the myriad queries the page required, then close the connection at the end of the page). In the general case, MySQL typically spends a lot more time making connections that it does executing queries.
And then I realized the bulk of my SELECT statements were used to create grid tables from large data sets. Standard data grid table with CRUD + search + sort capabilities on every column and every row.
I took a look at this from first principles and realized if I split the queries into two (one for the rows and another for the columns), I could eliminate the ugly IFNULL(MAX(CASE ... statements. In other words, you create one loop just pulling out the id for each row and inside that loop call another loop for all the grid columns based on that id needed to display that row. Assuming a grid of 30 rows with 20 columns say, that is 21 queries (but all over a single database connection). Of course you manage all the grid tables with pagination, so you might have 10,000 grid pages displaying 300,000 records 30 at a time on each page. If you present those grid tables in a usable manner (sorted by records most frequently accessed/updated, most recently accessed/updated etc), then statistically most of your users stay on the first grid page. And you manage the LIMIT statement to only ever get the 30 "virtual" records on the current page, whether in PHP or in JSON. Pretty fast!
As far as indexing is concerned, well each of the 7 real MySQL tables was indexed, so yeah EVERY field is indexed whether you want it or not. Creating combined indexes between tables has not been attempted.
So I got that approach performing nicely, then took it to another level putting the database schema itself inside the database. I could now build a "virtual" table from combining as many of the 7 fields as required for any given table definition. And just like a real MySQL table, you could join multiple "virtual" tables. After all an EAV database is about as normalized as you are ever going to get (one field per table, plus 2 indexes). Of course this is all done in data, so imagine a standard web table grid being used to Create/Retrieve/Update/Delete all the "virtual" table field definitions, labels, css values, etc..
This approach satisfied two of my business requirements - one need was to have a single framework to support a small number of clients with large datasets (e.g. millions of records, hundreds of tables). For them, I now had a tool where you do not need to be a programmer to create a simple web table grid of data. And where they needed hand-holding on more complex requirements, solutions could be deployed in a fraction of the time it would have taken me using traditional methods.
The other need was to support a large number of clients (thousands) with very simple database requirements (e.g. for the business customers of an ISP). Now I had one database framework to do both.
Doesn't satisfy every need, but it does one heck of a lot and takes care of all the low-hanging fruit. Like most developers who have been working for decades, it may have taken me that long to arrive at, but recreating it from scratch could be done very quickly.
I had guessed at your approach, and I wasn't too far off it seems. Moving the processing to the software level (rather than staying in the db layer) makes sense.
A challenge we have is that for many of our UIs, we have very wide rows. Our main "offender" has over 100 fields on the main page, and that table also has several 3-4 level deep child tables.
Would be interesting to see how it would perform using your approach. I might just have found another summer vacation project, just for fun...
Not that I think it would work for us, like I said we rely on multi-column indexes for performance and consistency so that's probably a show-stopper right there. But I do like to try different approaches just for the experience.
Do what works for you I guess.
I basically manage 2 EAV databases - a production one with the 7 tables (discussed) and a development one with the same 7 tables, where I will do imports, migrations, and such. One thing that is truly chaos is when you have hundreds of "virtual" EAV tables with 10's of millions of records (or more) in just 7 tables .... and the house of cards comes down for whatever reason (master-master replication failure, clustering failure etc). Gives you a whole new appreciation of the beauty of a simple flat file database.
I totally agree with you on developer productivity. Said another way, to connect technology & finance: early on, when developer cost is much more significant to the company than infrastructure costs, emphasizing developers building the right product is more important than optimizing the infrastructure costs.
Secondly, I am a fan of ORMs. I exclusively use ORMs on CRUD-based actions. The typical first-fix for ORMs I see is to move dashboards, reports, and aggregations to native SQL. Just doing that get you a lot of performance improvements. Recently, for a friend, not associated with Crunchy & not using Crunchy, I helped them lower their cost of database operations from $2500 / month to $500 / month. All I did was find the slowest queries, determine the ORM was running a slow query, and doing an N+1 query , then point them in a direction to fix it. Because their cost of operations were looking at increasing so quickly, they were looking at migrating to a different database, NoSQL, or something else.
Again, appreciate the feedback. Cheers.
I don't make money from them, but I tolerate them because they really help me scale right. Countless data and other optimizations have come from monitoring their usage