Thread: Data (Table) Structure Question

Data (Table) Structure Question

From
Date:
i hope everyone's thanksgiving was grand.

i have contacts, customers and employees that i want
to manage in a db application.

i can think of two ways to do this.

first, have a table for each and fill each with all
the relevant data:

1. t_custoemrs
2. t_employees
3. t_contacts

second, have a contacts table that records data that
is repeated throughout each table (ie, name, address,
phone, etc...)

i could then have a t_employees table with a foreign
key to the t_contacts table id.  this table would only
have employee related information and would link back
to contacts.

t_customers would do the same - list only customer
specific information.

i think the latter way is the way to go, but i'm not
sure.  i don't particularly like t_contacts as the
name of the general table.  maybe i need to name it
persons.

anyway, i'd value the input of some more experienced
developers.

tia,

oe1



____________________________________________________________________________________
Do you Yahoo!?
Everyone is raving about the all-new Yahoo! Mail beta.
http://new.mail.yahoo.com

Re: Data (Table) Structure Question

From
"Brandon Aiken"
Date:
I believe the preferred way to do this is to use sub-types.  Create a
t_person table.  Make a type field if you wish with 'E' for an employee
or 'C' for a customer, or you can use implicit typing from joins
('t_person inner join t_employee' will always get only employees, etc.).
You might even wish to create views from these tables to make
presentation easier.

The other option is to treat employees and customers as different and
unrelated entities entirely.  Then you'd make a t_employee table and a
t_customer table, and there would be no t_contacts or t_person table.

In this latter case if you happen to have some employees who are also
customers, then you'd make a table, say t_customer_employee, which has
two fields: one the primary key of t_employee and the other the primary
key of t_customer.  Then you make each one a foreign key to their
respective table.  That's how you do a many-to-many or
zero/one-to-zero/one relationship, which is what this is.

It depends entirely on whether your business logic ever needs to treat
customers and employees the same, and how often you need to do that.
You can, after all, do a distinct union if you only need to do this very
rarely and the field names in your tables are similar enough, but if you
need to do it a lot then you should design the database accordingly.

--
Brandon Aiken
CS/IT Systems Engineer

-----Original Message-----
From: pgsql-novice-owner@postgresql.org
[mailto:pgsql-novice-owner@postgresql.org] On Behalf Of
operationsengineer1@yahoo.com
Sent: Friday, November 24, 2006 5:11 AM
To: pgsql-novice@postgresql.org
Subject: [NOVICE] Data (Table) Structure Question

i hope everyone's thanksgiving was grand.

i have contacts, customers and employees that i want
to manage in a db application.

i can think of two ways to do this.

first, have a table for each and fill each with all
the relevant data:

1. t_custoemrs
2. t_employees
3. t_contacts

second, have a contacts table that records data that
is repeated throughout each table (ie, name, address,
phone, etc...)

i could then have a t_employees table with a foreign
key to the t_contacts table id.  this table would only
have employee related information and would link back
to contacts.

t_customers would do the same - list only customer
specific information.

i think the latter way is the way to go, but i'm not
sure.  i don't particularly like t_contacts as the
name of the general table.  maybe i need to name it
persons.

anyway, i'd value the input of some more experienced
developers.

tia,

oe1



________________________________________________________________________
____________
Do you Yahoo!?
Everyone is raving about the all-new Yahoo! Mail beta.
http://new.mail.yahoo.com

---------------------------(end of broadcast)---------------------------
TIP 5: don't forget to increase your free space map settings

Re: Data (Table) Structure Question

From
Richard Broersma Jr
Date:
> i have contacts, customers and employees that i want
> to manage in a db application.
> i can think of two ways to do this.
> first, have a table for each and fill each with all
> the relevant data:
> 1. t_custoemrs
> 2. t_employees
> 3. t_contacts
> second, have a contacts table that records data that
> is repeated throughout each table (ie, name, address,
> phone, etc...)
> i could then have a t_employees table with a foreign
> key to the t_contacts table id.  this table would only
> have employee related information and would link back
> to contacts.
> t_customers would do the same - list only customer
> specific information.
> i think the latter way is the way to go, but i'm not
> sure.  i don't particularly like t_contacts as the
> name of the general table.  maybe i need to name it
> persons.
> anyway, i'd value the input of some more experienced
> developers.

Are you trying to find a way to relate an employee to one or more customers?

Regards,

Richard Broersma Jr.

Re: Data (Table) Structure Question

From
Date:
> I believe the preferred way to do this is to use
> sub-types.  Create a
> t_person table.  Make a type field if you wish with
> 'E' for an employee
> or 'C' for a customer,

a customer can also be an employee.  one application
i'm working on is for a loan broker and employees can
get loans through this broker.

i'm looking for a way to be able to model this while
not repeating data entry.

> or you can use implicit
> typing from joins
> ('t_person inner join t_employee' will always get
> only employees, etc.).
> You might even wish to create views from these
> tables to make
> presentation easier.

iiuc, this means the data for a person that is also an
employee is duplicated - one time in t_person and one
time in t_employees, right?  my gut feel says to avoid
the duplication, but maybe it is the lesser of two
evils and i'm just not sure where to draw that line in
the sand.

> The other option is to treat employees and customers
> as different and
> unrelated entities entirely.  Then you'd make a
> t_employee table and a
> t_customer table, and there would be no t_contacts
> or t_person table.

iiuc, this duplicates data (once in employee and once
in customer for those folks who are customers and
employees), too.

> In this latter case if you happen to have some
> employees who are also
> customers, then you'd make a table, say
> t_customer_employee, which has
> two fields: one the primary key of t_employee and
> the other the primary
> key of t_customer.  Then you make each one a foreign
> key to their
> respective table.  That's how you do a many-to-many
> or
> zero/one-to-zero/one relationship, which is what
> this is.

this link table would be in place to only list the
dual role people - customers and employees, right?
for some reason, this doesn't approach feel right.

> It depends entirely on whether your business logic
> ever needs to treat
> customers and employees the same, and how often you
> need to do that.

employees and customers can be the same and it will
happen enough that it needs to be considered in the
application.

Richard, no, i'm not relating and employee to one or
more customers.  i may well end relating one or more
employees to a transaction that may have one or more
customers (clients).

in that case, i'd use a link table to link them all
together.

my problem is that i don't want to repeat data entry
in the table structure and the only way i can think of
doing that is to have a persons table with all known
people and then have clients and employees tables that
have a foreign key linked to the relevant persons
table id.

however, this isn't jumping out to me as the obvious
best way to do this.

Brandon and Richard, thanks for taking the time to
chime in here.



____________________________________________________________________________________
Do you Yahoo!?
Everyone is raving about the all-new Yahoo! Mail beta.
http://new.mail.yahoo.com

Re: Data (Table) Structure Question

From
Richard Broersma Jr
Date:
> employees and customers can be the same and it will
> happen enough that it needs to be considered in the
> application.
> in that case, i'd use a link table to link them all
> together.
>
> my problem is that i don't want to repeat data entry
> in the table structure and the only way i can think of
> doing that is to have a persons table with all known
> people and then have clients and employees tables that
> have a foreign key linked to the relevant persons
> table id.

This wouldn't create duplicate data in you database.  I believe
that Brandon is referring to a data model know as a
(generalization/inheritance) Hierarchy. This works by vertically
partitioning your data. I'll explain more below.


>
> however, this isn't jumping out to me as the obvious
> best way to do this.

There are two ways that I know of to do this:
1) a recursivly joined table
In this model you would only have one table that holds all people.
you would have one column that that is a foreign key that referenced the primary key of another
record. i.e.:

pkey  |  fkey  |  title  |   name | other | info |
1     |null    |lender   |dave    |       |      |
2     |null    |lender   |ted     |       |      |
3     |1       |emp      |jeff    |       |      |
4     |2       |emp      |sam     |       |      |

so if you wanted to know all of the people that a lender was loaning to:

select L.name as lender, E.name as emp
from t_person as L left join t_person as E
on (L.pkey = e.fkey);

This works okey as is very easy to set up, but doesn't scale well
with changing requiredments.


The other method is to use some sort heirarchy.  you can do this using
a postgresql extenstion called table inheritance. see the create table syntax
in the manual, or you can set up your one using vertically partitioned tables
that are linked together.  I read a little about this data model in ERD modeling books and
my SQL for smarties book that I am currently reading.

Using vertical partitioning, you would have one person table that holds information
that is common to all people.  Next you add sub-set tables Like employee, lender, bosses,
customer, vendor, that only hold extenstion data that would be not-applicable or beyond the scope
of a person.  Where applicable these tables would have a 1 to 1 link back to the person table.

I.e.  a person doesn't necessarly have
      but the ones linked to employee do have one in the employee table

      a person doesn't necessarly have
      credentials for lending but a person
      linked to the lender table does and
      the lender table hold this credentials.

This model requires alot more work to set up, but is can easily scale up to almost anything that
you throw at it.

I hope that this explains a little.  it is hard to explain it without the aid of a diagram.
This link might help:
http://uml.visual-paradigm.com/uml/Object_Relational_Mapping/New_Inheritance_Strategy_(Table_per_subclass)

The nice thing is that you can easily put relate table between two entities like lenders and
employees to track this information.

Regards,

Richard Broersma Jr.

Re: Data (Table) Structure Question

From
Date:
> > employees and customers can be the same and it
> will
> > happen enough that it needs to be considered in
> the
> > application.
> > in that case, i'd use a link table to link them
> all
> > together.
> >
> > my problem is that i don't want to repeat data
> entry
> > in the table structure and the only way i can
> think of
> > doing that is to have a persons table with all
> known
> > people and then have clients and employees tables
> that
> > have a foreign key linked to the relevant persons
> > table id.
>
> This wouldn't create duplicate data in you database.
>  I believe
> that Brandon is referring to a data model know as a
> (generalization/inheritance) Hierarchy. This works
> by vertically
> partitioning your data. I'll explain more below.
>
>
> >
> > however, this isn't jumping out to me as the
> obvious
> > best way to do this.
>
> There are two ways that I know of to do this:
> 1) a recursivly joined table
> In this model you would only have one table that
> holds all people.
> you would have one column that that is a foreign key
> that referenced the primary key of another
> record. i.e.:
>
> pkey  |  fkey  |  title  |   name | other | info |
> 1     |null    |lender   |dave    |       |      |
> 2     |null    |lender   |ted     |       |      |
> 3     |1       |emp      |jeff    |       |      |
> 4     |2       |emp      |sam     |       |      |
>
> so if you wanted to know all of the people that a
> lender was loaning to:
>
> select L.name as lender, E.name as emp
> from t_person as L left join t_person as E
> on (L.pkey = e.fkey);
>
> This works okey as is very easy to set up, but
> doesn't scale well
> with changing requiredments.
>
>
> The other method is to use some sort heirarchy.  you
> can do this using
> a postgresql extenstion called table inheritance.
> see the create table syntax
> in the manual, or you can set up your one using
> vertically partitioned tables
> that are linked together.  I read a little about
> this data model in ERD modeling books and
> my SQL for smarties book that I am currently
> reading.
>
> Using vertical partitioning, you would have one
> person table that holds information
> that is common to all people.  Next you add sub-set
> tables Like employee, lender, bosses,
> customer, vendor, that only hold extenstion data
> that would be not-applicable or beyond the scope
> of a person.  Where applicable these tables would
> have a 1 to 1 link back to the person table.
>
> I.e.  a person doesn't necessarly have
>       but the ones linked to employee do have one in
> the employee table
>
>       a person doesn't necessarly have
>       credentials for lending but a person
>       linked to the lender table does and
>       the lender table hold this credentials.
>
> This model requires alot more work to set up, but is
> can easily scale up to almost anything that
> you throw at it.
>
> I hope that this explains a little.  it is hard to
> explain it without the aid of a diagram.
> This link might help:
>
http://uml.visual-paradigm.com/uml/Object_Relational_Mapping/New_Inheritance_Strategy_(Table_per_subclass)
>
> The nice thing is that you can easily put relate
> table between two entities like lenders and
> employees to track this information.
>
> Regards,
>
> Richard Broersma Jr.
>

Richard, the latter method makes much more sense in my
mind.  i don't think scaling will be an issue (i'd
*love* to have *that* problem!), but i want something
that makes sense to me.

however, i don't understand what an extenstion would
do.  wouldn't using normal tables with apporpriate
primary / foreign key links work just fine?

tia...



____________________________________________________________________________________
Yahoo! Music Unlimited
Access over 1 million songs.
http://music.yahoo.com/unlimited

Re: Data (Table) Structure Question

From
Richard Broersma Jr
Date:
> Richard, the latter method makes much more sense in my
> mind.  i don't think scaling will be an issue (i'd
> *love* to have *that* problem!), but i want something
> that makes sense to me.
>
> however, i don't understand what an extenstion would
> do.  wouldn't using normal tables with apporpriate
> primary / foreign key links work just fine?

If you are referring to a generalization hierarchy,  you are using tables with primary keys and
foreign keys... However, each table has a one to one relationship.  Modeling a parts catalog is a
problem lends itself well to a generalizatoin hierarchy.

At the (highest level)/(most general) table of the hierarchy would be a simple parts table all of
the information in this table is common for all parts in a catalog:

tbl_Parts:
 PartNo  |    part_type  |   description   | unit_cost |
--------------------------------------------------------
1        | motor         | .25 hp DC motor |  50.00    |
2        | paint         | silver spray can|  2.00     |
3        | motor         | piston pump mtr |  40.00    |
4        | paint         | gray 1gal latex |  15.00    |
5        | relay         | 4PDT 24vdc relay|  20.00    |

This is a simple table but it doesn't allow you hold specific data about each type of part.  In
this case you have three options.  you can increase the size of you description field to around a
thousand characters so you have room to add a detail description, but this can be inconvient and
ugly to deal with.

or you can nullable column to this table that you filled in when it applies to a specific part.
This works well as long as you don't have many types of parts that require a specific field and
you only need a few nullable column to hold the additional details.

In the case of a parts table, I would like to have alot of additional columns to specify
additional detail about each part, and I could have hundreds of diffent part types.  So this in
case, I would like to put the additional information the (lower level child/more specific)
auxillary tables.

Since I am only showing 3 part types I will only create 3 additional tables:
Motor, Paint, relay:

Motors:
PartNo|part_type|voltage | HP | SF |
--------------------------------------
1     |motor    | 48VDC  |.25 | 1.5  |
3     |motor    | 120VAC | 5  | 1.25 |

if you joined tbl_parts to Motor you like:

select partNo, part_type, description, Price, voltage, hp, SF
from tbl_parts as P join Motors as M
on ( P.partNo, P.part_type) = ( M.partNo, M.part_type)
;

PartNo|part_type|description    |unitc|voltage | HP | SF |
----------------------------------------------------------
1     |motor    |.25 hp DC motor|50.00| 48VDC  |.25 | 1.5|
3     |motor    |piston pump mtr|40.00| 120VAC | 5  |1.25|


You use the same technique to create specific detail table that relate back to the main parts
table.  I would do this for the paint table and relay tables.

At this point ( having created the motor,paint,relay table) I can start building relationships
between these child tables.

Lets say you wanted to track which relays that were sold with a certail motor, you would create a
relate table between the two.

motors --------->[ rlt_motor_relays]<----------- relays.

To help explain it further you can read about the postgresql extenstion that supports this:
http://www.postgresql.org/docs/8.2/interactive/ddl-inherit.html

Regards,

Richard Broersma Jr.

Re: Data (Table) Structure Question

From
"Duncan Garland"
Date:
Hi,

The second structure is more normalised and it's a good rule of thumb to
normalise your data. Does anything else need to be split out? For instance
can a person have more than 1 address? Do you need an address history?

Regards

Duncan