![]() | |
![]() |
| | Thread Tools | Display Modes |
#1
| |||
| |||
|
#2
| |||
| |||
|
|
Date's "Introduction to Database Systems" is an amazing book. However, it doesn't says very much on HOW one should translate a given universe of discourse into a database which can be treated as a sane representation if it. Maybe Date also wrote a book mostly concerned on this topic, but unfortunately I haven't heard of it. So, maybe someone could explain what do I do with the next situation? Here it is: There are entities with attributes (yes, very trivial). Maybe they're fiscal reports, or something.One day, however, the entities change: several attributes are thrown out, several new attributes are introduced, and for some attributes, their domain are expanded. Well, if I were using SQL DBMS, I would just add new columns for new attributes and spam them with NULLs for the older entities, and the columns for thrown-out attributes will have NULLs in them from now on. Domains? Ha, I was using a special table of "id# -- describing text", so I just add some new records in it. But what do I do if I have D DBMS, implemented strictly by The Third Manifesto? I just can't imagine. I can't use NULLs. Making tables "ENTITIES_1999-2010", "ENTITIES_2011-NOW" surely won't work. How do I extend domains, again? It's not subtyping, it's supertyping, but I dislike the idea I introduce new wider types, then rewrite the existed ones so they will be the subtypes of the newly introduced types. So, what should I do? And please, no "screw that moronic theory Date invented" replies. I won't. |
#3
| |||
| |||
|
|
[Nulls] are an efficiency feature, added to allow a reduction in the number of physical tables required, as a concession to the physical access characteristics of mechanical storage devices. |
#4
| |||
| |||
|
|
There are entities with attributes (yes, very trivial). |
|
But what do I do if I have D DBMS, implemented strictly by The Third Manifesto? I just can't imagine. I can't use NULLs. |
#5
| |||
| |||
|
#6
| |||
| |||
|
|
So, naturally, I'd like to simply add several new relvars and constraints into the DB without touching existing ones (or touching them as little as possible. Yes, they have to be designed with several things in mind, I don't argue with this). But! Let assume that in the second game a) new characters were introduced, b) Characteristic Special has gone (i.e. older characters don't have this characteristic in this game), c) Two new characteristics SpecialAttack and SpecialDefense were introduced (older characters got these characteristics too), d) The domain ELEMENT was extended -- two new values were added; e) Several older characters got new Type2 (not Type! Type2 only). |
|
This design, however, has a certain flow: There will be new games III, IV, V, and so on. And I can't write a universal query to answer a question "How many characters is in every game?" |
|
Second, how do I declare ELEMENT2? |
#7
| |||
| |||
|
|
Since some elements don't exist in all games, the obvious predicate to include in your model would be "<Element> exists in <Game>". |
|
The predicate "<Character> has <Defense>", for instance, is incomplete. To complete it, you have to change it to "<Character> has Defense> in <Game>". |
|
?????? By including a relvar for that purpose in your DB design. Plus the needed relvars or attributes for documenting how characters relate to games. |

#8
| |||||||
| |||||||
|
|
On Nov 11, 12:39*am, Hugo Kornelis h... (AT) perFact (DOT) REMOVETHIS.info.INVALID> wrote: Since some elements don't exist in all games, the obvious predicate to include in your model would be "<Element> exists in <Game>". Well, it seems to be reasonable solution. Maybe "<Element> exists starting from <Game>" would be even better. Although it means I cannot rely on domain constraints... well, DCNF is pretty useless anyway, so actually there is no big problem. |
|
The predicate "<Character> has <Defense>", for instance, is incomplete. To complete it, you have to change it to "<Character> has Defense> in <Game>". The problem is, many characteristics never change at all. |
|
TABLE CharactersExistence{Character# CHAR_ID, CharacterName CHAR, Game GAME} PRIMARY KEY {Character#, Game}, FOREIGN KEY {Game} REFERENCES TO Games; |
|
But it seems that the table Characters has to go — characters have different sets of characteristics in different games, and I can't predict what will (dis)appear or which remained characteristic change -- except for name. |
|
I think I'd want to have a relation with predicate like "Characteristic <Name> with type <Type> existed in game <Game>", and I know how to do this... but I'm afraid of it and won't do it. |
|
TABLE CharacterSpecial {Character# CHAR_ID, Game GAME, Attack INT} PRIMARY KEY {Character#, Game}, FOREIGN KEY {Character#, Game} REFERENCES TO CharactersExistence, CONSTRAINT IS_EMPTY (CharactersExistance {Character#, Game} WHERE Game = GAME("First Game") XMINUS CharacterSpecial{Character#, Game}); // Special is mandatory in the first game, but is absent in all the later ones. |
|
Also I might need some other constraints to enforce, umm, the "mandatoriness" of several characteristics in certain games and the absence of several others in certain games. But this design is as ugly as hell. |
#9
| |||||||
| |||||||
|
|
On Wed, 10 Nov 2010 15:54:26 -0800 (PST), Kentauros joker... (AT) gmail (DOT) com> wrote: On Nov 11, 12:39 am, Hugo Kornelis h... (AT) perFact (DOT) REMOVETHIS.info.INVALID> wrote: The problem is, many characteristics never change at all. But why is that a problem? "Wario has defense 17 in Super Mario World" "Wario has defense 17 in Super Mario World 2" "Wario has defense 17 in Super Mario World 3D" "Wario has defense 17 in Super Mario World - the last part" "Wario has defense 17 in Super Mario World - the sequel to the last part" There is nothing wrong with this extension. The candidate key for this relvar is (Character, Game), and there are no violations of this key, or of any other constraint. The redundancy. That is what wrong. |
|
(snip) TABLE CharactersExistence{Character# CHAR_ID, *CharacterName CHAR, Game GAME} *PRIMARY KEY {Character#, Game}, *FOREIGN KEY {Game} REFERENCES TO Games; I'm wondering why you have introduced a character number, and why the CharacterName is not a candidate key. Since this is all about tracking different characteristics of the same character in different games, I would have expected the character name to be the most obvious identifier for characters - or are there indeed any games with a "Sonic" character that is not derived from the original hedgehog? Because these CharacterNumbers exist in the games, they're visible to |
|
But it seems that the table Characters has to go characters have different sets of characteristics in different games, and I can't predict what will (dis)appear or which remained characteristic change -- except for name. But why would that impact the table Characters? If a character exists in a game, you can represent that fact in this table, regardless of his/her characteristics. It's the work for CharacterExistence. The table Characters were |
|
If your UoD ensures that each character in each game has at least one characteristic (and only then), you could consider regardig this table as redundant and dropping it - though I'd probably still keep it, along with appropriate foreign keys. (You would not drop the table Orders because each order has at least one OrderItem either, would you?) In a given game, characters have list of characteristics. Some of |
|
TABLE CharacterSpecial {Character# CHAR_ID, *Game GAME, *Attack INT} * PRIMARY KEY {Character#, Game}, * FOREIGN KEY {Character#, Game} REFERENCES TO CharactersExistence, * CONSTRAINT IS_EMPTY (CharactersExistance {Character#, Game} WHERE Game = GAME("First Game") XMINUS CharacterSpecial{Character#, Game}); // Special is mandatory in the first game, but is absent in all the later ones. This is not a good constraint. What will you do if a new game is relased next month (just in time for Christmas), where special is mandatory again? Change the constraints? Yes. Just change the constraints. So the constraints will mean |
|
If special is mandatory on one game and optional in another, than you can do one of two things: 1) Leave it optional - after all, there clearly is no generic rule that each character must have special in each game. 2) Add the unary preciate "In <Game>, special is mandatory" to your model and use that instead of the name of the first game in the constraint. I repeat again, "special" is a mandatory attribute in the first game, |
|
I'm also wondering about your choice to use seperate tables for each characteristic (attack, defense, special, ...). Not that this is really WRONG, but it might not be the best choice either. Have you considered the predicate "<Character> has <Characteristic> <score> in Game>" to replace all these? Yes. And I don't think it will work. What will the domain of <score |
#10
| |||
| |||
|
|
On Nov 11, 10:32*pm, Hugo Kornelis h... (AT) perFact (DOT) REMOVETHIS.info.INVALID> wrote: On Wed, 10 Nov 2010 15:54:26 -0800 (PST), Kentauros joker... (AT) gmail (DOT) com> wrote: On Nov 11, 12:39 am, Hugo Kornelis h... (AT) perFact (DOT) REMOVETHIS.info.INVALID> wrote: The problem is, many characteristics never change at all. But why is that a problem? "Wario has defense 17 in Super Mario World" "Wario has defense 17 in Super Mario World 2" "Wario has defense 17 in Super Mario World 3D" "Wario has defense 17 in Super Mario World - the last part" "Wario has defense 17 in Super Mario World - the sequel to the last part" There is nothing wrong with this extension. The candidate key for this relvar is (Character, Game), and there are no violations of this key, or of any other constraint. The redundancy. That is what wrong. |
![]() |
| Thread Tools | |
| Display Modes | |
| |