473,407 Members | 2,598 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,407 software developers and data experts.

Compound Key Question

I'm generally against using compound keys, except in join tables,
but I'm currently mapping out a schema where the join table has
child records. The application is for fund-raising and I have four
relevant tables:

tblPerson
tblOutreach -- the list of fund-raising actions/events (letters,
events, etc.)

To join these two tables, I have:

tblPersonOutreach
PK: PersonID + OutreachID

Joined to that is:
tblContributions
PK: ContributionID
FK: ???

The question is:

Should I create a surrogate Autonumber in tblPersonOutreach to have
a single-field join between tblContribution and tblPersonOutreach,
or store the two fields of the compound key of tblPersonOutreach in
tblContribution?

I would normally lean towards using the surrogate key
(tblPersonOutreachID), but in this case, I can see that it would be
quite common for me to want to display or print data from tblPerson
and tblContribution, or data from tblOutreach and tblContribution
(+tblPerson, in most cases). Storing the compound key means that I
could leave the join table out of the mix entirely.

Then it occurs to me that if I'm going to structure it this way,
maybe I should just collapse tblPersonOutreach and tblContribution
into a single table. It means that there won't be a proper 1:N
relationship between the Outreach action and the contributions it
generates, but, well, given that the vast majority of these outreach
actions will generate only one contribution per action, and given
that there's very little data in the join table, I'm not sure I see
any real benefit from maintaining the strictly correct normalized
structure.

I've got another app which is used for fundraising and it works
exactly the same way, with the two tables collapsed into one, and it
has never posed any kind of problem whatsoever. However, the
difference there is that in that application, a record is created
only when a contribution is received (i.e., they don't track
unsuccessful outreach actions), so it makes a great deal of sense to
collapse the two into one.

It actually would make UI design easier. On the other hand, I could
always use a flattened recordsource for me list of Outreach
events/contributions (I was originally considering using a simple
datasheet list with cascading datasheets to show the contributions).

Thoughts? Comments?

I'm really not seeing any benefit to having the join table as a
separate table, except for an exactitude in data modelling that has
no benefit that I can see of in an actual application.

--
David W. Fenton http://www.bway.net/~dfenton
dfenton at bway dot net http://www.bway.net/~dfassoc
Nov 13 '05 #1
6 3726
David,
I ain't agin or fer any particular thing. Compound keys, if they help, are
something I'll use. It depends on what my customer wants. It most
especially depends on how my client answers the question, "What about your
organization are you measuring?" In most cases reports are about measuring
the performance of an organization in terms of declared aspects of the
business. Crap, bunch of jargon. One more time, in most cases the
management of an organization wants a database so they can learn how the
organization is performing and then make some decisions that will make it
perform better. Implied in your Person and Outreach tables is a need to
understand how much money was contributed by a person or during a particular
outreach event or activity. This would lead me to build a couple dimension
tables--Person and Outreach, and a fact table, Contributions, which would
have as a compound primary key PersonOutreach. I don't have access to your
requirements document so I can't say whether my start at a schema would work
for your customer. But compound keys are useful in data warehouse design
and I wouldn't just dismiss them because they don't fit what a text book
says is the orthodox design approach.

"David W. Fenton" <dX********@bway.net.invalid> wrote in message
news:Xn**********************************@24.168.1 28.90...
I'm generally against using compound keys, except in join tables,
but I'm currently mapping out a schema where the join table has
child records. The application is for fund-raising and I have four
relevant tables:

Nov 13 '05 #2
If I understand your situation correctly, it looks like you have a
many-to-many relationship between tblPerson and tblOutreach. That is,
one person can potentially contribute to multiple outreaches, and one
outreach will have many people contributing to it. In my experience,
it's always best to use a join table between many-to-many relationships
with a unique key for each join record. I would structure it like this

tblPerson tblPersonOutreach tblOutreach
--------- ----------------- -----------
PersonKey------| PersonOutreachKey |-----OutreachKey
PersonName |-----PersonFK | OutreachName
PersonAddr OutreachFK--------------| OutreachAddr
MorePersonData ContributionData MoreOutreachData

I may never use the join table key (PersonOutreachKey) but it's there
uniquely identifying each record if needed. That's where I would put
all the contribution data, such as amount, date, etc., data specific to
each contribution. When I design a database, I use unique keys for every
table.

Of course there are many ways you could do this, that's just how I'd do it.

Paul
David W. Fenton wrote:
I'm generally against using compound keys, except in join tables,
but I'm currently mapping out a schema where the join table has
child records. The application is for fund-raising and I have four
relevant tables:

tblPerson
tblOutreach -- the list of fund-raising actions/events (letters,
events, etc.)

To join these two tables, I have:

tblPersonOutreach
PK: PersonID + OutreachID

Joined to that is:
tblContributions
PK: ContributionID
FK: ???

The question is:

Should I create a surrogate Autonumber in tblPersonOutreach to have
a single-field join between tblContribution and tblPersonOutreach,
or store the two fields of the compound key of tblPersonOutreach in
tblContribution?

I would normally lean towards using the surrogate key
(tblPersonOutreachID), but in this case, I can see that it would be
quite common for me to want to display or print data from tblPerson
and tblContribution, or data from tblOutreach and tblContribution
(+tblPerson, in most cases). Storing the compound key means that I
could leave the join table out of the mix entirely.

Then it occurs to me that if I'm going to structure it this way,
maybe I should just collapse tblPersonOutreach and tblContribution
into a single table. It means that there won't be a proper 1:N
relationship between the Outreach action and the contributions it
generates, but, well, given that the vast majority of these outreach
actions will generate only one contribution per action, and given
that there's very little data in the join table, I'm not sure I see
any real benefit from maintaining the strictly correct normalized
structure.

I've got another app which is used for fundraising and it works
exactly the same way, with the two tables collapsed into one, and it
has never posed any kind of problem whatsoever. However, the
difference there is that in that application, a record is created
only when a contribution is received (i.e., they don't track
unsuccessful outreach actions), so it makes a great deal of sense to
collapse the two into one.

It actually would make UI design easier. On the other hand, I could
always use a flattened recordsource for me list of Outreach
events/contributions (I was originally considering using a simple
datasheet list with cascading datasheets to show the contributions).

Thoughts? Comments?

I'm really not seeing any benefit to having the join table as a
separate table, except for an exactitude in data modelling that has
no benefit that I can see of in an actual application.

Nov 13 '05 #3
rkc
David W. Fenton wrote:
Then it occurs to me that if I'm going to structure it this way,
maybe I should just collapse tblPersonOutreach and tblContribution
into a single table. It means that there won't be a proper 1:N
relationship between the Outreach action and the contributions it
generates, but, well, given that the vast majority of these outreach
actions will generate only one contribution per action, and given
that there's very little data in the join table, I'm not sure I see
any real benefit from maintaining the strictly correct normalized
structure.

I'd have to assume, because you don't say, that there must be some
other info in tblPersonOutreach that would be duplicated in
tblContribution if you did combine them. Otherwise there is no point
to tblPersonOutreach in the first place.
Nov 13 '05 #4
rkc <rk*@rochester.yabba.dabba.do.rr.bomb> wrote in
news:AQ*******************@twister.nyroc.rr.com:
David W. Fenton wrote:
Then it occurs to me that if I'm going to structure it this way,
maybe I should just collapse tblPersonOutreach and
tblContribution into a single table. It means that there won't be
a proper 1:N relationship between the Outreach action and the
contributions it generates, but, well, given that the vast
majority of these outreach actions will generate only one
contribution per action, and given that there's very little data
in the join table, I'm not sure I see any real benefit from
maintaining the strictly correct normalized structure.


I'd have to assume, because you don't say, that there must be some
other info in tblPersonOutreach that would be duplicated in
tblContribution if you did combine them. Otherwise there is no
point to tblPersonOutreach in the first place.


Presently, the only data I have in tblPersonOutreach (other than the
two keys) is the date of creation of the record and who created it.
I'm not sure if that information serves any purpose at all
independent of the other information. Once a contribution is
received, does it really matter when the PersonOutreach record was
created (most of them will be created in an automated fashion when
the app is finished, anyway, as the result of data exports or mail
merges).

--
David W. Fenton http://www.bway.net/~dfenton
dfenton at bway dot net http://www.bway.net/~dfassoc
Nov 13 '05 #5
rkc
David W. Fenton wrote:
rkc <rk*@rochester.yabba.dabba.do.rr.bomb> wrote in
news:AQ*******************@twister.nyroc.rr.com:

David W. Fenton wrote:

Then it occurs to me that if I'm going to structure it this way,
maybe I should just collapse tblPersonOutreach and
tblContribution into a single table. It means that there won't be
a proper 1:N relationship between the Outreach action and the
contributions it generates, but, well, given that the vast
majority of these outreach actions will generate only one
contribution per action, and given that there's very little data
in the join table, I'm not sure I see any real benefit from
maintaining the strictly correct normalized structure.


I'd have to assume, because you don't say, that there must be some
other info in tblPersonOutreach that would be duplicated in
tblContribution if you did combine them. Otherwise there is no
point to tblPersonOutreach in the first place.

Presently, the only data I have in tblPersonOutreach (other than the
two keys) is the date of creation of the record and who created it.
I'm not sure if that information serves any purpose at all
independent of the other information. Once a contribution is
received, does it really matter when the PersonOutreach record was
created (most of them will be created in an automated fashion when
the app is finished, anyway, as the result of data exports or mail
merges).


I see Person(contributor) in a many to many relationship with
Outreach(contributed to) joined by Contribution.

Unless PersonOutreach serves a purpose that can't be served by Contribution.

Nov 13 '05 #6
rkc <rk*@rochester.yabba.dabba.do.rr.bomb> wrote in
news:ox*******************@twister.nyroc.rr.com:
David W. Fenton wrote:
rkc <rk*@rochester.yabba.dabba.do.rr.bomb> wrote in
news:AQ*******************@twister.nyroc.rr.com:

David W. Fenton wrote:
Then it occurs to me that if I'm going to structure it this way,
maybe I should just collapse tblPersonOutreach and
tblContribution into a single table. It means that there won't
be a proper 1:N relationship between the Outreach action and the
contributions it generates, but, well, given that the vast
majority of these outreach actions will generate only one
contribution per action, and given that there's very little data
in the join table, I'm not sure I see any real benefit from
maintaining the strictly correct normalized structure.

I'd have to assume, because you don't say, that there must be
some other info in tblPersonOutreach that would be duplicated in
tblContribution if you did combine them. Otherwise there is no
point to tblPersonOutreach in the first place.

Presently, the only data I have in tblPersonOutreach (other than
the two keys) is the date of creation of the record and who
created it. I'm not sure if that information serves any purpose
at all independent of the other information. Once a contribution
is received, does it really matter when the PersonOutreach record
was created (most of them will be created in an automated fashion
when the app is finished, anyway, as the result of data exports
or mail merges).


I see Person(contributor) in a many to many relationship with
Outreach(contributed to) joined by Contribution.

Unless PersonOutreach serves a purpose that can't be served by
Contribution.


Well, I'm not going to be able to resolve it until I talk with the
client. It depends on what data they want to store.

Say, for example, they hold a fundraising event, but they send out
snail mail invites to some people and email invites to others. Where
should I store that information? It belongs in PersonOutreach.

Now, the client may not care whether a person was sent an email or
an actual letter. If they don't, then I don't have to worry about
it.

Or, if they do, I may need to structure Outreach differently, so
that an event can have multiple types of contact with the donors.

I'm leaning towards just implementing it without collapsing the two
tables, but basically, the question comes down to:

What's the cost of the extra join?

If the cost is not high, then I can implement it that way and the
user will never know, since I'll only ever present data in the
flattened view (which would be the case even when I need the extra
table).

--
David W. Fenton http://www.bway.net/~dfenton
dfenton at bway dot net http://www.bway.net/~dfassoc
Nov 13 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Sonia | last post by:
I have been looking for a definition of a compound class but cannot find it anywhere ? What exactly is a compound class ? Thanks
4
by: Mark | last post by:
BEGINNER QUESTION I have a table which has a compound primary key consisting of two columns. One of these columns is a foreign key which is generated in another table by an identity. I want...
6
by: William Ahern | last post by:
So, GCC 4.01 is giving errors that GCC 3.3 did not, and I'm thinking they've gone overboard with their new type checking infrastructure. Here's the supposedly offending code (no laughing or...
7
by: Eric Laberge | last post by:
Aloha! This question is meant to be about C99 and unnamed compound objects. As I read, if such a construct as int *p = (int){0}; is used within a function, then it has "automatic storage...
8
by: wespvp | last post by:
I am using PostgreSQL 7.4.1 on RedHat 7.2. The query I am executing is something like (I replaced all the return values with 'count'): db=> explain select count(*) from messages m join (select...
7
by: Timo Haberkern | last post by:
Hi there, i have some troubles with my TSearch2 Installation. I have done this installation as described in http://www.sai.msu.su/~megera/oddmuse/index.cgi/Tsearch_V2_compound_words...
6
by: c_beginner | last post by:
yes, this is my how work question. Since I am lack in getting an assistance with my lab work I put this in this advance group. Sorry for the trouble I am making. Write a program to calculate the...
0
by: kath | last post by:
Hi.... XLRDError: Can't find workbook in OLE2 compound document What does this error means? When I try to open some excel files using XLRD, I encounter this error. Not with every excel, but...
27
by: Nate Eldredge | last post by:
Consider the following pseudo-code: #include <opaque.h> struct foo { int a; opaque_t op; int b; };
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.