|P is for Practical|
The ability to change the structure of the database is an essential feature of relational databases.
Very much so. And that is one (of several) good reasons why SQL should not be embedded in application programs. Leastwise, not object oriented ones. And application programmers should not be designing DB schemas.
Applications (should) deal with application objects. Objects represent state, and flows of state, not data nor relationships.
That doesn't mean that RDBMSs can't be used to underpin application programs. It just means that there should be an interface layer between the application program and the SQL.
The make-up of the schema (tables and columns) is driven by the relationships inherent in the data. Different applications have different requirements of each relation. Read the bank balance; credit it; debit it; erase the entire relationship.
The most prevelent and effective mechanisms for these are writable views and stored procedures. Just as the Class decouples the user code from the internal representation, so views and/or stored procedures decouple the Class from the datastore schema.
That allows the DBA to amend the schema to incorporate new requirements for new applications, and tune it for a broad range of existing applications. Each application can have different logical and performance requirements, as well as different privilege levels to any given table or column.
The impedance between most development languages, procedural and object oriented, is at so many level--security, data integrity, concurrency and latency--that using them to directly manipulate relations is like using oven mitts to do watchmaking.
The only programming language I am aware of that really has the syntax and semantics for dealing with relational data natively is APL. It's set operators are very well matched to relational theory.
SQL is not (in my book) a good interface between them. It is a handy language for relatively simple queries that interogate the relationships and make set adjustments to them, but as an abstraction layer, it sucks.
Think of the times that you knew what you wanted to do, knew that the schema was capable of doing it, but get hung up on trying to frame the requirement into a form that SQL would accept. The frequency with which you will see large volumes of data pulled from a DB only to be subsetted with the application code highlights one level of impedance.