Application vs Database Programming
ledgersmbdev.blogspot.com
ledgersmbdev.blogspot.com
Worse is when some optimizers suddenly switch plans to something that is inefficient. Sybase had a really bad habit of this with big datasets.
Sadly, a lot of the problem comes down to schema design. A lot of designs are just fine retrieving one item and its attributes from the database, but get into trouble when you try to retrieve a group of items with the same attribute from a database. Status reports (e.g. how many unpaid invoices do we have?) tend to sniff these problems out. I generally follow the rule "if a single attribute on an item is important to know, then knowing all of the items with that attribute is going to come up and should be designed for".
If you're working with a pure key-value store, the only query you have is get(), plus maybe a scan over all keys. Stores like Cassandra give a little more structure to the data (column families, supercolumns, etc.) and you can use that to make certain types of queries simpler, but there's still nothing like the algebra that comes with relational DBs. Anything other than the most primitive logic is going to have to be written in client-side code, which is why you see things like MapReduce used to filter down large data sets or other complex client-side transformations.
The advantage of writing on the client is that you get to use whatever the hell programming paradigm you like: pretty much any language that can deal with a hashmap can deal with NoSQL. (That's true of relational DBs, of course, since you don't have to write complex queries; but if you're not taking advantage of the relational structure, NoSQL tends to be easier / faster.)
I'm not sure if I like that rationale for using NoSQL. Strikes me as being lazy up front. Or maybe you don't really need ad-hoc queries.
Here's a good article on NoSQL data modeling that covers it better, along with some good discussion in the comments:
http://highlyscalable.wordpress.com/2012/03/01/nosql-data-mo...
Nothing wrong with ORMs at all. Just that I would have expected at least a little SQL as introduction to relational (set) thinking. I hope that we haven't simply gone completely OO-imperative in classes these days.
BTW, wait until you see the SQL generated by some report generation tools - pages and pages of very weird SQL
This is the peril of leaving programming education to the computer scientists: People are routinely forced to rebuild a car's engine before being told what a stoplight is or how to merge onto the freeway.
And it might help explain why my coworkers think I'm some sort of RDBMS genius when all I've ever done was read SQL for Web Nerds:
Database researchers love to talk about relational algebra, n-tuples, normal form, and natural composition, while throwing around mathematical symbols. This patina of mathematical obscurity tends to distract your attention from their bad suits and boring personalities, but is of no value if you just want to use a relational database management system.
In fact, this is all you need to know to be a Caveman Database Programmer: A relational database is a big spreadsheet that several people can update simultaneously.
A caveman I may be, but I tell you, if you can type SHOW PROCESSLIST, EXPLAIN PLAN, and CREATE INDEX with effect, write a self-join, and use the GROUP BY… HAVING syntax, many people will speak of you as they would of Gandalf. It's embarrassing, really.
As someone who works on a "big spreadsheet that several people can update simultaneously", I can't resist making an off-topic comment.
The analogy between spreadsheets and relational databases is seductive because both appear to use tables (actually, spreadsheets use a grid addressing system which only looks like a table). But really the two are from different planets: their data models as well as their computational models are incompatible. For example, compare how databases relate data (foreign keys) to how spreadsheets do it (cell references). What do these have in common? Basically nothing.
The point may seem esoteric, but there have been lots of attempts to combine spreadsheets and databases and they all run aground on this mismatch. Crude integration a la import/export works ok, but the perennial dream of having a true spreadsheet on top of a relational database is out of the question unless you sacrifice efficiency, which you can't. I do wonder sometimes how far you could get implementing SQL on top of spreadsheet data.
As an aside, it's interesting that the research literature on databases is vast and rich while the literature on spreadsheets (alas!) approximates nil.
Wow. Just curious, have you ever programmed professionally? If not, I'd highly recommend you learn to write raw SQL. And not just the basics but really learn it in depth. ORMs are definitely very useful but I've never been able to complete a single project without writing a fair amount of SQL because the ORM was too slow or couldn't give me what I needed.
ORM is great when a database is being used as a simple program data persistence layer, but if you limit yourself to that then you might as well use a NoSQL solution.
They are such a nightmare to read, there's no exposure to them in the code that your IDE can make sense of, if there's a performance problem it's almost always down to one of those huge queries and in the end most software I work with the DB engine is either on the same box or on the same network so pushing across more rows to process in the app in a far more generic way doesn't cause the sort of latency problems you describe (seems a pretty rare config imo).
So I disagree.
Also I disagree with your admittedly fairly throw away comment about ORM & NoSQL. Even if it is just a data persistence layer bunging everything in a NoSQL solution is usually going to be the wrong call in the long run. If you're dealing with data it almost always pays off to keep it in a relational structure because if the app/business is a success someone will invariably start wanting to use the data in other ways. I think NoSQL is good for a very small subset of data storage problems, I want to use it, but have yet to have had a reason to.
For the vast set of programming problems having that user table that's relationally linked to a person table that's relationally linked to a company table that's relationally linked to, etc. gives you far more flexibility than having to start dealing with getting objects out of a key-value pair store and manually piecing together complex relationships just to add a simple page to the client's admin page to say how many people have setup their account properly (as a random real-world example where the admin emails their staff and they setup their own user details).
Once you get past the basic CRUD of a problem and start having to use the data for functionality, basically past anything more than a toy program, the relational model through an ORM is going to be much simpler than a NoSQL solution.
I just don't get how this statement makes sense:
ORM is great when a database is being used as a simple program data persistence layer, but if you limit yourself to that then you might as well use a NoSQL solution
I wouldn't because as soon as you start adding fairly simple functionality the NoSQL solution would rapidly become a nightmare. To me NoSQL would be the go to solution if I had a few very basic data structures that I had to do a lot of work on, not the opposite as dmethvin suggests, lots of different objects with simple operations.
In concrete examples, Google, NoSQL, Instagram, probably NoSQL, something like Freckle (Time Tracking), SQL, Salesforce, SQL all the way.
But as I said I've not had a project or personal project yet where I've gone 'Aha, now is the time! NoSQL here I come!' so push back if I'm doing it wrong!
If you're not careful though, your program-oriented database won't be very useful outside the realm of the program. As an example, I worked on a database where they persisted a good chunk of data in each record as a JSON string. They did it because they didn't want the hassle of updating the database schema. It worked fine for their needs inside the program, but it was kind of hard to do an ad-hoc query on that.
Having said that, ORMs are terrible at generating efficient queries for anything but toy requirements. Optimising a query is hard for a human and even harder for an ORM. That massive query could just as well have been a product of the ORM.
I'm sure developers out there get by with just an ORM and treat it like a Chinese wall between them and the mystery black box that is the RDBMS. I think that's a huge mistake. Relational DBs are incredibly powerful.
insert/insert/update. Wash rinse repeat.
The better way to do it (which solved the problem was:
Insert a bunch of rows, insert a bunch of rows, update a bunch of rows, no repeating.
For example, to find the common elements in two lists, you could use a for loop, or you could follow the OP's advice and use set operations to do something like:
set(list1).intersection(set(list2))It's natural, once you lose this limiting notion of "objects" which aren't represented in a generic way.
This is important across the entirety of your dev stack.
If you let the DB pick its own query plan all the time you can end up with inconsistent performance, often by an order of magnitude or more. However, if you turn on query plan stability (every query after the first one will have the same plan) then you can end up with a state where the query plan doesn't change as the data change, which can lead to serious performance issues as a table's size grows (if your table starts out small, the DB may choose a full table scan, which is very fast, but will bog down extremely when the table grows to thousands or millions of row).
In short, performance is a hard problem, and if anything the tools for analyzing and optimizing performance for DB operations are well behind the state of the art for compiled code, for example.
I know of one company that was running IBM DB2 EEE that had a 40 node production environment with almost a petabyte of data. I also hear that the USPS database is rather big.
Snark aside, you can take the author's advice too far in the other direction as well. Relational algebra is all fine on paper, but relational integrity, foreign keys, strict normalization and n-way joins are horrible for performance. At the end of the day, the declarative SQL you write has to translate to a bunch of bulk reads from a hard drive somewhere, and you really need to understand execution plans as well if you want any sort of performance.
He's right though that as you work with more and more data, the impact of making the traditional imperative/procedural mistakes because a real problem.