3 ms·
> While this entity-attribute-value model enables the developer to break out from the structure imposed by an SQL database, it loses out on all the benefits,[1]
by jstanley 8mo ago
> While this entity-attribute-value model enables the developer to break out from the structure imposed by an SQL database, it loses out on all the benefits,[1] since all of the work that could be done efficiently by the RDBMS is forced onto the application instead. Queries become much more convoluted,[2] the indexes and query optimizer can no longer work effectively, and data validity constraints are not enforced. Performance and maintainability can be extremely poor.
This is only true if you try to do this for all of your data.
I've used key-value tables loads of times, it's convenient for storing things like global configuration.
What else can you do? Make a table that has every configuration value as a separate column and populate it with only a single row? That seems absurd and worse.
- bastawhiz 8mo ago> What else can you do? Make a table that has every configuration value as a separate column and populate it with only a single row? If the values are singletons, what you're describing is the most efficient. What the author is describing is a surprisingly common anti-pattern where someone has a table with three columns: entity id, property name, property value. Almost like a graph database. Fetching data for one entity (normally one row in a properly built db) is fine, but fetching the data for multiple entities is instantly a mess. It's worth noting, though, that unless the configuration values are all the same type, you lose type safety with just one column for values. "I'll parse the data as JSON" means your service will fail hard at runtime if someone changes the configuration and uses invalid data.
- supriyo-biswas 8mo agoPersonally I’d pass all my JSON-y stuff through Pydantic or similar which would take care of these concerns.
- bastawhiz 8mo agoIt wouldn't. If you load configuration and it's the wrong type, now Pydantic is throwing an error. You can't run code if the config is invalid no matter what tools you use: failing validation is still an error.
- nextaccountic 8mo agoMake a table with a key and a json column. Use this table as key-value store.
- jspash 8mo agoOmit the key and store it in a single json column. The worst of all worlds!
- nextaccountic 8mo agoIf the json has a natural key, you can add a json index pointing to it, at least in postgres. But this will probably have worse performance characteristics than adding a separate key column. Also natural keys suck - if a bugged json comes with repeated key (or no key at all) you will be unable to save it to process it further (well unless you have a separate table to save them). Also some jsons won't be keyed But storing something with no index at all is probably okay if you don't plan to query much (or if the dataset is tiny)
- mrkeen 8mo agoThis paragraph rubbed me the wrong way too. > work that could be done efficiently by the RDBMS the RDBMS? You're only using one? Why not spread the work out a little? Even if you think you write all your queries efficiently, nothing stops your teammates from DOS'ing your efficient queries by writing inefficient queries themselves. Last week our team started started piling up write timeouts because another team was modifying one of their tables. Not in their db, in the db. > Queries become much more convoluted Please, every ounce of effort invested in ORMs like EF/LINQ is to make code look less like querying and more like plain old object access. For the most part, devs want to work with objects and store objects. If you didn't go the RDBMS route, you wouldn't need EF/LINQs help in decomposing your objects and scattering their parts into separate tables. The least convoluted query possible is to just grab the object you wanted directly.