On Jul 18, 2014, at 6:08 PM, Ken Roberts <alisonk...@gmail.com> wrote:

> I'm having fun trying to visualize this in my head, but I have 4 tables, 3 
> are basic relations, but the 4th table links to table 2.
> 
> Should I take the 4th table and have a relation join with all 3 tables or can 
> I just relate to table 2 and have table 2 relations do the rest?
> 
> Tables 1-3 are basic equipment relationships:
> 
> 1 - manufacturer
> 2 - model (foreignkey manufaturer.id)
> 3 - sources (foreignkey model.id) (sources = inputs available)
> 
>     manufacturers_table = Table(u'manufacturer', metadata,
>         Column(u'id', Integer, primary_key=True),
>         Column(u'name', String(50))
>     )
>     models_table = Table(u'model', metadata,
>         Column(u'id', Integer, primary_key=True),
>         Column(u'manufacturer_id', Integer, ForeignKey(u'manufacturer.id')),
>         Column(u'name', String(50))
>     )
>     sources_table = Table(u'source', metadata,
>         Column(u'id', Integer, primary_key=True),
>         Column(u'model_id', Integer, ForeignKey(u'model.id')),
>         Column(u'label', String(20)),
>     )
> 
> 
> The 4th table keeps track of equipment installed at the premise.
> 
> 4 - projector (foreignkey model.id)
> 
>     projector_table = Table(u'projector', metadata,
>         Column(u'id', Integer, primary_key=True),
>         Column(u'model_id', Integer, ForeignKey(u'model.id')),
>     )
> 
> 
> Tables 1-3 will be updated separately, the projector table will only join 
> with the other tables for reading.
> 
> The question(s) would be on the joins:
> 
> 1 ) Use projector table with join to model table (and model table will take 
> care of the joins with manufacturer and sources)
> 2) Add table 1 and 3 to projector:
> 
>     projector_table = Table(u'projector', metadata,
>         Column(u'id', Integer, primary_key=True),
>         Column(u'manufacturer_id', Integer, ForeignKey(u'manufacture.id')),
>         Column(u'model_id', Integer, ForeignKey(u'model.id')),
>         Column(u'sources_id', Integer, ForeighKey(u'sources.id'))
>     )
> 
> 
> Hope I'm making myself understood - databases with multiple relations are not 
> my strong suit.

you want option #1 here, at least for manufacturer_id.   In #2, by introducing 
synonymous foreign keys on projector_table you introduce the fact that these 
two identifiers must be kept synchronized, and the fact that your database can 
be in an invalid state if this process isn't followed.   This is a basic tenet 
of normalization.    When you introduce manufacturer_id to the projector table, 
this is a value which is specific to "model_id", and not "projector.id".  
Storing columns that are keyed to another column that isn't part of the primary 
key violates third normal form: http://en.wikipedia.org/wiki/Third_normal_form.

For sources_id, it's a little different because there can be many valid 
sources_id values for a single model_id value.   In that way, projector_table 
acts a bit like an association table to key a specific model_id and source_id 
together, *but*, if that were how this were arranged, you probably wouldn't 
have "model_id" on "sources".   Because again, projector can store a 
model_id/sources_id combination that is not valid given a particular 
source.model_id value.   It suggests that "projector"'s primary key is in fact 
specific to sources_id and not model_id, which would again be a 3rd normal form 
violation.

Basically 2nd and 3rd normal form guarantee that your DB can never have two 
pk/fk associations in a conflicting state (and it also compels you to really 
think what entities really correspond to which).   It is not necessarily 
*wrong* to have dupe FKs in a model, but when a non-normalized relationship 
pattern is introduced it is typically for performance reasons, and the part of 
the model that is "denormalized" should be noted; the application, or even 
better DB level triggers, should ensure that the "denormalized" sets of columns 
are always kept in sync with their "normalized" partners.

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to