| Register | FAQ | Calendar | Search | Today's Posts | Mark Forums Read |
|
#1
| |||
| |||
| I have put a draft critique of Robert C. Martin's "Agile Principles, Patterns, and Practices" on my blog: http://www.geocities.com/tablizer/martin1.htm Comments welcome. At least nice ones are :-) -T- |
|
#2
| |||
| |||
| topmind wrote: > I have put a draft critique of Robert C. Martin's "Agile Principles, > Patterns, and Practices" on my blog: > I haven't read the entire book (or your entire critique) but I agree database design is not an implementation detail, nor is it irrelevant. I suspect Mr. Martin and I are at opposite ends of this debate. For the past two weeks I've been promoting the belief the database is the biggest and perhaps most important 'object' in the system and your blog's excerpts from his book suggest he believes the opposite. I suspect he and Martin Fowler (it is reported) both share the opinion that if memory was both infinite and infallible that databases would be unnecessary. Well, perhaps they would be if you never needed to share, duplicate, or transport them. -- Visit <http://blogs.instreamfinancial.com/anything.php> to read my rants on technology and the finance industry. |
|
#3
| |||
| |||
| Thomas Gagne wrote: > topmind wrote: > > I have put a draft critique of Robert C. Martin's "Agile Principles, > > Patterns, and Practices" on my blog: > > > I haven't read the entire book (or your entire critique) but I agree > database design is not an implementation detail, nor is it irrelevant. > I suspect Mr. Martin and I are at opposite ends of this debate. For the > past two weeks I've been promoting the belief the database is the > biggest and perhaps most important 'object' in the system and your > blog's excerpts from his book suggest he believes the opposite. > > I suspect he and Martin Fowler (it is reported) both share the opinion > that if memory was both infinite and infallible that databases would be > unnecessary. Well, perhaps they would be if you never needed to share, > duplicate, or transport them. This is perhaps related: http://c2.com/cgi/wiki?ProgrammingWi...mDiskDichotomy Unlimited non-volitile RAM for their style of OO would still basically be a navigational database not much different than the contraptions that motivated Dr. Codd to "clean up the town". Adding "function pointers" (methods) into the mix or putting behavorial wrappers around them does not change their fundimental problems. No matter what new names or packaging they put around navigational DB's, they still have the same issues. Navigational structures are like the Vietnam War: every generation has to reinvent and relive it and suffer all over again. Only the place names and faces change. > > -- -T- |
|
#4
| |||
| |||
| > Unlimited non-volitile RAM for their style of OO would still basically > be a navigational database not much different than the contraptions > that motivated Dr. Codd to "clean up the town". Adding "function > pointers" (methods) into the mix or putting behavorial wrappers around > them does not change their fundimental problems. > > No matter what new names or packaging they put around navigational > DB's, they still have the same issues. Navigational structures are like > the Vietnam War: every generation has to reinvent and relive it and > suffer all over again. Only the place names and faces change. Suppose Adam(age 30) has children named John(tall), Mary(short), Bob(fat), Sue(short/thin), Adam(age 5). Body builds tall/short and fat/thin are opposites. And we want to find the following, without explicitly referring to John's parent (Adam) or John's build (tall) directly: 1) John's siblings. 2) John's fat siblings. 3) John's siblings of opposite build. 4) Persons with builds with whom Bob's build has same relationship as John's build's relationship with Mary's build (without explicitly referring to that relationship in the query). Below is a solution based on a network/OO-ish metholdolgy. Could you show how Codd's solution would be cleaner / less navigational especially as new data requirements are added later? (new 'tall 'build) (new 'athletic 'build) (new 'petite 'build) (new 'short 'build) (new 'thin 'build) (new 'fat 'build) (new 'opposite) (set tall opposite short) (set short opposite tall) (set fat opposite thin) (set thin opposite fat) (new 'john 'person) (set john build tall) (new 'mary 'person) (set mary build short) (new 'bob 'person) (set bob build fat) (new 'sue 'person) (set sue build short) (set sue build thin) (new 'age) (new 'adam 'person) (set+ adam age '10) (new 'adam 'person) (set+ (it) age '30) (set (it) child john) (set (it) child mary) (set (it) child bob) (set (it) child sue) (set (it) child (and (get * name 'adam) (get * age 10))) (; Get john's siblings by getting persons who are children of john's parent and are not himself) (; Gets mary, bob, sue, little adam) (!= (and (get person instance *) (get (get * child john) child *)) john) (; Get john's fat siblings by getting persons whose build is fat and are children of john's parent and are not himself) (; Gets bob) (!= (and (get person instance *) (get * build fat) (get (get * child john) child *)) john) (; Get john's siblings of opposite build by getting persons whose build is opposite of john's build and are children of john's parent and are not himself) (; Gets mary and sue) (!= (and (get person instance *) (get * build (get (get john build *) opposite *)) (get (get * child john) child *)) john) (; Get persons with builds with whom bob's build relationship is the same asjohn's build relationship to mary's build) (; Gets sue) (get * build (get (get bob build *) (get (get john build *) * (get mary build *)) *)) |
|
#5
| |||
| |||
| Neo wrote: > > Unlimited non-volitile RAM for their style of OO would still basically > > be a navigational database not much different than the contraptions > > that motivated Dr. Codd to "clean up the town". Adding "function > > pointers" (methods) into the mix or putting behavorial wrappers around > > them does not change their fundimental problems. > > > > No matter what new names or packaging they put around navigational > > DB's, they still have the same issues. Navigational structures are like > > the Vietnam War: every generation has to reinvent and relive it and > > suffer all over again. Only the place names and faces change. > > Suppose Adam(age 30) has children named John(tall), Mary(short), > Bob(fat), Sue(short/thin), Adam(age 5). Body builds tall/short and > fat/thin are opposites. And we want to find the following, without > explicitly referring to John's parent (Adam) or John's build (tall) > directly: We've been over these kinds of things already. I'll let somebody else try this time. I remember at least 2 cases where the relational equivalent was about the same as your nav version (although we had to use vendor-specific SQL in one case, but SQL is not on trial, relational is). I don't necessarily claim that all navigational queries will be longer than relational equivalents. The hard part about navigational is *lack of consistency* in the structures. Two different people who never met each other would generally come up with similar relational schemas. There are variations, but generally the possible normalized variations will be small, rarely more than 2 or 3 solutions at the most (in a grand sense). But, there are *no consistent rules* for navigational structures. This makes it take longer to get your head around the structures *and* work up the queries. Tables provide structure, but navigational has no guarenteed structure: they are just graphs. Some graphs may have some amount of treeness to them, but this is not guarenteed in any way. And, treeness may not make them flexible or clean anyhow even if in there. Also, it may create integrity problems. What prevents one from producing a recursive navigational query, for example? Even a good many OO fans seem to agree that relational is better at ad-hoc queries (even if not better for app-specific modeling). Unless it is a majority OO opinion, perhaps the "database theory" topic would be more appropriate for a claim that navigational is better for ad-hoc queries. Other than a handful of XML database pushers, I don't see that as a popular opinion. The lack of consistency probably makes it possible to tweak a structure to better fit a given nav query anyhow. This wiggle room gives you an edge. An analogy: The most compact procedural program for a set of requirments will probably use GOTO's instead of nested blocks. However, I would hate to have to maintain it as a human. > > 1) John's siblings. > 2) John's fat siblings. > 3) John's siblings of opposite build. > 4) Persons with builds with whom Bob's build has same relationship as > John's build's relationship with Mary's build (without explicitly > referring to that relationship in the query). > > Below is a solution based on a network/OO-ish metholdolgy. Could you > show how Codd's solution would be cleaner / less navigational > especially as new data requirements are added later? > > (new 'tall 'build) > (new 'athletic 'build) > (new 'petite 'build) > (new 'short 'build) > (new 'thin 'build) > (new 'fat 'build) > > (new 'opposite) > (set tall opposite short) > (set short opposite tall) > > (set fat opposite thin) > (set thin opposite fat) > > (new 'john 'person) > (set john build tall) > > (new 'mary 'person) > (set mary build short) > > (new 'bob 'person) > (set bob build fat) > > (new 'sue 'person) > (set sue build short) > (set sue build thin) > > (new 'age) > (new 'adam 'person) > (set+ adam age '10) > > (new 'adam 'person) > (set+ (it) age '30) > (set (it) child john) > (set (it) child mary) > (set (it) child bob) > (set (it) child sue) > (set (it) child (and (get * name 'adam) > (get * age 10))) > > (; Get john's siblings > by getting persons > who are children of john's parent > and are not himself) > (; Gets mary, bob, sue, little adam) > (!= (and (get person instance *) > (get (get * child john) child *)) > john) > > (; Get john's fat siblings > by getting persons > whose build is fat > and are children of john's parent > and are not himself) > (; Gets bob) > (!= (and (get person instance *) > (get * build fat) > (get (get * child john) child *)) > john) > > (; Get john's siblings of opposite build > by getting persons > whose build is opposite of john's build > and are children of john's parent > and are not himself) > (; Gets mary and sue) > (!= (and (get person instance *) > (get * build (get (get john build *) opposite *)) > (get (get * child john) child *)) > john) > > (; Get persons with builds with whom bob's build relationship is the > same asjohn's build relationship to mary's build) > (; Gets sue) > (get * build (get (get bob build *) > (get (get john build *) * (get mary build *)) > *)) |
|
#6
| |||
| |||
| > > > ... OO would still basically > > > be a navigational database not much different than the contraptions > > > that motivated Dr. Codd to "clean up the town". > > Below is a solution based on a network/OO-ish metholdolgy. Could you > > show how Codd's solution would be cleaner / less navigational > > especially as new data requirements are added later? > We've been over these kinds of things already. I'll let somebody else > try this time. I remember at least 2 cases where the relational > equivalent was about the same as your nav version (although we had to > use vendor-specific SQL in one case, but SQL is not on trial, > relational is). The underlying data structure in the prior examples could be managed systematically in RM. The "Sibling of Opposite Build" cannot. |
|
#7
| |||
| |||
| Neo wrote: > > > > ... OO would still basically > > > > be a navigational database not much different than the contraptions > > > > that motivated Dr. Codd to "clean up the town". > > > > Below is a solution based on a network/OO-ish metholdolgy. Could you > > > show how Codd's solution would be cleaner / less navigational > > > especially as new data requirements are added later? > > > We've been over these kinds of things already. I'll let somebody else > > try this time. I remember at least 2 cases where the relational > > equivalent was about the same as your nav version (although we had to > > use vendor-specific SQL in one case, but SQL is not on trial, > > relational is). > > The underlying data structure in the prior examples could be managed > systematically in RM. The "Sibling of Opposite Build" cannot. IIRC, I showed how to represent opposites in schemas about 2 weeks ago. The relational model can represent any graph. Perhaps you are arguing that it is "uglier" in RM? Again, you failed to prove your point on 2 prior query-size challenges. Why should I take you up on a 3rd one? Navigational queries are kind of off-topic anyhow. Plus, you seem to keep focusing on the size issue instead of the consistency issue. Try again in six months, maybe I'll feel like joining another query-size battle then :-) -T- |
|
#8
| |||
| |||
| > > The underlying data structure in the prior examples could be managed > > systematically in RM. The "Sibling of Opposite Build" cannot. > > IIRC, I showed how to represent opposites in schemas about 2 weeks ago. Neither of the two relational schemas offered were systematic or resilient solutions; no data was entered and no queries were shown. Quote "I will leave the query work to somebody else". > The relational model can represent any graph. True. The data structure underlying the "Sibling of Opposite Build" example isn't a graph. Its a network. The difference should become clearer when one try to formulate the last query. |
|
#9
| |||
| |||
| Neo wrote: > > > The underlying data structure in the prior examples could be managed > > > systematically in RM. The "Sibling of Opposite Build" cannot. > > > > IIRC, I showed how to represent opposites in schemas about 2 weeks ago. > > Neither of the two relational schemas offered were systematic or > resilient solutions; no data was entered and no queries were shown. > Quote "I will leave the query work to somebody else". I am not referring to that one. One is the one that would have been shortened via "natural joins" if the vendor's SQL supported it. (You supplied the original SQL, I would note.) In other words, SQL tends to have bloated JOIN's, but that is technically solvable. I don't remember you challenging that when I brought it up. I would note that you got to make up your own query language so are not bound by existing implementations. That is fine by me as long as *both sides* are allowed such. (I have proposed a new relational language called SMEQL, by the way. It would be easier for a DBA or programmer to extend than SQL because it has simpler "atoms".) And the 2nd example one was the "kitchen and fridge" one from roughly a year ago IIRC. I don't remember the details, but the relational query was reworked and comparable in size to your navigational query. > > > The relational model can represent any graph. > > True. The data structure underlying the "Sibling of Opposite Build" > example isn't a graph. Its a network. The difference should become > clearer when one try to formulate the last query. Well, maybe, but not today. 2 is enough for now. From my perspective, your quota for calling Wolf is spent for a while. -T- |
|
#10
| |||
| |||
| > > Neither of the two relational schemas offered were systematic or > > resilient solutions; no data was entered and no queries were shown. > > Quote "I will leave the query work to somebody else". > > I am not referring to that one. One is the one that would have been > shortened via "natural joins" if the vendor's SQL supported it. (You > supplied the original SQL, I would note.) In other words, SQL tends to > have bloated JOIN's, but that is technically solvable. I don't remember > you challenging that when I brought it up There was no reason to challenge there because RM can systematically manage the "Find Siblings" example. The "original SQL" was provided by a cdt member in response to that example. Below are the approx equivalent queries based on approx equivalent underlying data structures. (!= (and (get person instance *) (get (get * child john) child *)) john) SELECT P2.* FROM ((person INNER JOIN link ON person.ID = link.childID) INNER JOIN link AS link2 ON link.parentID = link2.parentID) INNER JOIN person AS P2 ON link2.childID = P2.ID WHERE (((P2.name)<>"John") AND ((person.name)="John") The above comparision was provided in response to your comment "Navigational query languages were proposed. They were ugly because navigational is ugly." > And the 2nd example one was the "kitchen and fridge" one from roughly a > year ago IIRC. I don't remember the details, but the relational query > was reworked and comparable in size to your navigational query. Below is a link to that thread starting near message 291. http://groups.google.com/group/comp....e7ae20bcfb4288 While that example can also be handled systematically in RM and the two queries appear similar, the queries are based on substantially different underlying structures. In the network/OO-ish implementation, not only can items in the house form an infinite depth hierarchy (ie house\floor\kitchen\fridge\2ndShelf\eggCarton\egg\ yolk etc), each item can contain things of various types and each item can 0 to many classifications, attributes and values; where as the RM solution is based on a simpler and fixed hierarchy (ie T_House, T_Room and T_Funiture) where each level can only contain things of one type. By specifying additional data, I can show that the original OO/Network-ish solution/query is more general and resilient compared to the RM solution/query. (& (get single-family instance *) (get * has (& (get bedroom instance *) (get * has (& (get carpet instance *) (get * color purple))))) (get * has (& (get kitchen instance *) (get * has (& (get fridge instance *) (get * mfg sears)))))) SELECT * FROM houses WHERE houseType="single family" AND houseID in (SELECT houseID FROM rooms WHERE carpetColor="purple") AND houseID in (SELECT houseID FROM furniture WHERE furnitureType="fridge" AND brand="Sears") Would you be willing expand on this example? Lets start with something simple. For example, if we add a room with carpet of multiple colors, the original OO/Network-ish query is unaffected. How can one handle this situation in the RM solution? |
![]() |
| Thread Tools | |
| Display Modes | |
In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.