|Keep It Simple, Stupid|
But, as an implementation detail, it's ok to have instances of two different classes have some of the details of your checking account, if not the ability to modify it.
I'm not sure that I'd agree with that myself. In my experience duplicating application state in multiple classes leads to the same sort of problems that duplication in a DB cause.
If I see duplicate state in a class hierarchy my first thought would be that there is a missing abstraction to be discovered, and my second thought would be that this would be a good area to look for bugs.
Not that I disagree that "Database decomposition is very different from class decomposition", because it is ;-)
Well-written OO code is inefficient
I agree with what you're saying here, but it's nothing to do with well written OO code being inefficient. Quite the opposite.
If an application needs to open four database connections for four queries we have a bad design. Badly written OO code being inefficient isn't really surprising.
(Interestingly enough I've seen similar problems from the opposite direction - with RDBMS people doing OO coding and creating lots of unnecessary "join" classes leading to hideously inefficient bloated code. Again this says nothing about the relative efficiency of OO or RDBMS models - just that they're different and you need to use the right one in the right place.)
Getting the most out of a database is HARD
I don't think it is actually. Don't scare people away!
At least, it's not any harder than getting the most out of an OO decomposition, or getting the most out of a functional decomposition.
It needs to be learnt, and more people need to learn it, but the basics are not that complicated.
The hard bits about databases aren't really the general theory, but the nitty gritty specifics about individual implementations.
Classes are not tables and attributes are not columns
Amen. Twice. In bold. Underlined.
Too many OO developers treat RDBMS as suboptimal object persistence layers, which is kind of like treating a train as a suboptimal car. True, but somewhat missing the point.
Smaller applications and certain subsystems of larger applications which do not have a performance component can benefit greatly from the ease-of-development that CDBI provides. But, without a lot of customization, those kind of tools do not scale well.
I'm not sure what you mean by "scale well" here. I've certainly used CDBI in large production systems without any problems.
It's certainly not suitable to all systems (because it has that one-table-per-class concept built into its core), but where it is applicable it works well in my experience. Where it doesn't work well you can always hand roll your own, or use one of the more flexible OO-RDBMS mappers.
However, stored procedures, while within the database application, have very little to do with the core function of a database - data storage and retrieval. At best, they are syntactic sugar that can help maintain data integrity. But, that is a far cry from saying that databases have behaviors.
Maintaining data integrity can hardly be called "syntactic sugar"! (and what else are we to call stored procedures, triggers, etc. if not behaviour?)