If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

 
Go Back  dBforums > General > Database Concepts & Design > A question of Database normalization

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old 08-20-07, 02:22
rojer_31 rojer_31 is offline
Registered User
 
Join Date: Aug 2007
Posts: 3
A question of Database normalization

Before my question, I'll give a brief discription of my application.

This is an online registration application to allow people to register and pay for any one of a set of (different types of) programs available. All of the programs have a set of common fields that the registrant has to enter.
Few (very few) programs have a varying set of optional fields (some of which are mandatory).
ie. Some types of programs need fields zzz and yyy. Others need aaa and bbb fields.

Right now, I just have the common set of fields in a single Table. I also have a seperate transaction related table (if that is of any importance).

So my question is, do I create a more 'normalised' database and put these additional fields in a seperate table, or do I just add these additional fields in the main registration table itself and use it only for those that need them?
And if I do use a separate table, how is that to be structured?

I'm sure this little 'problem' has come up before and someone has the perfect solution for this. I just need to know what that is

If it is needed, I could post the table structure as I have it.
Reply With Quote
  #2 (permalink)  
Old 08-20-07, 05:32
mike_bike_kite mike_bike_kite is offline
vaguely human
 
Join Date: Jun 2007
Location: London
Posts: 2,519
This is a first attempt for you but I haven't done one of these before.
The types for each field are up to you.
The stars indicate key fields.

Mike

Code:
-- stores all your apps
create table Apps (
   *id
   name
)

-- list of possible fields
-- if standard_yn=Y then this field applies to all apps
-- seq_no would decide the oprder it appears on screen
-- assume field_name is unique.
create table Fields(
   *field_name
   standard_yn
   seq_no
   mandatory_yn
)

-- list the non standard fields required for each app
create table AppOptionalFields(
   *app_id
   *field_name
)

-- if the user must pick from a list of values for a field
create table FieldValidValues(
   *field_name
   *value_code
   *value_str
)

-- the users responses for each field for each app.
-- Need to decide if standard fields just appear once per user
-- or are stored each time for each app.
-- This will affect whether app_id allows null or not
create table UserFieldValues(
   *user_id
   *field_name
   *app_id
   field_value
)

-- what ever fields you store for user
create table Users(
   *id
   name
   email
   pwd
   ...
)

-- not sure how you store payments
create table UserAppPayments(
   *user_id
   *app_id
   payment_date
   amount
)
Reply With Quote
  #3 (permalink)  
Old 08-20-07, 06:10
gvee gvee is offline
www.gvee.co.uk
 
Join Date: Jan 2007
Location: UK
Posts: 10,156
Quote:
Originally Posted by rojer 31
So my question is, do I create a more 'normalised' database and put these additional fields in a seperate table,
I reckon I'd run with that idea. This sounds like a situation where a 1:1 relationship should be maintained in more than one table.
__________________
George
Twitter | Blog
Reply With Quote
  #4 (permalink)  
Old 08-20-07, 08:11
r937 r937 is offline
SQL Consultant
 
Join Date: Apr 2002
Location: Toronto, Canada
Posts: 19,524
Quote:
Originally Posted by rojer_31
So my question is, do I create a more 'normalised' database and put these additional fields in a seperate table, or do I just add these additional fields in the main registration table itself and use it only for those that need them?
And if I do use a separate table, how is that to be structured?

I'm sure this little 'problem' has come up before and someone has the perfect solution for this. I just need to know what that is
there is no "perfect" solution, otherwise it would already be out there in the marketplace with a hefty price tag (and perhaps a free 30-day download)

what you have is almost a classic example of a subtype/supertype model (do a search)

your two main options:

1. a single common table with all columns (some of which must be NULLable)

2. a single common table (supertype) with additional related (subtype) tables

the "tipping point" between these two approaches is the ratio of the number of common columns to the number of unique columns

if there are but a few unique columns, use option 1

under no circumstances should you contemplate a design where you store a field name in a column
__________________
r937.com | rudy.ca
please visit Simply SQL and buy my book
Reply With Quote
  #5 (permalink)  
Old 08-20-07, 09:30
blindman blindman is offline
World Class Flame Warrior
 
Join Date: Jun 2003
Location: Ohio
Posts: 11,726
The other big consideration is the frequency with which new optional fields are defined. If you are going to be frequently adding new programs then you need a dynamic solution. Mike has suggested an EAV model. Another option is to use an XML column in the common table and avoid subtables altogether.
None of these solutions is perfect. All of the are awkard to implement in some way or another. Which you choose depends upon the nature of your data.
__________________
If it's not practically useful, then it's practically useless.

blindman
www.chess.com: "sqlblindman"
Reply With Quote
  #6 (permalink)  
Old 08-20-07, 09:33
mike_bike_kite mike_bike_kite is offline
vaguely human
 
Join Date: Jun 2007
Location: London
Posts: 2,519
Quote:
Originally posted by Rudy
under no circumstances should you contemplate a design where you store a field name in a column
The benifit of following Rudy's advice is being able to use foreign keys which will allow the database to screen bad data at a low level.

The only disadvantage is you'll just need to alter the structure of your database each time you have a new field for an existing application or a new application. This would involve either adding a new field to a table or creating a new table completely depending on your design. Obviously you'll need to redo all your application code as well to cope with these changes.

If you're happy doing all this work then this is definitely the way to go. I personally prefer systems which are compact, quick to write and are designed to cope with future changes. Up to you really

Mike
Reply With Quote
  #7 (permalink)  
Old 08-20-07, 09:38
r937 r937 is offline
SQL Consultant
 
Join Date: Apr 2002
Location: Toronto, Canada
Posts: 19,524
Quote:
Originally Posted by mike_bike_kite
Obviously you'll need to redo all your application code as well to cope with these changes.
that statement is inflammatory, alarmist, and fearmongering

there's no difference between adding a new column to a subtype/supertype model than to any other model -- only the affected portions of the app are affected
__________________
r937.com | rudy.ca
please visit Simply SQL and buy my book
Reply With Quote
  #8 (permalink)  
Old 08-20-07, 09:54
mike_bike_kite mike_bike_kite is offline
vaguely human
 
Join Date: Jun 2007
Location: London
Posts: 2,519
Quote:
that statement is inflammatory, alarmist, and fearmongering
... and true - unless I misunderstand your method.

If you're using new database fields to hold fields for the applications then this involves structural change. If you have structural change in the database then this needs to be matched with relevant changes in the application.

I don't view my solution as EAV (and all the attendant flaming that goes with it) - I'm simply storing the field name in a table which has a many to one relationship with the application. Generic yes - EAV no.

Mike
Reply With Quote
  #9 (permalink)  
Old 08-20-07, 10:04
pootle flump pootle flump is offline
King of Understatement
 
Join Date: Feb 2004
Location: One Flump in One Place
Posts: 14,905
It's EAV without the E.
__________________
Testimonial:
Quote:
pootle flump
ur codings are working excelent.
Reply With Quote
  #10 (permalink)  
Old 08-20-07, 10:29
blindman blindman is offline
World Class Flame Warrior
 
Join Date: Jun 2003
Location: Ohio
Posts: 11,726
Quote:
Originally Posted by r937
only the affected portions of the app are affected
No tautological arguments, please!
__________________
If it's not practically useful, then it's practically useless.

blindman
www.chess.com: "sqlblindman"
Reply With Quote
  #11 (permalink)  
Old 08-20-07, 11:08
r937 r937 is offline
SQL Consultant
 
Join Date: Apr 2002
Location: Toronto, Canada
Posts: 19,524
Quote:
Originally Posted by blindman
No tautological arguments, please!
ordinarily, i would agree with you, but in this instance i was contrasting only affected portions with all your application code

everyone who knows how a VIEW works will understand



no offence intended, i presume everyone here knows how a VIEW works
__________________
r937.com | rudy.ca
please visit Simply SQL and buy my book
Reply With Quote
  #12 (permalink)  
Old 08-20-07, 11:23
blindman blindman is offline
World Class Flame Warrior
 
Join Date: Jun 2003
Location: Ohio
Posts: 11,726
I would say that everyone who understands would understand.
__________________
If it's not practically useful, then it's practically useless.

blindman
www.chess.com: "sqlblindman"
Reply With Quote
  #13 (permalink)  
Old 08-20-07, 11:38
r937 r937 is offline
SQL Consultant
 
Join Date: Apr 2002
Location: Toronto, Canada
Posts: 19,524
that goes without saying, eh



um, wait a sec...
__________________
r937.com | rudy.ca
please visit Simply SQL and buy my book
Reply With Quote
  #14 (permalink)  
Old 08-20-07, 11:42
mike_bike_kite mike_bike_kite is offline
vaguely human
 
Join Date: Jun 2007
Location: London
Posts: 2,519
So if we use your approach to add a field to a new application we just :
  • create a new table for the application
  • add new fields when they're required
  • alter the view to incorperate each new field
While my "AV" approach would be
  • insert AppOptionalFields values ($my_app_id,'new_field')
I'm not sure I'm convinced yet

Also if you had 500 applications would you need 500 tables to hold the data? I'm not sure this would be very performance friendly.

Mike

EDIT: Added point about performance

Last edited by mike_bike_kite; 08-20-07 at 12:05.
Reply With Quote
  #15 (permalink)  
Old 08-20-07, 13:02
r937 r937 is offline
SQL Consultant
 
Join Date: Apr 2002
Location: Toronto, Canada
Posts: 19,524
who was that post in response to?

whose approach would add a table for an application? certainly not mine

i have a data-centric viewpoint towards database modelling, not an application-centric viewpoint

and look, please, i am certainly not out to convince you (i realize how much of an uphill battle that is, and i refuse to do it)
__________________
r937.com | rudy.ca
please visit Simply SQL and buy my book
Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On