Edgewall Software

Changes between Version 30 and Version 31 of GenericTrac


Ignore:
Timestamp:
Aug 3, 2010, 6:03:50 PM (14 years ago)
Author:
Christian Boos
Comment:

Talk about #Relations

Legend:

Unmodified
Added
Removed
Modified
  • GenericTrac

    v30 v31  
    6060Note that we might soon get ''relations'' (or ''links'') as well, see #31.
    6161
     62==== Properties
    6263Let's examine the advantages and disadvantages of each different kind of storage, for the properties:
    6364 1. properties stored in columns of a main table:
     
    101102Note by the way that newer "resources", like `repository` in MultiRepos already have this `(id,prop,value)` form, we'd only have to add `seq`.
    102103
    103 
     104==== Schema
    104105We could also keep the metadata associated to the properties in the database,
    105106instead of being hard-coded and present in the TracIni file, permitting an
     
    112113Furthermore, properties not defined in the schema could simply be ignored, so this would allow a great deal of flexibility for plugins when they need to store "special" properties or revision properties.
    113114
    114 
     115==== The Generic Scheme
    115116Actually, for achieving requirement 3. & 4., we need specialized tables,
    116117one for each different value column type we want to support:
     
    124125
    125126This set of tables is a "generic scheme" that can be easily created for any kind of "resource". There's also a trade-off here, between using one very generic set of "resource_..." table versus special instances like "ticket_...": having one set of tables presents the risk of introducing too much contention for backends using table locking, and leads to writing queries that will contain lots of difficult to joins. We will already have enough issues with this when writing multicriteria search queries...
     127
     128==== Identifier
    126129
    127130Along the same lines there's also the question of what should be the ''id'':
     
    142145This all suggests that using surrogate keys would be preferable.
    143146
    144 If this is the case, the '''resource_prop''' table could as well become simply:
    145 ||= id ||= prop ||= value ||= //seq// ||
    146 
    147  - the ''realm'' information could simply be stored as another prop/value entry (`'realm'`,`<the resource realm>`)
    148  - this could be extended naturally to the ''support of multiple projects'', with another (`'project'`,`<projectid>`) prop/value pair; this is better as adding an additional `project` column to all entries
    149 
    150 Note that having a separate table for storing the ''relations only'' wouldn't necessary be better, as we would likely have to store something like:
    151 ||= role ||= source ||= target ||= seq ||
    152 
    153 which is just a reformulation of:
    154 ||= prop ||= id ||= value ||= seq ||
    155 
    156 i.e. the proposed '''resource_prop'''.
     147==== Relations
     148
     149Storing the relations between resources is also an interesting topic.
     150We face several alternatives. Let's take the example of //ticket// and //project//. This is a simple example because we only have a "has_a / part_of" relation between ticket and project.
     151 1. in the `ticket_prop_int` table, via the `('project', <project_id>)` prop/value pair(s) (support of multiple projects per ticket is possible as any other multivalued field via multiple `seq`)
     152 2. in a dedicated `ticket_project` relation table `(<project_id>,  <ticket_id>)`
     153 3. in a global `project_relation` table `(<project_id>,  <resource_id>)`
     154 4. as part of the `project_prop_int` table, via `('ticket', <ticket_id>)` prop/value pair(s). This is symmetrical to 1., this time the relations are store on the project side.
     155
     156We also have the more demanding example of generic //ticket// vs. //ticket// relations, as discussed in #31.
     157There we don't want to have to add a new table for each new type of relation, hence a solution of the type 1. / 4. would be more appropriate (3. + a "role" type would essentially be the same as 1. / 4.).
     158
     159In order to decide between 1. or 4., we need to consider the nature of the relation, whether it's an essential or accidental property.
     160
     161A ticket doesn't really stand on its own, normally it's part of one project. Remember, in the context of MultiProject, even when there's no project defined, there's the implicit "whole" project. A ticket is eventually part of multiple projects but that's less common, if allowed at all. Even in that case, we can still consider that the //project// properties are essential properties of the ticket.
     162On the opposite, a project can well exist without any tickets attached to it, so it's pretty clear that the tickets are not essential properties of a project. It's also clear that when we load a project instance, we don't necessarily want to load thousands of ticket properties.
     163
     164For other relations, it can be less clear cut, we have to take sides. For example, concerning the ticket relations:
     165 - ''**parent**/child'': a child ticket necessarily has a ''parent'' ticket, otherwise it's not a child ticket ; the parent ticket may have one or more children tickets, but it can also exist on its own
     166 - ''**blocked-by**/is-blocking'': a ticket can be ''blocked-by'' one or more tickets ; the converse relation ''is-blocking'' is less strong
     167 - ''**duplicate-of**/duplicated-by'': a ticket may be qualified to be a ''duplicate-of'' of another ticket ; that other ticket is ''duplicated-by'' one or many tickets, but this is less strong
    157168
    158169