The first great blunder
, according to DateAndDarwen
, is the treatment of relations (in the RelationalDatabase
sense) and classes (in the ObjectOriented
sense) as equivalent. Instead, they propose DomainsNotRecordsOrTablesAreObjects
Specifically, they say:
- What concept is it in the relational world that is the counterpart to the concept object class in the object world?
- The reason this question is so crucial is that object class really is the most fundamental concept of all in the object world - all other object concepts depend on it to a greater or lesser degree. And there are two equations that can be, and have been, proposed as answers to this question:
- domain = object class
- relvar = object class
- ...the first equation is obviously right, since object classes and domains are both just types. Indeed, given that relvars are variables, and classes are types, it should be immediately obvious too that the second equation is wrong (variables and types are not the same thing); for this very reason, The Third Manifesto [3.3] asserts categorically that relvars are not domains. Nevertheless, many people, and some products, have in fact embraced the second equation - a mistake that we refer to as The Great Blunder (or, more precisely, The First Great Blunder, since we will meet another one later).
- Quoted from section 25.2 (p865) of An Introduction to Database Systems, 7th edition, C. J. Date, copyright 2000.
See also the SecondGreatBlunder
"Object class" is not the most fundamental concept in all ObjectOriented
systems. In actor systems behaviours are fundamental; in some ObjectFunctional
systems closures are fundamental; in PrototypeBasedProgramming
there are no classes as such.
and its descendants (like DylanLanguage
) are also notably different (and closer to TutorialDee
) in that functionality (methods) are separate
from state (objects).
Even for a class-based object system, domain = object class
and relvar = object class
are not the only ways to combine the relational and object models in a MultiParadigmDatabase
, and DomainsNotRecordsOrTablesAreObjects
is not the only other
way. -- DavidSarahHopwood
But isn't an object an instance of a class, and isn't an object variable similar to a relvar in that they are both variables that have data attached to them? The relvar however doesn't have methods (procedures) attached to it like an object does. Also, a STRUCT in C is very similar to a TUPLE. A tuple and a struct are so strikingly similar that it is almost important to compare the two to help programmers with understanding relational. C++ extends structs so that they have methods attached to them, which are known as class/object. The confusion and impedance mismatch continues. Undeed structs and classes can be mapped to tuples, but this is not a perfect map because tuples can't map object methods. If tuples should NOT be mapped to objects, then why are structs (plain C objects) so similar to tuples? The confusion continues again!
I don't see mapping an OO class (as a type) to the RM type (of tuples) of a relation in a relvar as a problem in itself.
(Of course there are some problems like the one of public vs private attributes but I'm just going to ignore it as it's not relevant to my point.)
Isn't the real "threat" of this FirstGreatBlunder
that of people not making normalized databases but instead creating relation-valued attributes?
So the RelationalModel
allows relation-valued attributes, but
After all doing so effectively just complicates things unnecessarily and makes sure that straightforward relational operations can't handle the data by themselves.
Thus the real problem is not that of making for example an SQL User table which looks exactly like the OO User class but of then trying to put the group ids to which the user belongs into a comma-separated string (or a Set-typed) attribute instead of making a proper many-to-many table in between. Or something similar which makes it a royal pain to do normal standard SQL queries to fetch the group tuples of the user with a single straightforward query.
This is why I think that a plain and simple "domain = object class" is a mistake as well if it allows for putting relations inside tuples.
Relations belong in relvars. Not in domains. Otherwise you can't make full use of the data in the way a relational database makes possible.
(The exception to this is of course attributes with non-scalar values that you really never ever need to treat as keys.)
Then again why can't an OO class (As a type. Not as a place to put global state into. Class variables are utterly irrelevant to this discussion.) be the type of the tuples in a relation?
Especially if one makes sure that the class implements everything required for the tuples to work as normal tuples in the relation.
Of course assuming that no relations are put inside the tuple but instead split off into a separate table or tables.
The same also applies to relations themselves.
As long as a relation in no way compromises the relational model (by implementing all the methods and/or interfaces a relation needs to have) does it matter what its class is?
If you're coming from an OO background, think of the relational model as a system of nested collections -- in particular, sets -- with algebraic operators (the RelationalAlgebra) to query and manipulate the collections. Each attribute is a value or instance, a set of related attributes is a tuple, a set of related tuples is a relation, and a set of related relations is a database. Where, in this arrangement, does a class (other than Set, Tuple or Relation) appear? Clearly, it's the type (aka the domain) of an instance, and an instance only appears in an attribute. Thus, class = domain/type. The FirstGreatBlunder is to try to identify a relation = class equivalence that simply doesn't exist.
Yes, you and D&D are absolutely correct.
I've been reading TheThirdManifesto
too and that's what they say in it.
No other classes appear in the pure relational model.
However what if one were to implement in OO code RelationalAlgebra
support on the objects by making them subclasses of or have them implement the behaviour of Tuple, Set and Relation?
Then again that would no longer be about bringing OO into RM but instead bringing RM into OO which isn't what D&D were talking about.
I still see a problem with the class = domain/type
idea if it allows for relation-valued attributes.
D&D say it's a bad idea as it isn't very relational and it's easy to see why. Or is it?
The most usual misconception or misunderstanding seems to be that of thinking that this FirstGreatBlunder
is about mapping a class to a relvar.
It's not. It's just says that they aren't the same thing and therefore no one should assume that they are.
A set of objects can be mapped to the tuples of a relation and thus their class to the type of the relation if one at least mentally
converts an object into a proposition or in other words to a tuple. Which seems to be what most popular object-relational mappers are doing.
However what you then have is a loose mapping between things and not a logical or conceptual equivalence.
"I still see a problem with the
class = domain/type idea if it allows for relation-valued attributes. D&D say it's a bad idea as it isn't very relational and it's easy to see why. Or is it?"
The RelationalModel allows attributes to be of any type, as long as values of that type can be tested for equality. Given that relation types are types like any other, we can't rationally exclude relation-valued attributes. However, that doesn't mean using relation-valued attributes is good database schema design. Fortunately, the RelationalModel and database schema design are essentially orthogonal, so it isn't a concern. Furthermore, relation-valued attributes can be useful in query results, so it makes sense to explicitly support them.
See also ObjectsAreFromMarsTablesAreFromVenus