From: Brian Selzer on

"Dmitry A. Kazakov" <mailbox(a)dmitry-kazakov.de> wrote in message
news:1kikgag7cq3zi$.ufxkz5oaeff.dlg(a)40tude.net...
> On Sat, 29 Mar 2008 15:37:13 GMT, Brian Selzer wrote:
>
>> "Dmitry A. Kazakov" <mailbox(a)dmitry-kazakov.de> wrote in message
>> news:e5lufueeu155.t1s8vlmxjhpt.dlg(a)40tude.net...
>>> On Sat, 29 Mar 2008 04:47:01 GMT, Brian Selzer wrote:
>>>
>>>> There is a table for attributes that are common to all
>>>> possible widgets, and a table for each set of attributes that are
>>>> common
>>>> not to all possible widgets, but rather to a subset of all possible
>>>> widgets.
>>>
>>> It is interesting to see people reinventing the wheel (class). The set
>>> of
>>> "all possible widgets having attributes T, U, V" is a class.
>>
>> That depends upon how you define what is a class. The set of all
>> possible
>> widgets having attributes T, U, V, such that T and U have the same sign
>> is a
>> different class. The set of all possible widgets having attributes T, U,
>> V
>> such that T and V have the same sign is also a different class. Under
>> this
>> definition, a widget may be a member of all three classes, right?
>
> Is the sign of attributes itself an attribute, or it is a constraint put
> on
> them? But basically, yes classes can intersect.
>
> ... and the point is, the problems and choices you have been discussing is
> the good old OOA/D with relational representations as a vehicle.
>
>>> But that is not my point. The problem with widgets hierarchy is that
>>> there
>>> are three axes of widget relations. You were discussing only one of them
>>> attributes, which is usually directly mapped to types. This is not that
>>> big deal. More difficult are other two:
>>>
>>> 2. Visual containment. Widgets can consist of / contain other widgets.
>>
>> If a widget consists of other widgets, then it must have attributes that
>> are
>> also widgets. If a widget contains other widgets, then it either has one
>> attribute for each contained widget or an attribute that is a set of
>> widgets. Visual containment can be defined in terms of attributes, so I
>> don't understand why it is a problem.
>
> (I am surprised that you did not mentioned a natively relational solution.
> I thought you would propose parent-child relation.) Anyway, an
> attribute-based model is very weak. It is like to have only record types
> but no arrays. There are lots of widgets which contain an unknown in
> advance number of other widgets. Another problem why your and the
> relational model I mentioned before would be problematic is handling all
> sorts of ordering, layout, alignment, size constraints put on contained
> widgets. In the traditional OO GUI design these constraints are a part of
> the container widget behavior. For example, GTK+ table widget arranges its
> children in columns, calculates its own size from the sizes of children
> (that goes recursively) etc. It would be extremely tedious to expose this
> stuff in terms of attributes for the poor user...
>

It's a simple matter to flatten out nested relations. Also, modeling a
1:0..n relationship is child's play. Ordering, layout, alignment, size can
all be represented by exposing attributes and defining functions and
relations. If the size of a widget depends upon the size of its children
then it must be the result of an aggregate function. It's generally bad
practice to record the results of an aggregate, since the value can be
arrived at by simply computing the aggregate. Any change that might affect
the aggregate result would then necessarily require a recomputation of the
stored aggregate value.

>>> 3. Signal handing. Handlers of widget events are composed in a certain
>>> hierarchical way.
>>
>> You don't store widgets, you store snapshots of widgets. How one widget
>> communicates with another has no bearing on how the snapshots of each are
>> stored. So where is the problem?
>
> I don't see your point. When you hit a mouse button, that should have some
> effect on the snapshots. Even if we ignored an application processing the
> event, there is a delivery to it and animation. For example, a button
> widget under the cursor gets down and up, while the sequence
> left_mouse_press, mouse_release is translated into button_click.

When you hit a mouse button, the state /may/ change. When the state
changes, another snapshot can be taken to replace one that had already been
recorded. Not every mouse click results in a change of state. For example,
someone hits the "Clear" button on a screeen that has already been cleared,
or someone double-clicks the "Clear" button, and the double-click is
interpreted as two single-clicks. When there is no change of state, there
is no need to record a change of state. Bottom line: the fact that a
left-mouse-press, left-mouse-release translates into a button_click is
irrelevant. What has delivery and animation to do with tracking widget
state?

>
> --
> Regards,
> Dmitry A. Kazakov
> http://www.dmitry-kazakov.de


From: Dmitry A. Kazakov on
On Sat, 29 Mar 2008 18:54:11 GMT, Brian Selzer wrote:

> "Dmitry A. Kazakov" <mailbox(a)dmitry-kazakov.de> wrote in message
> news:1kikgag7cq3zi$.ufxkz5oaeff.dlg(a)40tude.net...
>> On Sat, 29 Mar 2008 15:37:13 GMT, Brian Selzer wrote:
>>
>>> "Dmitry A. Kazakov" <mailbox(a)dmitry-kazakov.de> wrote in message
>>> news:e5lufueeu155.t1s8vlmxjhpt.dlg(a)40tude.net...
>>>> On Sat, 29 Mar 2008 04:47:01 GMT, Brian Selzer wrote:
>>>>
>>>>> There is a table for attributes that are common to all
>>>>> possible widgets, and a table for each set of attributes that are common
>>>>> not to all possible widgets, but rather to a subset of all possible widgets.
>>>>
>>>> It is interesting to see people reinventing the wheel (class). The set of
>>>> "all possible widgets having attributes T, U, V" is a class.
>>>
>>> That depends upon how you define what is a class. The set of all possible
>>> widgets having attributes T, U, V, such that T and U have the same sign is a
>>> different class. The set of all possible widgets having attributes T, U, V
>>> such that T and V have the same sign is also a different class. Under this
>>> definition, a widget may be a member of all three classes, right?
>>
>> Is the sign of attributes itself an attribute, or it is a constraint put on
>> them? But basically, yes classes can intersect.
>>
>> ... and the point is, the problems and choices you have been discussing is
>> the good old OOA/D with relational representations as a vehicle.
>>
>>>> But that is not my point. The problem with widgets hierarchy is that
>>>> there
>>>> are three axes of widget relations. You were discussing only one of them
>>>> attributes, which is usually directly mapped to types. This is not that
>>>> big deal. More difficult are other two:
>>>>
>>>> 2. Visual containment. Widgets can consist of / contain other widgets.
>>>
>>> If a widget consists of other widgets, then it must have attributes that are
>>> also widgets. If a widget contains other widgets, then it either has one
>>> attribute for each contained widget or an attribute that is a set of
>>> widgets. Visual containment can be defined in terms of attributes, so I
>>> don't understand why it is a problem.
>>
>> (I am surprised that you did not mentioned a natively relational solution.
>> I thought you would propose parent-child relation.) Anyway, an
>> attribute-based model is very weak. It is like to have only record types
>> but no arrays. There are lots of widgets which contain an unknown in
>> advance number of other widgets. Another problem why your and the
>> relational model I mentioned before would be problematic is handling all
>> sorts of ordering, layout, alignment, size constraints put on contained
>> widgets. In the traditional OO GUI design these constraints are a part of
>> the container widget behavior. For example, GTK+ table widget arranges its
>> children in columns, calculates its own size from the sizes of children
>> (that goes recursively) etc. It would be extremely tedious to expose this
>> stuff in terms of attributes for the poor user...
>
> It's a simple matter to flatten out nested relations. Also, modeling a
> 1:0..n relationship is child's play. Ordering, layout, alignment, size can
> all be represented by exposing attributes and defining functions and
> relations.

Yes, but what will happen with the nice global widget-attribute model? The
problem is that the least common denominator (an OO guy would say, the root
class) is practically null. This is independent on whether widgets are
represented as relations of attributes or as types with properties.

> If the size of a widget depends upon the size of its children
> then it must be the result of an aggregate function. It's generally bad
> practice to record the results of an aggregate, since the value can be
> arrived at by simply computing the aggregate. Any change that might affect
> the aggregate result would then necessarily require a recomputation of the
> stored aggregate value.

In practice it is more complex, the container interacts with its children.
There are quite horrific protocols of children being asked for what they
want, what they could, what the user has requested (resizing), what the
preferred geometry is (window manager). To bring this to one formula would
be a challenge. And the problem is how would you reuse this mess? In OO it
is a behavior encapsulated into the widget. In RDBMS you would have some
deeply layered views of pseudo attributes. To me it is just same OO
translated into some "relational code." And the mapping set value <->
behavior is as old as the world (every piece of hardware works this way).

>>>> 3. Signal handing. Handlers of widget events are composed in a certain
>>>> hierarchical way.
>>>
>>> You don't store widgets, you store snapshots of widgets. How one widget
>>> communicates with another has no bearing on how the snapshots of each are
>>> stored. So where is the problem?
>>
>> I don't see your point. When you hit a mouse button, that should have some
>> effect on the snapshots. Even if we ignored an application processing the
>> event, there is a delivery to it and animation. For example, a button
>> widget under the cursor gets down and up, while the sequence
>> left_mouse_press, mouse_release is translated into button_click.
>
> When you hit a mouse button, the state /may/ change. When the state
> changes, another snapshot can be taken to replace one that had already been
> recorded. Not every mouse click results in a change of state. For example,
> someone hits the "Clear" button on a screeen that has already been cleared,
> or someone double-clicks the "Clear" button, and the double-click is
> interpreted as two single-clicks. When there is no change of state, there
> is no need to record a change of state.

Normally it is the button's behavior to catch low-level events and to
translate them into higher-level ones. Some events go no further. This is
what I meant under composition of event handlers. An event is issued and
then propagated through some dynamically managed network of handlers. It
can be routed, reflected, it can signal new events etc. It is quite messy.
(BTW, I don't like it. But it is the best known solution today.)

In terms of states, there exist transitional states which never become
visible above some level. It seems that you consider only the states
relevant for widget rendering. But this is a way different and even more
complex story. Rendering states are asynchronous to the GUI and application
states. The rendering engine is asynchronous to one of the widgets. Much of
rendering stuff runs in the graphic accelerator or remotely. There is a
sort of transaction model between the widget's engine and the rendering
environment (device contexts etc).

> Bottom line: the fact that a
> left-mouse-press, left-mouse-release translates into a button_click is
> irrelevant. What has delivery and animation to do with tracking widget
> state?

Because "button pressed" is a visible state for an application if it wants
to see it. Technically you cannot publish all state transitions. That would
throttle most powerful hardware you'd take. And most of these states are
just irrelevant to the application. Differently to DB which is largely
passive and driven by applications, GUI has it own life and application
just reacts on the interesting to it state transitions. It also kicks some
new transitions.

This is BTW another important problem of GUI design. When an application
initiates some transitions it wishes A) to be asynchronously to them and B)
it often does not want to be notified about its own actions. So you need
synchronization mechanisms and events filtering based on the issuer.

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
From: topmind on


Brian Selzer wrote:
> "topmind" <topmind(a)technologist.com> wrote in message
> news:a742d466-e6a9-4d13-a1ba-953567fcb3dc(a)u10g2000prn.googlegroups.com...
> [big snip]
>
> > It's a gut feeling for everyone here because it's never been tried in
> > practice. We cannot really know with near certainty all the possible
> > usage scenarios (query patterns) and which are more frequent. It's an
> > educated WAG at best.
> >
>
> Perhaps some testing is in order.
>
> > There's another suggestion that nobody's mentioned here that I know
> > of: Add each new column to the Widgets table as needed, creating a
> > "sparse" table. If we are going to allow add/change to schemas, then
> > why not just add the new frippen column to the Widgets table and be
> > done with it? Sparse tables are not really space hogs on most modern
> > RDBMS like they were in the past. The overhead for unused (null)
> > columns is small.
> >
>
> It's not about space. Separate tables can be indexed separately, permitting
> the selection of better query plans. A lot of nulls, such as you would find
> in a sparse table, skews the statistics for columns, making some indexes
> that would otherwise appear optimal less attractive, leading to poor
> performance.

I doubt queries against sparse columns would be common. Generally
there would first be a query involving the "widget type" and/or
attribute type, which would greatly narrow what is being searched.
And, depending on how the optimizer and index system is built, you
don't need to store Nulls *in* the indexes. Think about it. There are
a few operations where indexing nulls makes sense, but they are not
common enough to bother in my opinion. There are other ways to get the
same info. But, a given vendor may have seen it different. In short,
it depends on the DB engine.

EAV's don't need to store nulls. You just don't include that entry. If
a given index engine is not null-friendly, then perhaps an EAV is
better than a sparse table as far as performance.


>
> The idea of a sparse table is ugly because it involves nulls.
> Nulls--especially those that indicate 'there shouldn't be a value
> here'--should be avoided whenever possible. If you're interested, there
> have been many discussions on cdt regarding nulls. If you can wade through
> the flames, you might even find some useful information.
>
> Data has an inherent structure.

Sometimes its "inherent structure" does NOT fit static tables well.
The real world is not always friendly to a given abstraction. And,
although I am against "nulls" for strings, the concept of some kind of
"empty" cell (zero length) is not necessarily a bad thing. (In some
RDBMS, zero length and null are the same thing, in others they are
not.)

> Stuffing everything into one table, whether
> it be an EAV table or a sparse table imposes an alien structure on the data,
> introducing redundancy and complexity and usually reducing performance. A
> solution that has one table per widget type also imposes a structure on the
> data, one that inevitably introduces redundancy. The 'table-happy' design
> that I suggested earlier does not introduce redundancy and does not require
> nulls.

Your solution does NOT reduce redundancy because the foreign key has
to be repeated over and over again. And, empty cells don't
necessarily reduce performance, per above. And, filling up table-space
is ugly and not debugging-friendly. Fat table-spaces slow me down. I
cannot speak for everybody's psychology and hand-eye-mouse-brain
coordination, but it slows down MINE.

I will respect your choice because the tradeoffs are all sticky either
way. But, I do not agree with it, nor do I agree with your performance
criticisms and redundancy claims. They appear incorrect.

-T-
From: topmind on
On Mar 29, 7:11 am, "Roy Hann" <specia...(a)processed.almost.meat>
wrote:
> "topmind" <topm...(a)technologist.com> wrote in message
>
> news:79cae24d-bca7-47e5-94f6-7bb5bfa508f1(a)s8g2000prg.googlegroups.com...
>
>
>
> > I never liked table-happy designs,
>
> You prefer code-happy designs?!

Prove it would require more code.

>
> I've heard enough. Plonk.
>
> Roy

-T-
From: topmind on


Brian Selzer wrote:
> "topmind" <topmind(a)technologist.com> wrote in message
> news:f743faa4-962b-4048-9d3d-203951b57e17(a)e6g2000prf.googlegroups.com...
> >
> >
> > Brian Selzer wrote:
> >> "topmind" <topmind(a)technologist.com> wrote in message
> >> news:1f649255-eba1-4e82-82b1-99228e761fa5(a)c19g2000prf.googlegroups.com...
> >> >
> >> >
> >> > Brian Selzer wrote:
> >> >> "topmind" <topmind(a)technologist.com> wrote in message
> >> >> news:79cae24d-bca7-47e5-94f6-7bb5bfa508f1(a)s8g2000prg.googlegroups.com...
> >> >> >
> >> >> >
> >> >> > Brian Selzer wrote:
> >> >> >> "topmind" <topmind(a)technologist.com> wrote in message
> >> >> >> news:a8855c5d-1e3f-46ef-a99a-5c09b94bfba5(a)u10g2000prn.googlegroups.com...
> >> >> >> > (addendum)
> >> >> >> >
> >> >> >> > For an example of the need for flexible columns/attributes,
> >> >> >> > consider
> >> >> >> > a
> >> >> >> > relational-based GUI system where widget state and info are
> >> >> >> > tracked
> >> >> >> > in
> >> >> >> > some kind of RDBMS. We want it to be able to add new widgets from
> >> >> >> > different vendors without each widget needing its own table(s)
> >> >> >> > (unless
> >> >> >> > its a really special need).
> >> >> >> >
> >> >> >> > There seems to be a need for either a EAV table (row-based
> >> >> >> > dynamism)
> >> >> >> > or Dynamic Relational (column-based dynamism) of some kind so
> >> >> >> > that
> >> >> >> > attributes that are not known up-front can be tracked.
> >> >> >> >
> >> >> >> > If you suggest otherwise, please present your design.
> >> >> >> >
> >> >> >>
> >> >> >> Well it's really simple. You have a single table with attributes
> >> >> >> that
> >> >> >> are
> >> >> >> common to all possible widgets, and when a set of attributes that
> >> >> >> are
> >> >> >> not
> >> >> >> known up front needs to be tracked, a new table or set of tables is
> >> >> >> created
> >> >> >> to house the set of attributes that references the table with the
> >> >> >> common
> >> >> >> attributes. It's really very simple and doesn't require a special
> >> >> >> dynamism
> >> >> >> (Is that the correct use of that word?) mechanism.
> >> >> >
> >> >> > Having different vendor widgets being able to create their own
> >> >> > little
> >> >> > table is not very practical. There are versioning issues, for one.
> >> >> > What if a widget creates a table that does not work with the current
> >> >> > version or brand of our GUI RDBMS?
> >> >> >
> >> >>
> >> >> Since when do widgets create their own tables?
> >> >
> >> > I thought that was *your* suggestion. May I suggest you describe a
> >> > sample scenario to reduce unstated assumptions between us.
> >> >
> >>
> >> Widgets don't necessarily need to know how to serialize themselves. They
> >> only need to know how to provide a snapshot of themselves for
> >> serialization.
> >> Some other part of the system may be responsible for committing that
> >> snapshot to the database.
> >>
> >> >>
> >> >> > And, I find gazillion tables hard to navigate when looking for
> >> >> > tables
> >> >> > or debugging. I never liked table-happy designs, but individuals may
> >> >> > have personal preferences that differ.
> >> >> >
> >> >>
> >> >> For me, it's a lot easier to wade through a gazillion tables than to
> >> >> try
> >> >> to
> >> >> decipher the content in an EAV table.
> >> >
> >> > That's you, not me. In this case I prefer EAV.
> >> >
> >> >> The 'table-happy' design permits the
> >> >> definition of relationships between attributes.
> >> >> That is a whole lot more
> >> >> difficult when everything is stuffed in an EAV table. For example,
> >> >> suppose
> >> >> that every widget that has attribute Y also has attribute Z. Try
> >> >> enforcing
> >> >> that rule with everything stuffed in an EAV table. With the
> >> >> 'table-happy'
> >> >> design, all you need is to specify that attributes Y and Z are in the
> >> >> same
> >> >> table.
> >> >
> >> > I don't see why that would be a common scenario for GUI's. I cannot
> >> > even think of a single realistic case right now. I am not saying it
> >> > will never happen, but its not common enough to tilt the decision
> >> > unless its close.
> >> >
> >> > Plus, lots of similar tables often results in having to do UNION
> >> > queries, which are ugly and slow. With EAV, one could get/dump the GUI
> >> > attributes in a single query. With your myriad table suggestion, one
> >> > would have to first take an inventory of all custom-widget tables.
> >> >
> >>
> >> I don't see why you would need to do union queries. I think you're stuck
> >> on
> >> the idea that each widget type has its own table. That's not at all what
> >> I
> >> am suggesting. There is a table for attributes that are common to all
> >> possible widgets, and a table for each set of attributes that are common
> >> not
> >> to all possible widgets, but rather to a subset of all possible widgets.
> >> So
> >> for example, suppose that widget A has attributes T, U, V, and W, and
> >> widget
> >> B has attributes T, U, V, X, and Y, and widget C has attributes T, U, V,
> >> Y
> >> and Z, you wouldn't necessarily have a table for each type of widget.
> >> Assuming that T, U, and V are common to all widgets, you would have one
> >> table, the common table, with attributes T, U, and V. Let's also assume
> >> that values for T uniquely identify a widget, meaning that T would be the
> >> primary key of the common table. Then you would have a table with T and
> >> W,
> >> a table with T and X, one with T and Y, and one with T and Z, each
> >> referencing the common table. Widget A would have a row in the common
> >> table
> >> and one in the table with T and W; widget B would have a row in the
> >> common
> >> table, one in the table with T and X and one in the table with T and Y;
> >> widget C would have a row in the common table, one in the table with T
> >> and Y
> >> and one in the table with T and Z. When a new widget, D, that has
> >> attributes T, U, V, X and P needs to be recorded, a new table with T and
> >> P
> >> would need to be created, and then widget D would have a row in the
> >> common
> >> table, one in the table with T and X and one in the new table with T and
> >> P.
> >
> > How is this better than an EAV table? At least with EAV's, you don't
> > have to create new tables for columns that don't already exist.
> >
>
> You're kidding yourself if you think there is any less work with an EAV
> table. So what if you have to create a new table for columns that don't
> already exist. Unless you don't care about integrity, you will have to
> alter the constraints on an EAV table whenever you add an attribute that
> doesn't already exist. The columns in each new table are typed. The values
> in the EAV table cannot be, otherwise you wouldn't be able to store names
> and addresses and numbers and images in the same table. This means that for
> each attribute, you have to define a constraint that specifies the values
> allowable for that attribute. There are other reasons that this is better.
> I listed one earlier: if whenever A, B, then put A and B in the same table.
> Another is that indexes can be applied to individual columns or groups of
> colums. Constraints are simpler, and therefore easier to read, understand
> and maintain, not to mention that being on separate objects, they can
> operate independently, improving both performance and scalability.

A bunch of joins is not exactly fast. I don't believe you.

> If you
> have hundreds of different attributes, then you have hundreds of sets of
> values, and therefore hundreds of additional compares just to determine
> which constraints apply. I could go on, but it should be obvious that you
> don't really gain anything by using an EAV table, you just end up
> reinventing the wheel: instead of using the type checking that is built into
> the system, you have to roll your own.

I am not much of a fan of types. A data dictionary can be used for
validation if needed. Anyhow, this sounds like a perpetual argument
that keeps repeating the same arguments over and over. Each solution
has its own drawbacks and compromises.

And *if* new tables are to be created, I think dedicated tables per
widget, other than the shared ones, is preferable to one table per new
column.

-T-