Putting like tables into one table

W

Will G

Hey i know this might not sound smart, but i am working with a database where
initially the tables were or design horribly wrong. The tables have multiple
like fields and now they have a huge amount of record in them. now, the
person that design this tables have no idea on how to do create a database
and i am new to this as well. however, i know that it's no correct to create
tables like that in a database. e.x. of table: he created this tables in way
that he going to be entering information through a form as he creates this
beds.

bedID Quilt1 Quilt2 Quilt3 Spring Uph1 Uph2
33500 s0001 s0002 s0003 sp23 u888 u889

now the data is extensive and i would like someone to help me out to create
one table for Quilt and Uph and tell me how would this all come out if i have
a form that's design to enter information through it that way shown above .
 
S

Sprinks

Will,

Make a backup copy of your current database and create the master tables for
the quilts and uph's.

I assume you already have master tables for the two items similar to:

Quilts
--------------------
QuiltID Text to accommodate existing code (PK)
....other quilt-specific fields

Uph
--------------------
UphID Text (PK)
....other Uph-specific fields

I suggest two additional tables, BedQuilts and BedUph to hold the detail
records for each bed:

BedQuilts
-------------------
BedQuiltID AutoNumber (PK)
BedID Text (Foreign Key to Beds)
QuiltID Text (Foreign Key to Quilts)

BedUph
-------------------
BedUphID AutoNumber (PK)
BedID Text (Foreign Key to Beds)
UphID Text (Foreign Key to Quilts)

Create continuous subforms for the detail tables and embed them on your main
Bed form, linked by the BedID.

To insert the existing records into the new tables, perform a series of
Append queries from each Quilt field in the Beds table. The SQL for Quilt1
would be:

INSERT INTO BedQuilts ( BedID, QuiltID )
SELECT Beds.BedID, Beds.Quilt1
FROM Beds;

Modify the query for the other two Quilt fields, and follow the same
strategy to insert the Uphs into the BedUph table.

Load the form and check your data. When you're sure you've got them all as
expected, you can delete the Quilt1-3 and Uph1-2 fields from Beds.

Hope that helps.
Sprinks
 
W

Will G

Hello Sprinks,

sorry man, but i am very new to this and i appreciate your help. now, just
to be clear on what i am doing; in order for me to enter the existing records
into the new tables, create queries, from the big BED table and query just
the first Quilt and you said to perform the following:
INSERT INTO BedQuilts ( BedID, QuiltID )
SELECT Beds.BedID, Beds.Quilt1
FROM Beds;
in what part of that query should i enter this information and can you
please break down the steps to the subform explanation. because to me i am
going to have form that contains multiple combo box...from Quilt and Uph
fill...if i am creating a bed per say, i will need to apply is multiple
Quilts and Uph fills.....directly on a form.....sorry i am not be
understanding what you previously suggested. can you break it down for me
please...thanks Sprinkers
 
S

Sprinks

Will,

Don't sweat it; we were all newbies once. That's what this forum is
about--leveraging each others' experience.

Since I've made some assumptions, I think it would be a good idea to first
fully understand your current table structure(s). Then I can give detailed
instructions that match your table and field names. Please post your current
table(s) in the following format, e.g.:

Projects
-------------------------------------------------------------
FieldName FieldType
-------------------------------------------------------------
ProjectID AutoNumber (Primary Key)
ProjectName Text
Location Text
ProjectManagerID Integer (Foreign Key to Staff)

Sprinks
 
W

Will G

Hey Sprinks;
thanks for understanding man. now the big bad table looks like this:

BED

Field fieldtype
------------------------------------------
ID AutoNumber(Primary Key)
ModelNum text
Desc1 text
Desc2 text
Desc3 text
Spring text
pattern text
needle text
label text
labelDesc text
bottonfill(Bfill1) text
bottonfill(Bfill2) text
Quilt fill(Qfill1) text
Quilt fill(Qfill2) text
Quilt fill(Qfill3) text
Quilt fill(Qfill4) text
Uph fill(Uph1) text
Uph fill(Uph2) text
Uph fill(Uph3) text
Uph fill(Uph4) text

now i know this is a total wrong design table, i didnt design it, my boss
did. he doesnt know about access, nor to design a database. he design the
table in a way he will be entering or displaying information for a mattress.
he will have different layer of quilts and uph and so on......and he designed
the table that way. now my job is to fix this problem and come up with some
nice report for his production. for example. he wants a PO(purchase order)
for Quilts where the quilts items will be listed by Vendor and also for
Springs and Uphfills(upholstery). and each item has it's individual tables
with records already in them and this big monster that you see above also has
beds already formatted in it. meaning and model number that has all the other
records for the fields.

i have done what you previously suggested creating other tables with ex.
Quiltstable (quiltID, ModelNumber, quilt), but i am not sure on how creating
queries of the big table of each quilt item and this will automatically put
things in this new table. i created an append query for Bfill1 & Bfill2 and
Qfill1 & Qfill2....and how does that going to add this records into the new
tables because it's not doing them....HELP.....SORRY MAN AND THANKS
 
W

Will G

Hey Sprinks;
i have done transferring the data to the new tables with your suggestion of
Appended queries. now how can i come together with a form with multiple like
fields from the same table, like it was originally intended. and do i delete
the appended queries after this.
 
S

Sprinks

Will,

After seeing that some of my assumptions re: your current structure have
proved incorrect, the scope of rendering your application into fully
normalized tables that will be easy to maintain, while not conceptually
difficult, is larger than I first imagined.

The first step is getting your tables "normalized"--that is redesigning them
such that they follow certain rules of relational database design that render
it into one or more hierarchical, normalized "forms. Most developers try to
meet the requirements of 3rd normal form. Access doesn't fully support some
normal forms. I have posted links on the topic at the end of this post.

Inadequacies of Current Design:
--------------------------------------------------------
- Your current design violates first normal form because it contains
repeating groups: Descx, Bfillx, Qfillx, Uphx. Searches, for example, for a
given Quilt fill must pool searches across the QFill1, QFill2, QFill3 &
QFill4 fields.

- Furthermore, since all of these groups, plus the Spring, Pattern, Needle
Label, and Label Description fields are text fields, you have redundant data,
which is likely to be riddled with misspellings, further frustrating search
attempts. If you want to know which models use Spring 7CX, you may have to
search by:

7CX
7 CX
7C-X

- I suspect Label Description is fully defined by the Label field. If so,
the Label Description field is unnecessary.

- I'm not sure of the purpose of the multiple Description fields. It seems
they could either be a single Text or Memo field or belong in a one-to-many
detail table.

Correcting Single Field Design Inadequacies - Overview
---------------------------------------------------------------------------------------
While none of the steps are conceptually difficult, they are sufficiently
complex that I've broken it down into this Overview and more detailed
instructions below. Read the post completely before proceeding.

Major Steps:
- Normalize the tables by creating "lookup" tables that store a description
ONCE, thereby eliminating spelling permutations. In the process, we will use
temporary IDs to denote the equivalence of any spelling permutations that
currently exist.
- Create detail tables that eliminate the field groups. It sounds like you
may have already done this.
- Modify the existing form, and create and embed subforms for the detail
tables.

Resulting Table Designs
--------------------------------------------------------------------------------
The resulting structures will store only the numeric key from the "lookup"
table (called a foreign key) in the main and detail tables. The quotes
around "lookup" means that these are tables that you can use as the RowSource
of a combo box, NOT the to-be-avoided, problematic "lookup field"
functionality provided by Access in the table definition phase. They are
simply separate tables with an AutoNumber or other numeric primary key, and a
text description field.

Since BFillx, QFillx, and Uphx all contain fill materials, a single
FillMaterial lookup table can handle all three.

The resulting structure will look like the following. Choose more
meaningful field and table names as appropriate.

Mattresses (Main Table)
-----------------------------
ID AutoNumber (PK)
ModelNumber Text
SpringID Integer (Foreign Key to Springs)
PatternID Integer (Foreign Key to Patterns)
NeedleID Integer (Foreign Key to Needles)
LabelID Integer (Foreign Key to Labels)

Lookup Tables:

Springs
------------------------------
SpringID AutoNumber (PK)
Spring Text

Patterns
------------------------------
PatternID AutoNumber (PK)
Pattern Text

Needles
------------------------------
NeedleID AutoNumber (PK)
Needle Text

Labels
------------------------------
LabelID AutoNumber (PK)
Label Description

Descriptions *
------------------------------------------
DescriptionID AutoNumber
Description Text

* This might be a single text field in the main table w/no Lookup table
required, or a lookup table and a one-to-many detail table, depending on your
intent.

FillMaterials
------------------------------
FillMaterialID AutoNumber (PK)
FillMaterial Text

DetailTables (all in one-to-many relationship with Mattresses):
(I prefer to name detail tables using the name of the main & lookup tables +
Detail, but name them however you wish)
Note that all contain the MattressID field, by which we will link their
respective subforms to the main table.

MattressBattonDetail
-------------------------------------
MattressBattonID AutoNumber (PK)
MattressID Integer (FK to Mattresses)
FillMaterialID Integer (FK to FillMaterials)

MattressQuiltDetail
------------------------------
MattressQuiltID AutoNumber (PK)
MattressID Integer (FK to Mattresses)
FillMaterialID Integer (FK to FillMaterials)

MattressUphDetail
------------------------------
MattressUphDetailID AutoNumber (PK)
MattressID Integer (FK to Mattresses)
FillMaterialID Integer (FK to FillMaterials)

MattressDescriptionDetail
-----------------------------------------
MattressDescriptionDetailID AutoNumber (PK)
MattressID Integer (FK to Mattresses)
DescriptionID Integer (FK to Descriptions)


Correcting Data - Detail
---------------------------------------------------------------------
- Create a backup of your database.
- Modify the design of the Mattresses table, adding the following integer
fields: SpringID, NeedleID, PatternID, TempSpringID, TempNeedleID,
TempPatternID.
- Sort the Mattress table by Spring, and look for any spelling
permutations. Assign the same integer value to the TempSpringID field for
any equivalent springs, and a unique integer value to each unique spring.
For example, you might end up with something like the following:

Spring TempSpringID
-----------------------------------------
XC102 1
XC 102 1 (spelling permutation)
XC103 2
XC104 3
Xc104 3 (spelling permutation)

- Create the Spring table. Include an extra integer field to hold the
TempSpringID's just assigned.
- Review the Materials table. For each unique TempSpringID, enter this
value and a single "master" description for it into the Springs table.
Access will automatically assign the AutoNumber SpringID. You now have your
master "lookup" records.
- Create a query consisting of the Mattresses and Springs tables. Link them
by the TempSpringID, but delete the link Access assigns on SpringID. Drag
the SpringID of the Mattresses table to the query grid.
- Choose Query, Update Query from the menu.
- In the Update To: row, type Springs.SpringID. Access will place brackets
around the table and field names.
- Choose View, SQL to see the SQL. It should look like the following,
different ONLY by any different field and table names you choose:

UPDATE Mattresses INNER JOIN Springs ON Mattresses.TempSpringID =
Springs.TempSpringID SET Mattresses.SpringID = [Springs].[SpringID];

- If all looks good, press the Exclamation icon to run the update query.
- Review the Mattresses and Springs tables side-by-side. Whereever the
TempSpringID field matches from the Mattresses to the Springs table, the
SpringID should also match. If it does, you can delete the TempSpringID
field from both tables.

Modifying the Main Form
---------------------------------------------------------------------------------------------
- To display it correctly on your main form, load it in design view. Enable
the combo box wizard by selecting View, Toolbox, and making sure the button
with the wand and stars is depressed. Now add a combo box, preferably next
to the existing textbox bound to the text-based Spring field. Tell the
wizard to look up values from the Springs table. Select both fields, and
Hide Key Field (Recommended). This will display the text field in the combo
box but store the numeric key field. At the end, tell the wizard to store
the selection in the SpringID field. Save the form and return to Normal view.
- Scroll through the existing records. The value in the text Spring field
should correspond (less spelling permutations) with the value displayed in
the combo box. If this is verified, you can delete the textbox from the
form, and delete the text Spring field from the Mattresses table.
- You've now normalized the Springs field. Repeat the data correction and
form modification processes for the other main form fields--Needle, Pattern,
and Label.

When you've got these all working on the main form, repost. I'll think
carefully about how to handle the field groups in the meantime, it's a little
more complex now, since the fields are simply text.

Hope that helps.
Sprinks


Normalization Links:
ACC: Database Normalization Basics
http://support.microsoft.com/?id=100139
http://support.microsoft.com/?id=209534
http://support.microsoft.com/?id=283878

Database Normalization Tips by Luke Chung
http://www.fmsinc.com/tpapers/genaccess/databasenorm.html

Support WebCast: Database Normalization Basics
http://support.microsoft.com/default.aspx?scid=/servicedesks/webcasts/wc060600/wcblurb060600.asp

Database Normalization:
http://burks.bton.ac.uk/burks/foldoc/35/28.htm

5 Rules of Database Normalization:
http://www.datamodel.org/NormalizationRules.html

"Understanding Relational Database Design" Document Available in Download
Center:
http://support.microsoft.com/?id=283698
http://support.microsoft.com/?id=164172

ACC2000: "Understanding Relational Database Design"
http://support.microsoft.com/?id=234208

Fundamentals of Relational Database Design:
http://support.microsoft.com/?id=129519

Database Deisgn Principles:
http://msdn.microsoft.com/library/en-us/dndbdes/html/ch04DDP.asp
 
W

Will G

Hey Sprinks

man you load me up...thanks "to the second power", as i look at this, it
will definitely help getting the foot at the door to database done the right
way for me. i am in the process of doing everything you wrote down, only got
couple of questions.

1. what's going to be the FillMaterials tbl role?
2. in your privious posts, you told me to create appended queries to
transfer data to these new tables i created, now i will be using this tables
yes and do i need to normalize them as well or just those old orginal tbls?

thanks again man.....you are really a source
--
need help


Sprinks said:
Will,

After seeing that some of my assumptions re: your current structure have
proved incorrect, the scope of rendering your application into fully
normalized tables that will be easy to maintain, while not conceptually
difficult, is larger than I first imagined.

The first step is getting your tables "normalized"--that is redesigning them
such that they follow certain rules of relational database design that render
it into one or more hierarchical, normalized "forms. Most developers try to
meet the requirements of 3rd normal form. Access doesn't fully support some
normal forms. I have posted links on the topic at the end of this post.

Inadequacies of Current Design:
--------------------------------------------------------
- Your current design violates first normal form because it contains
repeating groups: Descx, Bfillx, Qfillx, Uphx. Searches, for example, for a
given Quilt fill must pool searches across the QFill1, QFill2, QFill3 &
QFill4 fields.

- Furthermore, since all of these groups, plus the Spring, Pattern, Needle
Label, and Label Description fields are text fields, you have redundant data,
which is likely to be riddled with misspellings, further frustrating search
attempts. If you want to know which models use Spring 7CX, you may have to
search by:

7CX
7 CX
7C-X

- I suspect Label Description is fully defined by the Label field. If so,
the Label Description field is unnecessary.

- I'm not sure of the purpose of the multiple Description fields. It seems
they could either be a single Text or Memo field or belong in a one-to-many
detail table.

Correcting Single Field Design Inadequacies - Overview
---------------------------------------------------------------------------------------
While none of the steps are conceptually difficult, they are sufficiently
complex that I've broken it down into this Overview and more detailed
instructions below. Read the post completely before proceeding.

Major Steps:
- Normalize the tables by creating "lookup" tables that store a description
ONCE, thereby eliminating spelling permutations. In the process, we will use
temporary IDs to denote the equivalence of any spelling permutations that
currently exist.
- Create detail tables that eliminate the field groups. It sounds like you
may have already done this.
- Modify the existing form, and create and embed subforms for the detail
tables.

Resulting Table Designs
--------------------------------------------------------------------------------
The resulting structures will store only the numeric key from the "lookup"
table (called a foreign key) in the main and detail tables. The quotes
around "lookup" means that these are tables that you can use as the RowSource
of a combo box, NOT the to-be-avoided, problematic "lookup field"
functionality provided by Access in the table definition phase. They are
simply separate tables with an AutoNumber or other numeric primary key, and a
text description field.

Since BFillx, QFillx, and Uphx all contain fill materials, a single
FillMaterial lookup table can handle all three.

The resulting structure will look like the following. Choose more
meaningful field and table names as appropriate.

Mattresses (Main Table)
-----------------------------
ID AutoNumber (PK)
ModelNumber Text
SpringID Integer (Foreign Key to Springs)
PatternID Integer (Foreign Key to Patterns)
NeedleID Integer (Foreign Key to Needles)
LabelID Integer (Foreign Key to Labels)

Lookup Tables:

Springs
------------------------------
SpringID AutoNumber (PK)
Spring Text

Patterns
------------------------------
PatternID AutoNumber (PK)
Pattern Text

Needles
------------------------------
NeedleID AutoNumber (PK)
Needle Text

Labels
------------------------------
LabelID AutoNumber (PK)
Label Description

Descriptions *
------------------------------------------
DescriptionID AutoNumber
Description Text

* This might be a single text field in the main table w/no Lookup table
required, or a lookup table and a one-to-many detail table, depending on your
intent.

FillMaterials
------------------------------
FillMaterialID AutoNumber (PK)
FillMaterial Text

DetailTables (all in one-to-many relationship with Mattresses):
(I prefer to name detail tables using the name of the main & lookup tables +
Detail, but name them however you wish)
Note that all contain the MattressID field, by which we will link their
respective subforms to the main table.

MattressBattonDetail
-------------------------------------
MattressBattonID AutoNumber (PK)
MattressID Integer (FK to Mattresses)
FillMaterialID Integer (FK to FillMaterials)

MattressQuiltDetail
------------------------------
MattressQuiltID AutoNumber (PK)
MattressID Integer (FK to Mattresses)
FillMaterialID Integer (FK to FillMaterials)

MattressUphDetail
------------------------------
MattressUphDetailID AutoNumber (PK)
MattressID Integer (FK to Mattresses)
FillMaterialID Integer (FK to FillMaterials)

MattressDescriptionDetail
-----------------------------------------
MattressDescriptionDetailID AutoNumber (PK)
MattressID Integer (FK to Mattresses)
DescriptionID Integer (FK to Descriptions)


Correcting Data - Detail
---------------------------------------------------------------------
- Create a backup of your database.
- Modify the design of the Mattresses table, adding the following integer
fields: SpringID, NeedleID, PatternID, TempSpringID, TempNeedleID,
TempPatternID.
- Sort the Mattress table by Spring, and look for any spelling
permutations. Assign the same integer value to the TempSpringID field for
any equivalent springs, and a unique integer value to each unique spring.
For example, you might end up with something like the following:

Spring TempSpringID
-----------------------------------------
XC102 1
XC 102 1 (spelling permutation)
XC103 2
XC104 3
Xc104 3 (spelling permutation)

- Create the Spring table. Include an extra integer field to hold the
TempSpringID's just assigned.
- Review the Materials table. For each unique TempSpringID, enter this
value and a single "master" description for it into the Springs table.
Access will automatically assign the AutoNumber SpringID. You now have your
master "lookup" records.
- Create a query consisting of the Mattresses and Springs tables. Link them
by the TempSpringID, but delete the link Access assigns on SpringID. Drag
the SpringID of the Mattresses table to the query grid.
- Choose Query, Update Query from the menu.
- In the Update To: row, type Springs.SpringID. Access will place brackets
around the table and field names.
- Choose View, SQL to see the SQL. It should look like the following,
different ONLY by any different field and table names you choose:

UPDATE Mattresses INNER JOIN Springs ON Mattresses.TempSpringID =
Springs.TempSpringID SET Mattresses.SpringID = [Springs].[SpringID];

- If all looks good, press the Exclamation icon to run the update query.
- Review the Mattresses and Springs tables side-by-side. Whereever the
TempSpringID field matches from the Mattresses to the Springs table, the
SpringID should also match. If it does, you can delete the TempSpringID
field from both tables.

Modifying the Main Form
---------------------------------------------------------------------------------------------
- To display it correctly on your main form, load it in design view. Enable
the combo box wizard by selecting View, Toolbox, and making sure the button
with the wand and stars is depressed. Now add a combo box, preferably next
to the existing textbox bound to the text-based Spring field. Tell the
wizard to look up values from the Springs table. Select both fields, and
Hide Key Field (Recommended). This will display the text field in the combo
box but store the numeric key field. At the end, tell the wizard to store
the selection in the SpringID field. Save the form and return to Normal view.
- Scroll through the existing records. The value in the text Spring field
should correspond (less spelling permutations) with the value displayed in
the combo box. If this is verified, you can delete the textbox from the
form, and delete the text Spring field from the Mattresses table.
- You've now normalized the Springs field. Repeat the data correction and
form modification processes for the other main form fields--Needle, Pattern,
and Label.

When you've got these all working on the main form, repost. I'll think
carefully about how to handle the field groups in the meantime, it's a little
more complex now, since the fields are simply text.

Hope that helps.
Sprinks


Normalization Links:
ACC: Database Normalization Basics
http://support.microsoft.com/?id=100139
http://support.microsoft.com/?id=209534
http://support.microsoft.com/?id=283878

Database Normalization Tips by Luke Chung
http://www.fmsinc.com/tpapers/genaccess/databasenorm.html

Support WebCast: Database Normalization Basics
http://support.microsoft.com/default.aspx?scid=/servicedesks/webcasts/wc060600/wcblurb060600.asp

Database Normalization:
http://burks.bton.ac.uk/burks/foldoc/35/28.htm

5 Rules of Database Normalization:
http://www.datamodel.org/NormalizationRules.html

"Understanding Relational Database Design" Document Available in Download
Center:
http://support.microsoft.com/?id=283698
http://support.microsoft.com/?id=164172

ACC2000: "Understanding Relational Database Design"
http://support.microsoft.com/?id=234208

Fundamentals of Relational Database Design:
http://support.microsoft.com/?id=129519

Database Deisgn Principles:
http://msdn.microsoft.com/library/en-us/dndbdes/html/ch04DDP.asp
 
S

Sprinks

Will,

Sorry to confuse you, Will.

2) To answer your 2nd question first, my previous post described multiple
append queries to BedQuilts and BedUph detail tables, and I haven't yet
posted a new solution to this portion of the problem.

The previous strategy was based on the erroneous assumption that you already
had lookup tables Quilts and Uph, consisting of a numeric primary key and a
text-based Description field. I'd assumed, then that the QFill1-4 and Uph1-4
fields in the main table were numeric foreign keys that corresponded to the
numeric primary fields of the Quilts and Uph tables when in fact they are
text fields.

The current realities being more complex than originally thought requires
three processes:

- The strategy of my original post no longer applies. We will have to start
over with the detail tables.

- Since the single fields to remain in the main table are ALSO text fields,
we need to, for each field:

- create a "lookup" table for the field
- eliminate the spelling permutations by assigning similar spellings the
same temp ID
- create master records under this temporary ID in the lookup table
- perform an update query to assign the AutoNumber ID assigned by Access
of the newly created master records to the foreign key ID field

- This process is described in detail in my last post. In addition to this
"spelling permutation phenomenon, the detail table records also have the
"field group" issue to deal with. The combination of these two is
sufficiently complex that I'd rather think about it carefully while you make
the changes on the fields to remain in the main table and their corresponding
controls in the main form. If you're successful, your experience will make
it easier for you to understand what's necessary for the detail tables.

1) It would be possible, as I'd originally suggested, to have separate
lookup tables for the fill materials being assigned to the Quilt and Uph
detail tables, which I thought already existed. But they're not
necessary--they and the Bfill detail represent a single entity--a
Material--and can therefore use a single lookup table that contains ALL
materials, whether it goes into a quilt, uph, or batton field.

Presumably some materials might go into more than one type, but presumably
they won't ALL be used for ALL types. This means you'll probably want to
limit the list of materials in the each detail combo box to only those
materials that are used in that particular detail--quilt materials for the
quilt detail, batton materials for the batton detail, etc. If so, we'll use
another strategy to so limit the combo boxes that still will permit the
simplicity of storing them in a single table.

Let me know when you've successfully made the changes to the fields in the
main table and their corresponding controls on the main form, and we'll move
on.

Sprinks

Will G said:
Hey Sprinks

man you load me up...thanks "to the second power", as i look at this, it
will definitely help getting the foot at the door to database done the right
way for me. i am in the process of doing everything you wrote down, only got
couple of questions.

1. what's going to be the FillMaterials tbl role?
2. in your privious posts, you told me to create appended queries to
transfer data to these new tables i created, now i will be using this tables
yes and do i need to normalize them as well or just those old orginal tbls?

thanks again man.....you are really a source
--
need help


Sprinks said:
Will,

After seeing that some of my assumptions re: your current structure have
proved incorrect, the scope of rendering your application into fully
normalized tables that will be easy to maintain, while not conceptually
difficult, is larger than I first imagined.

The first step is getting your tables "normalized"--that is redesigning them
such that they follow certain rules of relational database design that render
it into one or more hierarchical, normalized "forms. Most developers try to
meet the requirements of 3rd normal form. Access doesn't fully support some
normal forms. I have posted links on the topic at the end of this post.

Inadequacies of Current Design:
--------------------------------------------------------
- Your current design violates first normal form because it contains
repeating groups: Descx, Bfillx, Qfillx, Uphx. Searches, for example, for a
given Quilt fill must pool searches across the QFill1, QFill2, QFill3 &
QFill4 fields.

- Furthermore, since all of these groups, plus the Spring, Pattern, Needle
Label, and Label Description fields are text fields, you have redundant data,
which is likely to be riddled with misspellings, further frustrating search
attempts. If you want to know which models use Spring 7CX, you may have to
search by:

7CX
7 CX
7C-X

- I suspect Label Description is fully defined by the Label field. If so,
the Label Description field is unnecessary.

- I'm not sure of the purpose of the multiple Description fields. It seems
they could either be a single Text or Memo field or belong in a one-to-many
detail table.

Correcting Single Field Design Inadequacies - Overview
---------------------------------------------------------------------------------------
While none of the steps are conceptually difficult, they are sufficiently
complex that I've broken it down into this Overview and more detailed
instructions below. Read the post completely before proceeding.

Major Steps:
- Normalize the tables by creating "lookup" tables that store a description
ONCE, thereby eliminating spelling permutations. In the process, we will use
temporary IDs to denote the equivalence of any spelling permutations that
currently exist.
- Create detail tables that eliminate the field groups. It sounds like you
may have already done this.
- Modify the existing form, and create and embed subforms for the detail
tables.

Resulting Table Designs
--------------------------------------------------------------------------------
The resulting structures will store only the numeric key from the "lookup"
table (called a foreign key) in the main and detail tables. The quotes
around "lookup" means that these are tables that you can use as the RowSource
of a combo box, NOT the to-be-avoided, problematic "lookup field"
functionality provided by Access in the table definition phase. They are
simply separate tables with an AutoNumber or other numeric primary key, and a
text description field.

Since BFillx, QFillx, and Uphx all contain fill materials, a single
FillMaterial lookup table can handle all three.

The resulting structure will look like the following. Choose more
meaningful field and table names as appropriate.

Mattresses (Main Table)
-----------------------------
ID AutoNumber (PK)
ModelNumber Text
SpringID Integer (Foreign Key to Springs)
PatternID Integer (Foreign Key to Patterns)
NeedleID Integer (Foreign Key to Needles)
LabelID Integer (Foreign Key to Labels)

Lookup Tables:

Springs
------------------------------
SpringID AutoNumber (PK)
Spring Text

Patterns
------------------------------
PatternID AutoNumber (PK)
Pattern Text

Needles
------------------------------
NeedleID AutoNumber (PK)
Needle Text

Labels
------------------------------
LabelID AutoNumber (PK)
Label Description

Descriptions *
------------------------------------------
DescriptionID AutoNumber
Description Text

* This might be a single text field in the main table w/no Lookup table
required, or a lookup table and a one-to-many detail table, depending on your
intent.

FillMaterials
------------------------------
FillMaterialID AutoNumber (PK)
FillMaterial Text

DetailTables (all in one-to-many relationship with Mattresses):
(I prefer to name detail tables using the name of the main & lookup tables +
Detail, but name them however you wish)
Note that all contain the MattressID field, by which we will link their
respective subforms to the main table.

MattressBattonDetail
-------------------------------------
MattressBattonID AutoNumber (PK)
MattressID Integer (FK to Mattresses)
FillMaterialID Integer (FK to FillMaterials)

MattressQuiltDetail
------------------------------
MattressQuiltID AutoNumber (PK)
MattressID Integer (FK to Mattresses)
FillMaterialID Integer (FK to FillMaterials)

MattressUphDetail
------------------------------
MattressUphDetailID AutoNumber (PK)
MattressID Integer (FK to Mattresses)
FillMaterialID Integer (FK to FillMaterials)

MattressDescriptionDetail
-----------------------------------------
MattressDescriptionDetailID AutoNumber (PK)
MattressID Integer (FK to Mattresses)
DescriptionID Integer (FK to Descriptions)


Correcting Data - Detail
---------------------------------------------------------------------
- Create a backup of your database.
- Modify the design of the Mattresses table, adding the following integer
fields: SpringID, NeedleID, PatternID, TempSpringID, TempNeedleID,
TempPatternID.
- Sort the Mattress table by Spring, and look for any spelling
permutations. Assign the same integer value to the TempSpringID field for
any equivalent springs, and a unique integer value to each unique spring.
For example, you might end up with something like the following:

Spring TempSpringID
-----------------------------------------
XC102 1
XC 102 1 (spelling permutation)
XC103 2
XC104 3
Xc104 3 (spelling permutation)

- Create the Spring table. Include an extra integer field to hold the
TempSpringID's just assigned.
- Review the Materials table. For each unique TempSpringID, enter this
value and a single "master" description for it into the Springs table.
Access will automatically assign the AutoNumber SpringID. You now have your
master "lookup" records.
- Create a query consisting of the Mattresses and Springs tables. Link them
by the TempSpringID, but delete the link Access assigns on SpringID. Drag
the SpringID of the Mattresses table to the query grid.
- Choose Query, Update Query from the menu.
- In the Update To: row, type Springs.SpringID. Access will place brackets
around the table and field names.
- Choose View, SQL to see the SQL. It should look like the following,
different ONLY by any different field and table names you choose:

UPDATE Mattresses INNER JOIN Springs ON Mattresses.TempSpringID =
Springs.TempSpringID SET Mattresses.SpringID = [Springs].[SpringID];

- If all looks good, press the Exclamation icon to run the update query.
- Review the Mattresses and Springs tables side-by-side. Whereever the
TempSpringID field matches from the Mattresses to the Springs table, the
SpringID should also match. If it does, you can delete the TempSpringID
field from both tables.

Modifying the Main Form
---------------------------------------------------------------------------------------------
- To display it correctly on your main form, load it in design view. Enable
the combo box wizard by selecting View, Toolbox, and making sure the button
with the wand and stars is depressed. Now add a combo box, preferably next
to the existing textbox bound to the text-based Spring field. Tell the
wizard to look up values from the Springs table. Select both fields, and
Hide Key Field (Recommended). This will display the text field in the combo
box but store the numeric key field. At the end, tell the wizard to store
the selection in the SpringID field. Save the form and return to Normal view.
- Scroll through the existing records. The value in the text Spring field
should correspond (less spelling permutations) with the value displayed in
the combo box. If this is verified, you can delete the textbox from the
form, and delete the text Spring field from the Mattresses table.
- You've now normalized the Springs field. Repeat the data correction and
form modification processes for the other main form fields--Needle, Pattern,
and Label.

When you've got these all working on the main form, repost. I'll think
carefully about how to handle the field groups in the meantime, it's a little
more complex now, since the fields are simply text.

Hope that helps.
Sprinks


Normalization Links:
ACC: Database Normalization Basics
http://support.microsoft.com/?id=100139
http://support.microsoft.com/?id=209534
http://support.microsoft.com/?id=283878

Database Normalization Tips by Luke Chung
http://www.fmsinc.com/tpapers/genaccess/databasenorm.html

Support WebCast: Database Normalization Basics
http://support.microsoft.com/default.aspx?scid=/servicedesks/webcasts/wc060600/wcblurb060600.asp

Database Normalization:
http://burks.bton.ac.uk/burks/foldoc/35/28.htm

5 Rules of Database Normalization:
http://www.datamodel.org/NormalizationRules.html

"Understanding Relational Database Design" Document Available in Download
Center:
http://support.microsoft.com/?id=283698
http://support.microsoft.com/?id=164172

ACC2000: "Understanding Relational Database Design"
http://support.microsoft.com/?id=234208

Fundamentals of Relational Database Design:
http://support.microsoft.com/?id=129519

Database Deisgn Principles:
http://msdn.microsoft.com/library/en-us/dndbdes/html/ch04DDP.asp
 
W

Will G

Sprinks,
you the best. now, i have done most of the things that you had told me.
created this new table (Mattress main table with field:
ID,ModelNumber,SpringID,PatternID,NeedleID) and so on...these fields are
foreigh to the main table and are primary on thier corresponding ORGINAL
tables. Didnt create a Description on, just kept one Desc in the main table.

created the fillMaterials table.....which is like by it's primary key to a
field in the Quilt, Uph, Bfill tables.........now, i coverted the tables that
i had created for the Query Appending actions and turned them into the detail
tables....this action made me loose all the data that i had transfered
through the query appending....IT's that ok....or was i suppose to create new
tables......?

the detail tables are created accordingly to your suggestion......i called
them BedQuilt, BedBfill, BedUphFill, BedSpring.....so on.....and these i gave
the fields of the MattressID from the Main table, and FillMaterialID AND it's
primary key field..
so...

BedQuilt tbl
------
BedQfillID----AutoNumber(pk)
MattressID-----Int(fk)
FillMaterialID----Int(fk)

same for the rest of the tables that have Fills and for others like Spring tbl

BedSpring tbl
-------
BedSpringID------AutoNumber(pk)
MattressID-------Int(fk)
SpringID---------Int(fk)----these being from the ORIGINAL spring table

AND SO ON TO THE REST OF THE TABLES
now, again, while i was doing these changes, the data that i was appended
were eliminated !! all the detail tables are empty now. now i have primary
keys.....with numbers....no more text primary keys.........just a reminder, i
still have that big ugly database that i had previously created that contains
the original tables like the big one with repeating fields. Do need to create
Appended Queries to transfer the data into the detail tables, which i could
just use the old appended queries that i previously created....since i kinda
started fresh.....any suggestion to that.....or thoughts? please give me a
light.......
what could be out next move to this?

and again man...thanks a bunch for this........
--
need help


Sprinks said:
Will,

Sorry to confuse you, Will.

2) To answer your 2nd question first, my previous post described multiple
append queries to BedQuilts and BedUph detail tables, and I haven't yet
posted a new solution to this portion of the problem.

The previous strategy was based on the erroneous assumption that you already
had lookup tables Quilts and Uph, consisting of a numeric primary key and a
text-based Description field. I'd assumed, then that the QFill1-4 and Uph1-4
fields in the main table were numeric foreign keys that corresponded to the
numeric primary fields of the Quilts and Uph tables when in fact they are
text fields.

The current realities being more complex than originally thought requires
three processes:

- The strategy of my original post no longer applies. We will have to start
over with the detail tables.

- Since the single fields to remain in the main table are ALSO text fields,
we need to, for each field:

- create a "lookup" table for the field
- eliminate the spelling permutations by assigning similar spellings the
same temp ID
- create master records under this temporary ID in the lookup table
- perform an update query to assign the AutoNumber ID assigned by Access
of the newly created master records to the foreign key ID field

- This process is described in detail in my last post. In addition to this
"spelling permutation phenomenon, the detail table records also have the
"field group" issue to deal with. The combination of these two is
sufficiently complex that I'd rather think about it carefully while you make
the changes on the fields to remain in the main table and their corresponding
controls in the main form. If you're successful, your experience will make
it easier for you to understand what's necessary for the detail tables.

1) It would be possible, as I'd originally suggested, to have separate
lookup tables for the fill materials being assigned to the Quilt and Uph
detail tables, which I thought already existed. But they're not
necessary--they and the Bfill detail represent a single entity--a
Material--and can therefore use a single lookup table that contains ALL
materials, whether it goes into a quilt, uph, or batton field.

Presumably some materials might go into more than one type, but presumably
they won't ALL be used for ALL types. This means you'll probably want to
limit the list of materials in the each detail combo box to only those
materials that are used in that particular detail--quilt materials for the
quilt detail, batton materials for the batton detail, etc. If so, we'll use
another strategy to so limit the combo boxes that still will permit the
simplicity of storing them in a single table.

Let me know when you've successfully made the changes to the fields in the
main table and their corresponding controls on the main form, and we'll move
on.

Sprinks

Will G said:
Hey Sprinks

man you load me up...thanks "to the second power", as i look at this, it
will definitely help getting the foot at the door to database done the right
way for me. i am in the process of doing everything you wrote down, only got
couple of questions.

1. what's going to be the FillMaterials tbl role?
2. in your privious posts, you told me to create appended queries to
transfer data to these new tables i created, now i will be using this tables
yes and do i need to normalize them as well or just those old orginal tbls?

thanks again man.....you are really a source
--
need help


Sprinks said:
Will,

After seeing that some of my assumptions re: your current structure have
proved incorrect, the scope of rendering your application into fully
normalized tables that will be easy to maintain, while not conceptually
difficult, is larger than I first imagined.

The first step is getting your tables "normalized"--that is redesigning them
such that they follow certain rules of relational database design that render
it into one or more hierarchical, normalized "forms. Most developers try to
meet the requirements of 3rd normal form. Access doesn't fully support some
normal forms. I have posted links on the topic at the end of this post.

Inadequacies of Current Design:
--------------------------------------------------------
- Your current design violates first normal form because it contains
repeating groups: Descx, Bfillx, Qfillx, Uphx. Searches, for example, for a
given Quilt fill must pool searches across the QFill1, QFill2, QFill3 &
QFill4 fields.

- Furthermore, since all of these groups, plus the Spring, Pattern, Needle
Label, and Label Description fields are text fields, you have redundant data,
which is likely to be riddled with misspellings, further frustrating search
attempts. If you want to know which models use Spring 7CX, you may have to
search by:

7CX
7 CX
7C-X

- I suspect Label Description is fully defined by the Label field. If so,
the Label Description field is unnecessary.

- I'm not sure of the purpose of the multiple Description fields. It seems
they could either be a single Text or Memo field or belong in a one-to-many
detail table.

Correcting Single Field Design Inadequacies - Overview
---------------------------------------------------------------------------------------
While none of the steps are conceptually difficult, they are sufficiently
complex that I've broken it down into this Overview and more detailed
instructions below. Read the post completely before proceeding.

Major Steps:
- Normalize the tables by creating "lookup" tables that store a description
ONCE, thereby eliminating spelling permutations. In the process, we will use
temporary IDs to denote the equivalence of any spelling permutations that
currently exist.
- Create detail tables that eliminate the field groups. It sounds like you
may have already done this.
- Modify the existing form, and create and embed subforms for the detail
tables.

Resulting Table Designs
--------------------------------------------------------------------------------
The resulting structures will store only the numeric key from the "lookup"
table (called a foreign key) in the main and detail tables. The quotes
around "lookup" means that these are tables that you can use as the RowSource
of a combo box, NOT the to-be-avoided, problematic "lookup field"
functionality provided by Access in the table definition phase. They are
simply separate tables with an AutoNumber or other numeric primary key, and a
text description field.

Since BFillx, QFillx, and Uphx all contain fill materials, a single
FillMaterial lookup table can handle all three.

The resulting structure will look like the following. Choose more
meaningful field and table names as appropriate.

Mattresses (Main Table)
-----------------------------
ID AutoNumber (PK)
ModelNumber Text
SpringID Integer (Foreign Key to Springs)
PatternID Integer (Foreign Key to Patterns)
NeedleID Integer (Foreign Key to Needles)
LabelID Integer (Foreign Key to Labels)

Lookup Tables:

Springs
------------------------------
SpringID AutoNumber (PK)
Spring Text

Patterns
------------------------------
PatternID AutoNumber (PK)
Pattern Text

Needles
------------------------------
NeedleID AutoNumber (PK)
Needle Text

Labels
------------------------------
LabelID AutoNumber (PK)
Label Description

Descriptions *
------------------------------------------
DescriptionID AutoNumber
Description Text

* This might be a single text field in the main table w/no Lookup table
required, or a lookup table and a one-to-many detail table, depending on your
intent.

FillMaterials
------------------------------
FillMaterialID AutoNumber (PK)
FillMaterial Text

DetailTables (all in one-to-many relationship with Mattresses):
(I prefer to name detail tables using the name of the main & lookup tables +
Detail, but name them however you wish)
Note that all contain the MattressID field, by which we will link their
respective subforms to the main table.

MattressBattonDetail
-------------------------------------
MattressBattonID AutoNumber (PK)
MattressID Integer (FK to Mattresses)
FillMaterialID Integer (FK to FillMaterials)

MattressQuiltDetail
------------------------------
MattressQuiltID AutoNumber (PK)
MattressID Integer (FK to Mattresses)
FillMaterialID Integer (FK to FillMaterials)

MattressUphDetail
------------------------------
MattressUphDetailID AutoNumber (PK)
MattressID Integer (FK to Mattresses)
FillMaterialID Integer (FK to FillMaterials)

MattressDescriptionDetail
-----------------------------------------
MattressDescriptionDetailID AutoNumber (PK)
MattressID Integer (FK to Mattresses)
DescriptionID Integer (FK to Descriptions)


Correcting Data - Detail
---------------------------------------------------------------------
- Create a backup of your database.
- Modify the design of the Mattresses table, adding the following integer
fields: SpringID, NeedleID, PatternID, TempSpringID, TempNeedleID,
TempPatternID.
- Sort the Mattress table by Spring, and look for any spelling
permutations. Assign the same integer value to the TempSpringID field for
any equivalent springs, and a unique integer value to each unique spring.
For example, you might end up with something like the following:

Spring TempSpringID
-----------------------------------------
XC102 1
XC 102 1 (spelling permutation)
XC103 2
XC104 3
Xc104 3 (spelling permutation)

- Create the Spring table. Include an extra integer field to hold the
TempSpringID's just assigned.
- Review the Materials table. For each unique TempSpringID, enter this
value and a single "master" description for it into the Springs table.
Access will automatically assign the AutoNumber SpringID. You now have your
master "lookup" records.
- Create a query consisting of the Mattresses and Springs tables. Link them
by the TempSpringID, but delete the link Access assigns on SpringID. Drag
the SpringID of the Mattresses table to the query grid.
- Choose Query, Update Query from the menu.
- In the Update To: row, type Springs.SpringID. Access will place brackets
around the table and field names.
- Choose View, SQL to see the SQL. It should look like the following,
different ONLY by any different field and table names you choose:

UPDATE Mattresses INNER JOIN Springs ON Mattresses.TempSpringID =
Springs.TempSpringID SET Mattresses.SpringID = [Springs].[SpringID];

- If all looks good, press the Exclamation icon to run the update query.
- Review the Mattresses and Springs tables side-by-side. Whereever the
TempSpringID field matches from the Mattresses to the Springs table, the
SpringID should also match. If it does, you can delete the TempSpringID
field from both tables.

Modifying the Main Form
---------------------------------------------------------------------------------------------
- To display it correctly on your main form, load it in design view. Enable
the combo box wizard by selecting View, Toolbox, and making sure the button
with the wand and stars is depressed. Now add a combo box, preferably next
to the existing textbox bound to the text-based Spring field. Tell the
wizard to look up values from the Springs table. Select both fields, and
Hide Key Field (Recommended). This will display the text field in the combo
box but store the numeric key field. At the end, tell the wizard to store
the selection in the SpringID field. Save the form and return to Normal view.
- Scroll through the existing records. The value in the text Spring field
should correspond (less spelling permutations) with the value displayed in
the combo box. If this is verified, you can delete the textbox from the
form, and delete the text Spring field from the Mattresses table.
- You've now normalized the Springs field. Repeat the data correction and
form modification processes for the other main form fields--Needle, Pattern,
and Label.

When you've got these all working on the main form, repost. I'll think
carefully about how to handle the field groups in the meantime, it's a little
more complex now, since the fields are simply text.

Hope that helps.
Sprinks


Normalization Links:
ACC: Database Normalization Basics
http://support.microsoft.com/?id=100139
http://support.microsoft.com/?id=209534
http://support.microsoft.com/?id=283878
 
S

Sprinks

Will,

I'm unclear on what you've created so far. It might be easier if you send
me both the modified and the original databases, and I'll clean it up and
return it to you.

k.sprinkelNOSPAM @ comcast.net

Remove NOSPAM from above.

Sprinks
 
W

Will G

did you get the DB ..sprinks.....what do you think....it needs a lot of
work... i know....thanks for helping man.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top