Schema-Free MySQL vs NoSQL
igvita.com
igvita.com
Instead of defining columns on a table, each attribute has its own table
(new tables are created on the fly), which means that we can add and
remove attributes at will. In turn, performing a select simply means
joining all of the tables on that individual key.
... and now you know why nobody is doing this.Back before NoSQL had a name (and fast implementations) and we would just build key-value stores inside of relational databases and describe them to people as "tall, skinny tables", this was how you would construct a query.
Of course, it was a lot easier in a skinny table than the method you describe because you'd simply join the table back on itself n times rather than having n tables sitting around in your database.
Regardless, doing things that way was generally regarded as a bad idea even back in the 90's, and was only something to consider when you had highly-configurable things to describe that didn't fit well into a relational structure. Everybody realized that you suffered huge performance hits at query-time, and you were essentially eliminating the possibility of reporting.
So no, given that NoSQL is all about using key/value stores to boost performance by trading off reportability, this solution (which actually trades both sides of that equation away) is not a replacement.
My point is that the decision to choose your dbms should be driven by, the kind of data you have, and the kind of queries you are going to run. If performance really matters to you, you should really do some empirical testing before choosing the technology. Both there is some give and take here, one is not definitively better than the other.
That said I agree with you that this is a bad solution don't simulate a column store with a row store it won't perform as well as a good column store since it is not optimized for tuple reconstruction.
I've recently been doing some load-testing of key-value stores for caching, and also found that MySQL compares pretty favourably with some of the new kids on the block.
Just talking a "create table (key char(64) not null, value blob not null, index (key))" schema. (Plus some MySQL performance tweaks, which I won't go into here)
Some advantages:
* When it comes to redundancy and failover, you can re-use the existing master/slave replication functionality in MySQL, rather than worry about whether your k/v store of choice supports anything like this, how stable it is and how to configure and manage it etc. One less thing to worry about especially if you're already doing mysql replication for other data.
* MySQL can keep hot data in RAM and cold data on disk, and is pretty tuneable in this regard; some of the trendy k/v stores aren't so hot on this front (eg Redis, although they're addressing it in version 2)
* With InnoDB tables (which are pretty good for k/v functionality) you get the transaction support which can save your ass from some nasty race conditions with concurrent processes writing back to a cache. Especially handy if your main relational dataset is also in MySQL since you can update the normalised data and the cached data in one transaction
* You can join 'relational-style' tables directly to the 'k/v-style' tables, rather than having to fetch a bunch of IDs and then look them up (for some stores, one at a time) in a separate store. Which is a great when you have some infrequently-changed data that can be denormalised as cached blobs, and some frequently-changing data which refers to it.
* Possibly more...
I'm assuming you mean tweaking MySQL just for k/v store usage.
One thing was forcing InnoDB to cluster by insertion order by adding an otherwise-redundant autoincrement primary key alongside the unique index on the actual key column. Also tweaking various innodb-specific config settings.
Not only was the solution faster, but it made code so much more concise, because you can just serialize Python objects to the database rather than write a huge database abstraction layer. For me this is even more valuable than the performance ramifications.
If you're using Python+MySQL, be sure to check out Tornado's database wrapper (http://github.com/facebook/tornado/blob/master/tornado/datab...) because it handles all sorts of sharp corners that straight up MySQLdb won't (like working with binary data, reconnecting when necessary, etc.)