----- Original Message ----- 
From: "Chris Kavanagh" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Monday, December 06, 2004 12:11 PM
Subject: A newbie and his first MySQL schema


> Dear list,
>
> So I'm having a bit of trouble with my first schema.  I'm sure I'm
> missing something idiotic here, but days of learning MySQL and setting
> up servers and working in UNIX have kind of fried my brain.  Okay, here
> goes:
>
> My project management system includes (among others) two tables:
> "people" and "projects".  I want each project to have a list of people
> that are authorised to view it.  To my mind, the field ought to look a
> bit like this:
>
> --
> Authorised list:
> Chris Kavanagh
> Joe Schmoe
> Jane Doe
> --
>
> But fields can't hold multiple values, can they?  And on my schema, it
> seems to be a many-to-many relationship between the two tables, and I
> heard that they are the work of the Devil and must be shunned.  I'm
> sure I need to make a new table or something, but I'm not really sure
> which one.  Can anyone help me?
>
First of all, there is no problem with storing a value like "Chris Kavanagh"
in a single column; a column defined as char() or varchar() or even the BLOB
should store that data just fine. You just have to make sure that the column
is defined large enough to hold the largest value that you expect to store.

Of course, it is often a good idea to store the different parts of a name in
separate columns so that you can search on them individually. This can also
help with your understanding of the data. For instance, some Chinese people
I meet give me their last name first and then their first name, e.g. Lee
Xian, in the Chinese fashion (Remember that in the name "Mao Tse Tung",
"Mao" was his family name, not his first name). Other Chinese people give me
their first name first and then their last name, e.g. Xian Lee, the way we
usually do in the West. However, if you simply stored "Xian Lee" (or "Lee
Xian") in a single column and then had a requirement to return all of the
rows were the first name was "Lee", you might get confused when it comes to
"Lee Xian": is "Lee" his/her first name or family name? This situation could
easily happen if the input form that provided the data in the first place
simply called for the entire customer name to be entered in a single field.
On the other hand, if the form (and the underlying table) separated first
name and last name into two separate fields, you also know if "Lee" was the
person's first name or last name.

As for your other question, yes, many-to-many relationships are virtually
always split into a pair of one-to-many relationships for many good reasons.
In your case, you will have a table for people, a table for projects, and a
new table, usually called an "intersection" (or "association") table, to
show the relationships between people and projects. You're going to end up
with something like this:

People - one row for each employee, primary key employee ID
====
EmpID    Lastname    Firstname    ...
1            Kavanagh    Chris
2            Schmoe       Joe
3            Doe             Jane


Project - one row for each project, primary key project ID
=====
ProjID    ProjName    ....
A           Marketing System
B           Shipping System
C           Purchasing System


People_Project - one row for each person/project combination that actually
exists
==========
EmpID    ProjID
1            B
1            C
2            A
3            A
3            C

In other words, employee 1 works on projects B and C but not A. Employee 2
works only on project A. Employee 3 works on projects A and C but not B.

The primary key for the intersection table is the COMBINATION of EmpID and
ProjID! Neither column by itself would make sense as the primary key of the
table; the EmpID and ProjID need to be combined to form the primary key. It
is now possible to store as many projects for an employee as you like but no
way to say that Employee 1 is on Project B *twice*. That's exactly what you
want.

As a "bonus" feature, the intersection table can have additional columns if
that is appropriate. For example, each employee was dedicated to each
project for a dedicated percentage of their time, you could put that in the
intersection table since it is information about the person/project
combination. Then, you might end up with something like this:

People_Project
==========
EmpID    ProjID    Percent
1            B           50
1            C           50
2            A           100
3            A            25
3            C            75

In other words, employee 1 splits there time 50/50 between projects B and C;
employee 2 spends all of their time on project A; employee 3 spends 25% of
their time on project A and 75% on project C.

Rhino


-- 
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:    http://lists.mysql.com/[EMAIL PROTECTED]

Reply via email to