Chapter 5. Linking Tables with Relationships

The tables you’ve seen so far lead lonely, independent lives. You don’t find this isolation with real-world databases. Real databases have their tables linked together in a web of relationships.

Suppose you set out to build a database that can manage the sales of your custom beadwork shop. The first ingredient’s simple enough—a Products table that lists your merchandise—but before long you’ll need to pull together a lot more information. The wares in your Products table are sold in your Orders table. The goods in your Orders table are mailed out and recorded in a Shipments table. The people in your Customers table are billed in your Invoices table. All these tables—Products, Orders, Shipments, Customers, and Invoices—have bits of related information. As a result, if you want to find out the answer to a common question (like, “How much does Jane Malone owe?” or “How many beaded wigs did we sell last week?”), you’ll need to consult several tables.

Based on what you’ve learned so far, you already know enough to nail down the design for a database like this one. But relationships introduce the possibility of inconsistent information. And once a discrepancy creeps in, you’ll never trust your database the same way again.

In this chapter, you’ll learn how to explicitly define the relationships between tables. This process lets you prevent common errors, like data in different tables that doesn’t sync up. It also gives you a powerful tool for browsing through related information in several tables.

Relationship Basics

One of any database’s key goals is to break information down into distinct, manageable pieces. In a well-designed database, you’ll end up with many tables. Although each table records something different, you’ll often need to travel from one table to another to get all the information you want.

To better understand relationships (of the non-romantic kind, anyway), consider an example. The following section demonstrates two ways to add information to the bobblehead database: one that risks redundant data, and one that avoids the problem by properly using a relationship.

Redundant Data vs. Related Data

Think back to the Dolls table you created in Chapter 1 to store a list of bobblehead dolls. One of the Dolls table’s pieces of information is the Manufacturer field, which lists the name of the company that created each doll. Although this seems like a simple-enough detail, it turns out that to properly assess the value of a bobblehead, you need to know a fair bit more about the manufacturing process. You may want to know things like where the manufacturing company’s located, how long it’s been in business, and if it’s had to fight off lawsuits from angry customers.

If you’re feeling lazy, you could add all this information to the Dolls table, like so (the shaded columns are the new ones):

Table 5-1. 

ID

Character

Manufacturer

Manufacturer-Location

Manufacturer-OpeningYear

Manufacturer-Lawsuits

PurchasePrice

342

Yoda

MagicPlastic

China

2003

No

$8.99

Your first reaction to this table is probably to worry about the clutter of all these fields. But don’t panic—in the real world, tables must include all the important details, so they often grow quite wide. (That’s rule #3 of data design, from Section 2.5.4.) So don’t let the clutter bother you. You can use techniques like column hiding (Section 3.1.4) to filter out the fields that don’t interest you.

Although column clutter isn’t a problem, another issue lurks under the surface in this example—redundant data. A well-designed table should list only one type of thing. This version of the Dolls table breaks that rule by combining information about the bobblehead and the bobblehead manufacturer.

This situation seems innocent enough, but if you add a few more rows, things don’t look as pretty:

Table 5-2. 

ID

Character

Manufacturer

Manufacturer-Location

Manufacturer-OpeningYear

Manufacturer-Lawsuits

PurchasePrice

342

Yoda

MagicPlastic

China

2003

No

$8.99

343

Dick Cheney

Rebobblicans

Taiwan

2005

No

$28.75

344

Tiger Woods

MagicPlastic

China

2003

No

$2.99

Once you have two bobbleheads that were made by the same company (in this case, MagicPlastic), you’ve introduced duplicate data, the curse of all bad data-bases. (You’ll recognize this as a violation of rule #4 of good database design, from Section 2.5.4.) The potential problems are endless:

  • If MagicPlastic moves its plants from China to South Korea, you’ll need to update a whole batch of bobblehead records. If you were using two tables with related data (as you’ll see next), you’d have just one record to contend with.

  • It’s all too easy to update the manufacturer information in one bobblehead record but miss it in another. If you make this mistake, you’ll wind up with inconsistent data in your table, which is even worse than duplicate data. Essentially, your manufacturer information will become worthless because you won’t know which record has the correct details, so you won’t be able to trust anything.

  • If you want to track more manufacturer-related information (like a contact number) in your database, you’ll have to update your Dolls table and edit every single record. Your family may not see you for several few weeks.

  • If you want to get information about manufacturers (but not dolls), you’re out of luck. For example, you can’t print out a list of all the bobblehead manufacturers in China (at least not easily).

It’s easy to understand the problem. By trying to cram too many details into one spot, this table fuses together information that would best be kept in two separate tables. To fix this design, you need to create two tables that use related data. For example, you could create a Dolls table like this:

Table 5-3. 

ID

Character

Manufacturer

PurchasePrice

342

Yoda

MagicPlastic

$8.99

343

Dick Cheney

Rebobblicans

$28.75

344

Tiger Woods

MagicPlastic

$2.99

And a separate Manufacturers table with the manufacturer-specific details:

Table 5-4. 

ID

Manufacturer

Location

OpeningYear

Lawsuits

1

MagicPlastic

China

2003

No

2

Rebobblicans

Taiwan

2005

No

This design gives you the flexibility to work with both types of information (dolls and manufacturers) separately. It also removes the risk of duplication. The savings are small in this simple example, but in a table with hundreds or thousands of bobblehead dolls (and far fewer manufacturers), the difference is dramatic.

Now, if MagicPlastic moves to South Korea, you need to update the Location field for only one record, rather than many instances in an overloaded Dolls table. You’ll also have an easier time building queries (Chapter 6) that combine the information in neat and useful ways. (For example, you could find out how much you’ve spent on all your MagicPlastic dolls and compare that with the amounts you’ve spent for dolls made by other manufacturers.)

Note

Access includes a tool that attempts to spot duplicate data in a table and help you pull the fields apart into related tables. (To try it out, choose Database Tools → Analyze → Analyze Table.) Although it’s a good idea in theory, this tool really isn’t that useful. You’ll do a much better job of spotting duplicate data and creating well-designed tables from the start if you understand the duplicate-data problem yourself.

Matching Fields: The Relationship Link

This bobblehead database shows you an example of a relationship. The telltale sign of a relationship is two tables with matching fields. In this case, the tip-off’s the Manufacturer field, which exists in both the Dolls table and the Manufacturers table.

Note

In this example, the fields that link the two tables have the same name in both tables: Manufacturer. However, you don’t have to do it this way. You can give these fields different names, so long as they have the same data type.

Using these linked fields, you can start with a record in one table and look up related information in the other. Here’s how it works:

  • Starting at the Dolls table, pick a doll that interests you (let’s say Yoda). You can find out more information about the manufacturer of the Yoda doll by looking up “MagicPlastic” in the Manufacturers table.

  • Starting at the Manufacturers table, pick a manufacturer (say, Rebobblicans). You can now search for all the products made by that manufacturer by searching for “Rebobblicans” in the Dolls table.

In other words, a relationship gives you the flexibility to ask more questions about your data, and get better answers.

Linking with the ID Column

In the previous example, the Dolls and Manufacturers tables are linked through the Manufacturer field, which stores the name of the manufacturing company. This seems like a reasonable design—until you spend a couple of minutes thinking about what might go wrong. And databases experts are known for spending entire weeks contemplating inevitable disasters.

Here are two headaches that just may lie in store:

  • Two manufacturers have the same company name. So how do you tell which one made a doll?

  • A manufacturer gets bought out by another company and changes its name. All of a sudden, there’s a long list of records to change in the Dolls table.

You might recognize these problems, because they’re similar to the challenges you faced when you tackled primary keys (Section 2.4). As you learned, it’s difficult to find information that’s guaranteed to be unique and unchanging. Rather than risk problems, you’re better off just relying instead on an AutoNumber field, which stores an Access-generated ID number.

Interestingly enough, you use the same solution when linking tables. To refer to a record in another table, you shouldn’t use just any piece of information—instead, you should use the unique ID number that points to the right record. Here’s a redesigned Dolls table that gets it right by changing the Manufacturer field to ManufacturerID:

Table 5-5. 

ID

Character

ManufacturerID

Purchase-Price

342

Yoda

1

$8.99

343

Dick Cheney

2

$28.75

344

Tiger Woods

1

$2.99

If you take a look back at the Manufacturers table (Section 5.1.1), then you can quickly find out that the manufacturer with the ID value 1 is MagicPlastic.

This design’s the universal standard for databases. However, it does have two obvious drawbacks:

  • The person adding records to the Dolls table probably doesn’t know the ID of each manufacturer.

  • When you look at the Dolls table, you can’t tell what manufacturer created each doll.

To solve both these problems, use a lookup. Lookups show the corresponding manufacturer information in the Dolls table, and they also let you choose from a list of manufacturers when you add a record or edit the ManufacturerID field. (You saw how to use lookups with value lists in Section 4.4.1. You’ll learn how to use lookups to bring together related tables, like Dolls and Manufacturers, in Section 5.2.5.)

Tip

For even more power, you can use a join query (Section 6.3). A join query lets you fill in all the manufacturer details alongside the doll information so you can view them side by side.

The Parent-Child Relationship

No, this isn’t a detour into feel-good Dr. Phil psychology. Database nerds use the labels parent and child to identify the two tables in a relationship, and keep track of which one’s which.

Here’s the analogy. As you no doubt know, in the real world a parent can have any number of children. However, a child has exactly one set of parents. The same rule works for databases. In the bobblehead database, a single manufacturer record can be linked to any number of doll records. However, each doll record refers to a single manufacturer. So according to the database world’s strange sociology, Manufacturers is a parent table and Dolls is a child table. They’re linked by a parent-child relationship.

Tip

Don’t think too hard about the parent-child analogy. It’s not a perfect match with biological reality. For example, in the bobblehead database, you may create a manufacturer that doesn’t link to any dolls (in other words, a parent with no children). You still call that record a parent record, because it’s part of the parent table.

It’s important to realize that you can’t swap the parent and child tables around without changing your relationship. It’s incorrect to suggest that Dolls is the parent table and Manufacturers is the child table. You can see that such a suggestion would break the parent-child analogy: a single doll can’t have more than one manufacturer, and a manufacturer isn’t limited to creating a single doll. In order to prevent problems and all-around fuzzy thinking, you need to know exactly which table’s the parent and which one’s the child.

Tip

If you have trouble identifying which table’s the parent, there’s a simple rule to steer you right. The child table always contains a piece of identifying information from the parent table. In the bobblehead database, the Dolls table contains the ManufacturerID field. On the other hand, the Manufacturer table doesn’t have any doll information.

If you have database-savvy friends, you’ll hear the term parent-child relationship quite a bit. The same relationship’s also called a one-to-many relationship (where one is the parent and many represents the children, because a single parent record in one table can link to several child records in the other). It’s the most common relationship, but not the only one—you’ll learn about two other types in Section 5.3 and Section 5.3.2.

Note

Relationships are so common in modern-day databases that software like Access is often described as a relational database management system (RDBMS). A database without relationships is about as common as a beachfront resort in Ohio.

Using a Relationship

The relationship between Dolls and Manufacturers is implicit, which is a fancy way of saying that you know the relationship exists, but Access doesn’t. Database pros aren’t satisfied with this arrangement. Instead, they almost always define their relationships explicitly. When you create an explicit relationship, you clearly tell Access how two tables are related. Access then stores the information about that relation-ship in the database file.

You have good reasons to bring your relationships out into the open. Once Access knows about a relationship, it can enforce better error checking. It can also provide handy features for browsing related data and editing linked fields. You’ll see all these techniques in the following sections. But first, you need to learn how to define a relationship.

Defining a Relationship

You can try out the following steps with the Bobblehead.accdb file, which is included with the online examples for this chapter. It contains the Dolls and Manufacturers tables, in their original form (with no relationships defined). The BobbleheadRelationships.accdb database file shows the final product: two tables with the right relationship.

Here’s what you need to do to set up a relationship:

  1. Every relationship links two fields, each in a different table. Your first step is to identify the field you need to use in the parent table.

    In a well-designed database, you use the primary-key field (Section 2.4) in the parent table. For example, in the Manufacturers table, you use the ID column, which uniquely identifies each manufacturer.

  2. Open the child table in Design view. (The quickest way is to right-click it in the navigation pane, and then choose Design View.)

    In this example, the child table is Dolls.

  3. Create the field you need in the child table, if it’s not there already.

    Each child record creates a link by storing a piece of information that points to a record in the parent table. You need to add a new field to store this information, as shown in Figure 5-1.

    Note

    The fields that you link in the parent and child tables must have consistent data types. However, there’s one minor wrinkle. If the parent field uses the AutoNumber data type, then the child field should use the Number data type instead (with a Field Size of Long Integer). Behind the scenes, an AutoNumber and a Long Integer actually store the same numeric information. But the AutoNumber data type tells Access to fill in the field with a new, automatically generated value whenever you create a record. You obviously don’t want this behavior for the ManufacturerID field in the Dolls table.

    In the Dolls table, you need a field that identifies the manufacturer for that doll. It makes sense to add a new field named ManufacturerID. Set the data type to Number, and the Field Size to Long Integer, so it matches the ID field in the Manufacturers table. After you add this field, you need to fill it with the right information. (Each doll record should have the ID number of the corresponding manufacturer.)

    Figure 5-1. In the Dolls table, you need a field that identifies the manufacturer for that doll. It makes sense to add a new field named ManufacturerID. Set the data type to Number, and the Field Size to Long Integer, so it matches the ID field in the Manufacturers table. After you add this field, you need to fill it with the right information. (Each doll record should have the ID number of the corresponding manufacturer.)

  4. Close both tables.

    Access prompts you to save your changes. Your tables are now relationship-ready.

  5. Choose Database Tools → Show/Hide → Relationships.

    Access opens a new tab named Relationships. This tab’s a dedicated window where you can define the relationships between all the tables in your database. In this example, you’ll create a just a single relationship, but you can use the Relationships tab to define many more.

    Before Access lets you get to work in the Relationships tab, it pops up a Show Table dialog box asking what tables you want to work with (see Figure 5-2).

    You can add as many tables as you want to the Relationships tab. Be careful not to add the same table twice (it’s unnecessary and confusing).

    Figure 5-2. You can add as many tables as you want to the Relationships tab. Be careful not to add the same table twice (it’s unnecessary and confusing).

  6. Add both the parent table and child table to your work area.

    It doesn’t matter which one you choose first. To add a table, select it in the list, and then click Add (or just double-click it).

    Access represents each table in the Relationships tab by a small box that lists all the table fields. If relationships are already defined between these tables, they’ll appear as connecting lines.

  7. Click Close.

    You can now arrange the tables in the Relationships tab (see Figure 5-3). The Relationships tab shows a database diagram—it’s the canvas where you add relationships by “drawing” them on.

    You can drag the tables you’ve added to any place in the window. If you have a database that’s thick with relationships, this ability lets you arrange them so that the relationships are clearly visible. To remove a table from the diagram, right-click it, and then choose Hide Table. To add another table, right-click the blank space, and then choose Show Table to pop up the Show Table dialog box.

    Figure 5-3. You can drag the tables you’ve added to any place in the window. If you have a database that’s thick with relationships, this ability lets you arrange them so that the relationships are clearly visible. To remove a table from the diagram, right-click it, and then choose Hide Table. To add another table, right-click the blank space, and then choose Show Table to pop up the Show Table dialog box.

    Tip

    Access gives you a shortcut if you need to rework the design of a table that’s open in the Relation-ships tab. Just right-click the table box, and choose Design Table.

  8. To define your relationship, find the field you’re using in the child table. Drag this field to the field you want to link it to in the parent table.

    In this case, you’re linking the ManufacturerID field in the Dolls table (the child) to the ID field in the Manufacturers table (the parent). So drag ManufacturerID (in the Dolls box) over to ID (in the Manufacturers box).

    Tip

    You can drag the other way, too (from the child to the parent). Either way, Access creates the same relationship.

    When you release the mouse button, the Edit Relationships dialog box appears (see Figure 5-4).

    Access is clever enough to correctly identify the parent table (shown in the Table/Query box) and the child table (shown in the Related Table/Query box) when you connect two fields. Access identifies the field in the parent table because it has a primary key (Section 2.4) or a unique index (Section 4.1.3). If something isn’t quite right in the Edit Relationships dialog box, then you can swap the tables or change the fields you’re using to create the relationship before continuing.

    Figure 5-4. Access is clever enough to correctly identify the parent table (shown in the Table/Query box) and the child table (shown in the Related Table/Query box) when you connect two fields. Access identifies the field in the parent table because it has a primary key (Section 2.4) or a unique index (Section 4.1.3). If something isn’t quite right in the Edit Relationships dialog box, then you can swap the tables or change the fields you’re using to create the relationship before continuing.

  9. If you want to prevent potential errors, then put a checkmark in the Enforce Referential Integrity option. (It’s always a good idea.)

    This setting turns on enhanced error checking, which prevents people from making a change that violates the rules of a relationship (like creating a doll that points to a nonexistent manufacturer). You’ll learn more about referential integrity and the two settings for cascading changes in Section 5.2.3. For now, it’s best to switch on the Enforce Referential Integrity option and leave the others unchecked.

  10. Click Create.

    This action creates the relationship that links the two tables. It appears in the diagram as a line (Figure 5-5).

    Tip

    If you chose Enforce Referential Integrity (in step 9), Access checks to make sure any existing data in the table follows the relationship rules. If it finds some that doesn’t, then it alerts you about the problem and refuses to continue. At this point, the best strategy’s to create the relationship without referential integrity, correct the invalid data, and then edit the relationship later to turn on referential integrity.

  11. Close the Relationships tab. (You can click the X in the tab’s top-right corner, or choose Relationship Tools | Design → Relationships → Close.)

    Access asks whether or not you want to save the Relationships tab’s layout. Access is really asking you whether you want to save the relationship diagram you’ve created. No matter what you choose, the relationship remains in the database, and you can use it in the same way. The only difference is whether you’ll be able to quickly review or edit the relationship in the Relationships tab.

    Access uses a line to connect related fields in the Relationships tab. The tiny 1 and infinity (∞) symbols let you distinguish between the “one” and the “many” side in this one-to-many relationship. To edit the relationship, double-click the line. To remove it altogether, right-click the line, and then choose Delete.

    Figure 5-5. Access uses a line to connect related fields in the Relationships tab. The tiny 1 and infinity (∞) symbols let you distinguish between the “one” and the “many” side in this one-to-many relationship. To edit the relationship, double-click the line. To remove it altogether, right-click the line, and then choose Delete.

    If you choose to keep the relationship diagram, the next time you switch to the Relationships tab (by choosing Database Tools → Show/Hide → Relationships), you see the same arrangement of tables. This feature’s handy.

    If you choose not to keep the relationship diagram, it’s up to you to recreate the diagram next time by adding the tables you want to see and arranging them in the window (although you won’t need to redefine the relationships). This process takes a little more work.

Tip

Many database pros choose to save their database diagram, because they want to see all their relationships at once in the Relationships tab, just the way they left them. However, real-world databases often end up with a tangled web of relationships. In this situation, you may choose not to save a complete diagram so you can focus on just a few tables at once.

Editing Relationships

The next time you want to change or add relationships, you’ll follow the same path to get to the Relationship window (choose Database Tools → Show/Hide → Relationships).

If you choose to save a relationship diagram (in step 11 in the previous section), the tables you added appear automatically, just as you left them. If you want to work with tables that aren’t in any relationships yet, you can add them to the diagram by right-clicking anywhere in the blank area, and then choosing Show Table.

If you chose not to save your relationship diagram, you can use a few shortcuts to put your tables back on display:

  • Drag your tables right from the navigation pane, and then drop them in the Relationships tab.

  • Choose Relationship Tools | Design → Relationships → All Relationships to show all the tables that are involved in any relationships you’ve created previously.

  • Add a table to the diagram, select it, and then choose Relationship Tools | Design → Relationships → Direct Relationships to show the tables that are linked to that table.

As you already know, you can use the Relationships tab to create new relationships. You can also edit the relationships you’ve already created. To do so, right-click the line that represents the relationship, and then choose Edit Relationship. (This takes some nimble finger-clicking. If you don’t see the Edit Relationships option in the menu, you’ve just missed the line.) To remove a relationship, right-click the relationship line, and then choose Delete.

Note

Usually, you edit a relationship to change the options for referential integrity, which you’ll learn about in the next section.

Referential Integrity

Now that you’ve gone to the work of defining your relationship, it’s time to see what benefits you’ve earned. As in the real world, relationships impose certain restrictions. In the database world, these rules are called referential integrity. Taken together, they ensure that related data’s always consistent.

Note

Referential integrity comes into action only if you switched on the Enforce Referential Integrity option (Section 5.2.1) for your relationship. Without this detail, you’re free to run rampant and enter inconsistent information.

In the bobblehead example, referential integrity requires that every manufacturer you refer to in the Dolls table must exist in the Manufacturer table. In other words, there can never be a bobblehead record that points to a nonexistent manufacturer. That sort of error could throw the hardiest database software out of whack.

To enforce this rule, Access disallows the following three actions:

  • Adding a bobblehead that points to a nonexistent manufacturer.

  • Deleting a manufacturer that’s linked to one or more bobblehead records. (Once this record’s removed, you’re left with a bobblehead that points to a nonexistent manufacturer.)

  • Updating a manufacturer by changing its ID number, so that it no longer matches the manufacturer ID in the linked bobblehead records. (This updating isn’t a problem if you use an AutoNumber field, because you can’t change AutoNumber values once you’ve created the record.)

Note

If you need to add a new doll made by a new manufacturer, you must add the manufacturer record first, and then add the doll record. There’s no problem if you add manufacturer records that don’t have corresponding doll records—after all, it’s perfectly reasonable to list a manufacturer even if you don’t have any of the dolls they’ve made.

Along with these restrictions, Access also won’t let you remove a table if it’s in a relationship. You need to delete the relationship first (using the Relationships window) and then remove the table.

Blank values for unlinked records

It’s important to realize that there’s one operation you can perform that doesn’t violate referential integrity: creating a bobblehead that doesn’t point to any manufacturer. You do this by leaving the ManufacturerID field blank (which database nerds refer to as a null value). The only reason you’ll leave the ManufacturerID field blank is if the manufacturer record doesn’t exist in your database, or if the information doesn’t apply. Perhaps the bobblehead wasn’t created by any manufacturer but was created by an advanced space-faring alien race and left on this planet for you to discover.

If this blank-value back door makes you nervous, then you can stop it. Just set the Required field property (Section 4.1.1) on the ManufacturerID field in the Dolls table. This setting ensures that every bobblehead in your Dolls table has legitimate manufacturer information. This technique’s important when related information isn’t optional. A sales company shouldn’t be able to place an order or create an invoice without linking to the customer who made the order.

Cascading deletes

The rules of referential integrity stop you cold if you try to delete a parent record (like a manufacturer) that other child records (like dolls) link to. However, there’s another option—and it’s much more drastic. You can choose to blow away all related child records whenever you delete a parent. For example, this would allow you to remove a manufacturer and wipe out all the dolls that were produced by that manufacturer.

Warning

Cascading deletes are risky. It’s all too easy to wipe out way more records that you intend, and if you do there’s no going back. Even worse, the Undo feature can’t help you reverse this change. So proceed with caution.

To turn on this option, you need to switch on the Cascade Delete Related Records setting when you create your relationship (Figure 5-4). You can also modify the relationship later on to add this setting.

Once you’ve switched this option on, you can try it out by deleting a manufacturer, as shown in Figure 5-6.

In this example, the Dolls-Manufacturers relationship uses the Cascade Delete Related Records setting. When you delete a manufacturer, Access warns you that you’ll actually end up deleting every linked doll record, for a total of nine records.

Figure 5-6. In this example, the Dolls-Manufacturers relationship uses the Cascade Delete Related Records setting. When you delete a manufacturer, Access warns you that you’ll actually end up deleting every linked doll record, for a total of nine records.

Cascading updates

Access also provides a setting for cascading updates. If you switch on this feature (by going to the Edit Relationships dialog box, and then choosing Cascade Update Related Fields), Access copies any change you make to the linked field in the parent record to all the children.

With the bobblehead database, a cascading update lets you change the ID of one of your manufacturers. When you change the ID, Access automatically inserts the new value into the ManufacturerID field of every linked record in the Dolls table. Without cascading updates, you can’t change a manufacturer’s ID if there are linked doll records.

Cascading updates are safer than cascading deletes, but you rarely need them. That’s because if you’re following the rules of good database design, you’re linking based on an AutoNumber ID column (Section 2.3.9). Access doesn’t let you edit an AutoNumber value, and you don’t ever need to. (Remember, an AutoNumber simply identifies a record uniquely, and it doesn’t correspond to anything in the real world.)

On the other hand, cascading updates come in handy if you’re working with a table that hasn’t been designed to use AutoNumber values for links. If the Dolls and Manufacturers table were linked based on the manufacturer name, then you need cascading updates—it makes sure that child records are synchronized whenever a manufacturer name’s changed. Cascading updates are just as useful if you have linked records based on Social Security numbers, part numbers, serial numbers, or other codes that aren’t generated automatically and are subject to change.

Navigating a Relationship

Relationships aren’t just useful for catching mistakes. Relationships also make it easier for you to browse through related data. In Chapter 6, you’ll learn to create search routines that pull together information from related tables (Section 6.3). But even without this technique, Access provides some serious relationship mojo in the datasheet.

Here’s how it works. If you’re looking at a parent table in the datasheet, then you can find the related child records for any parent record by clicking the plus box that’s just at the left of the row (Figure 5-7).

Curious to find out what dolls you have from MagicPlastic? Just click the plus box (circled).

Figure 5-7. Curious to find out what dolls you have from MagicPlastic? Just click the plus box (circled).

This drops a subdatasheet into view, which shows just the related records (Figure 5-8). You can use the subdatasheet to edit the doll records here in exactly the same way as you would in the full Dolls datasheet. You can even add new records.

The subdatasheet’s really a filtered version of the ordinary Dolls datasheet. It shows only the records that are linked to the manufacturer you chose. The subdatasheet has all the same view settings (like font, colors, column order) as the datasheet for the related table.

Figure 5-8. The subdatasheet’s really a filtered version of the ordinary Dolls datasheet. It shows only the records that are linked to the manufacturer you chose. The subdatasheet has all the same view settings (like font, colors, column order) as the datasheet for the related table.

Note

You can open as many subdatasheets as you want at the same time. The only limitation’s that the records in a subdatasheet don’t show up if you print the datasheet (Section 3.4).

A parent table may be related to more than one child table. In this case, Access gives you a choice of what table you want to use when you click the plus box. Imagine you’ve created a Customers table that’s linked to a child table of customer orders (Orders), and a child table of billing information (Invoices). When you click the plus box, Access doesn’t know which table to choose, so it asks you (see Figure 5-9).

When Access doesn’t know which table to use as a subdatasheet, it lets you pick from a list of all your tables. In this case, only two choices make sense. Choose Orders to see the customer’s orders, or Invoices to see the customer’s invoices. When you select the appropriate table in the list, Access automatically fills in the linked fields in the boxes at the bottom of the window. You can then click OK to continue.

Figure 5-9. When Access doesn’t know which table to use as a subdatasheet, it lets you pick from a list of all your tables. In this case, only two choices make sense. Choose Orders to see the customer’s orders, or Invoices to see the customer’s invoices. When you select the appropriate table in the list, Access automatically fills in the linked fields in the boxes at the bottom of the window. You can then click OK to continue.

Note

You have to choose the subdatasheet you want to use only once. Access remembers your setting and always uses the same subdatasheet from that point on. If you change your mind later on, you’ll need to tweak the table settings, as described in the box “Changing Subdatasheet Settings” in Section 5.2.5.

As you create more elaborate databases, you’ll find that your tables are linked together in a chain of relationships. One parent table might be linked to a child table, which is itself the parent of another table, and so on. This complexity doesn’t faze Access—it lets you drill down through all the relationships (see Figure 5-10).

There are two relationships at work here. Customers is the parent of Orders (which lists all the orders a customer’s placed). Orders is the parent of OrderDetails (which lists the individual items in each order). By digging through the levels, you can see what each customer bought.

Figure 5-10. There are two relationships at work here. Customers is the parent of Orders (which lists all the orders a customer’s placed). Orders is the parent of OrderDetails (which lists the individual items in each order). By digging through the levels, you can see what each customer bought.

Lookups with Related Tables

So far, you’ve seen how relationships make it easier to review and edit your records. But what about when you add your records in the first place? Relationships are usually based on an unhelpful AutoNumber value. When you create a new doll, you probably won’t know that 3408 stands for Bobelle House O’ Dolls. Access stops you from entering a manufacturer ID that isn’t linked to anyone at all, but it doesn’t help you choose the ID value you want.

Fortunately, Access has a technique to help you out. In the previous chapter, you learned about lookups (Section 4.4.1), a feature that provides you with a list of possible values for a column. When creating a lookup, you can supply a list of fixed values, or you can pull values from another table. You could create a lookup for the ManufacturerID field in the Dolls table that uses a list of ID values drawn from the Manufacturers table. This type of lookup helps a bit—it gives you a list of all the possible values you can use—but it still doesn’t solve the central problem. Namely, the befuddled people using your database won’t have a clue what ID belongs to what manufacturer. You still need a way to show the manufacturer name in the lookup list.

Happily, lookup lists provide just this feature. The trick’s to create a lookup that has more than one column. One column holds the information (in this case, the manufacturer name) that you want to display to the person using the database. The other column has the data you want to use when a value’s picked (in this case, the manufacturer ID).

Note

Access is a bit quirky when it comes to lookups. It expects you to add the lookup, and then the relationship. (In fact, when you set up a lookup that uses a table, Access creates a relationship automatically.) So if you’ve been following through with the examples on your own, then you’ll need to delete the relationship between the Dolls and Manufacturers tables (as described in Section 5.2.3) before you go any further.

The following steps show how you can create a lookup list that links the Dolls and Manufactures tables:

  1. Open the child table in Design view.

    In this example, it’s the Dolls table.

  2. Select the field that links to the parent table, and, in the Data Type column, choose the Lookup Wizard option.

    In this example, the field you want is ManufacturerID.

  3. Choose “I want the lookup column to look up the values in a table or query” and then click Next.

    The next step shows a list of all the tables in your database, except the current table.

  4. Choose the parent table, and then click Next.

    In this case, you’re after the Manufacturers table. Once you select it and move to the next step, you’ll see a list of all the fields in the table.

  5. Add the field you use for the link and another more descriptive field to the list of Selected Fields (Figure 5-11). Click Next to continue.

    In this case, you need to add the ID field and the Manufacturer field.

    The secret to a good lookup is getting two pieces of information: the primary key (in this case, the ID field) and a more descriptive value (in this case, the manufacturer’s name). The ID field’s the piece of information you need to store in the doll record, while the Manufacturer field’s the value you’ll show in the lookup list to make it easier to choose the right manufacturer.

    Figure 5-11. The secret to a good lookup is getting two pieces of information: the primary key (in this case, the ID field) and a more descriptive value (in this case, the manufacturer’s name). The ID field’s the piece of information you need to store in the doll record, while the Manufacturer field’s the value you’ll show in the lookup list to make it easier to choose the right manufacturer.

    Tip

    In some cases, you might want to use more than one field with descriptive information. For example, you might grab both a FirstName and LastName field from a FamilyRelatives table. But don’t add too much information, or the lookup list will become really wide in order to fit it all in. This looks a bit bizarre.

  6. Choose a field to use for sorting the lookup list (Figure 5-12), and then click Next.

    In this example, the Manufacturer field’s the best choice to sort the list.

    It’s important to sort the lookup list, so that the person using it can find the right item quickly.

    Figure 5-12. It’s important to sort the lookup list, so that the person using it can find the right item quickly.

  7. The next step shows a preview of your lookup list (Figure 5-13). Make sure the “Hide key column” option’s selected, and then click Next.

    Although the primary-key field has the value that links the two tables together, it doesn’t mean much to the person using the database. The other, descriptive field’s more important.

    Here, the lookup list shows the manufacturer name (the Manufacturer field) and hides the manufacturer ID (the ID field).

    Figure 5-13. Here, the lookup list shows the manufacturer name (the Manufacturer field) and hides the manufacturer ID (the ID field).

  8. Choose a name for the lookup column.

    Usually, it’s clearest if you keep the name of the field that uses the lookup (in this case, ManufacturerID).

    The final step also gives you an option named Allow Multiple Values. If you check this, then the lookup list shows a checkbox next to each item, so that you can pick several at once. (In this example, you can create a doll that has more than one manufacturer.) You’ll learn more about the Allow Multiple Values option in Section 5.3.2.2.

  9. Click Finish.

    Now, Access creates the lookup for the field and prompts you to save the table. Once you do, Access creates a relationship between the two tables you’ve linked with your lookup column. Here, Access creates a parent-child relationship between Manufacturers and Dolls, just as you did yourself in Section 5.2.1.

Note

The relationships that Access creates don’t enforce referential integrity, because Access doesn’t know if your records can live up to that strict standard. You can have a doll that points to a nonexistent manufacturer. If this possibility seems dangerously lax, you can edit your relationship using the Relation-ships tab (as described in Section 5.2.2). Begin by adding both the Dolls and the Manufacturers table to the relationships diagram. Then, right-click the relationship line in between, and then choose Edit Relation-ship. Finally, switch on the Enforce Referential Integrity checkbox, and then click OK.

Now, if you switch to the datasheet view of the Dolls table, you can use your lookup when you’re editing or adding records (Figure 5-14).

Even though the Dolls table stores an ID value in the ManufacturerID field behind the scenes, that’s not how it appears on your datasheet. Instead, you see the related manufacturer name (both onscreen and in any printouts you make). Even better, if you need to add a new record or change the manufacturer that’s assigned to an existing one, then you can pick the manufacturer from the list by name.

Figure 5-14. Even though the Dolls table stores an ID value in the ManufacturerID field behind the scenes, that’s not how it appears on your datasheet. Instead, you see the related manufacturer name (both onscreen and in any printouts you make). Even better, if you need to add a new record or change the manufacturer that’s assigned to an existing one, then you can pick the manufacturer from the list by name.

More Exotic Relationships

As you learned in Section 5.2, a one-to-many (a.k.a. parent-child) relationship that links a single record in one table to zero, one, or more records in another table is the most common relationship. A single manufacturer could be linked to one bobblehead, several bobbleheads, or no bobbleheads at all.

Along with one-to-many relationships, there are two subtly different types of relationships: one-to-one relationships and many-to-many relationships. You’ll learn about both in the following sections.

One-to-One Relationship

A one-to-one relationship links one record in a table to zero or one record in another table. People sometimes use one-to-one relationships to break down a table with lots of fields into two (or more) smaller tables.

A Products table may include detailed information that describes the product and its price, and additional information that describes how it’s built. This information’s important only to the people in the engineering department, so you may choose to split it into a separate table (named something like Products-Engineering). That way, sales folks don’t need to think about it when they’re making an order. Other times, you might break a table into two pieces because it’s simply too big. (Access doesn’t let any table have more than 255 fields.)

You create a one-to-one relationship in the same way you create a one-to-many relationship—by dragging the fields in the Relationships tab (Figure 5-15). The only difference is that the linked fields in both tables need to be set to prevent duplicates. This way, a record in one table can (at most) be linked to a single record in the other table.

Note

A field prevents duplicates if it’s set as the primary key for a table (Section 2.4), or if it has an index that prevents duplicates (Section 4.1.3).

When you link two fields that don’t allow duplicates (and you have the Enable Referential Integrity option switched on), Access realizes that you’re creating a one-to-one relationship. Access places the number 1 at each side of the line to distinguish it from other types of relationships. In this example, the ID column in the Products table and the ID column in the ProductsEngineering table are both primary keys of their respective tables, so there’s no way to link more than one record in ProductsEngineering to the same record in Products.

Figure 5-15. When you link two fields that don’t allow duplicates (and you have the Enable Referential Integrity option switched on), Access realizes that you’re creating a one-to-one relationship. Access places the number 1 at each side of the line to distinguish it from other types of relationships. In this example, the ID column in the Products table and the ID column in the ProductsEngineering table are both primary keys of their respective tables, so there’s no way to link more than one record in ProductsEngineering to the same record in Products.

Many-to-Many Relationship

A many-to-many relationship links one or more records in one table to one or more records in another table. Consider a database that tracks authors and books in separate tables. Best-selling authors don’t stop at one book (so you need to be able to link one author to several books). However, authors sometimes team up on a single title (so you need to be able to link one book to several authors). A similar situation occurs if you need to put students into classes, employees into committees, or ingredients into recipes. You can even imagine a situation where this affects the bobblehead database, if more than one manufacturer can collaborate to create a single bobblehead doll.

Many-to-many relationships are relatively common, and Access gives you two ways to deal with them.

Junction tables

Junction tables are the traditional approach for dealing with many-to-many relationships, and people use them throughout the database world (including in industrial-strength products like Microsoft SQL Server). The basic idea’s that you create an extra table that has the sole responsibility of linking together two tables.

Each record in the junction table represents a link that binds together a record from each table in the relationship. In the books and authors database, a single record in the junction table links together one author with one book. If the same author writes three books, then you need to add three records to the junction table. If two authors work on one book, then you need an additional record to link each new author.

Suppose you have these records in your Authors table:

Table 5-6. 

ID

FirstName

LastName

10

Alf

Abet

11

Cody

Pendant

12

Moe

DeLawn

And you have these records in your Books table:

Table 5-7. 

ID

Title

Published

402

Fun with Letters

January 1, 2007

403

How to Save Money by Living with Your Parents

February 24, 2008

404

Unleash Your Guilt

May 5, 2007

Here’s the Authors_Books table that binds it all together:

Table 5-8. 

ID

AuthorID

BookID

1

10

402

2

11

403

3

12

403

4

11

404

Authors_Books is a junction table that defines four links. The first record indicates that author #10 (Alf Abet) wrote book #402 (Fun with Letters). As you traverse the rest of the table, you’ll discover that Cody Pendant contributed to two books, and two authors worked on the same book (How to Save Money by Living with Your Parents).

Tip

The junction table often has a name that’s composed of the two tables it’s linking, like Authors_ Books.

The neat thing about a junction table is that it’s actually built out of two one-to-many relationships that you define in Access. In other words, the junction table’s a child table that has two parents. The Authors table has a one-to-many relationship with the Authors_Books table, where Authors is the parent. The Books table also has a one-to-many relationship with Authors_Books, where Books is the parent. You can define these two relationships in the Relationships tab to make sure referential integrity rules the day (Figure 5-16).

The many-to-many relationship between Authors and Books is really two one-to-many relationships that involve the Authors_Books table. Once you’ve defined these relationships, you can’t link to an author or book that doesn’t exist, and can’t delete an author or book that has a record in the Authors_ Books table.

Figure 5-16. The many-to-many relationship between Authors and Books is really two one-to-many relationships that involve the Authors_Books table. Once you’ve defined these relationships, you can’t link to an author or book that doesn’t exist, and can’t delete an author or book that has a record in the Authors_ Books table.

Although junction tables seem a little bizarre at first glance, most database fans find that they quickly become very familiar. As with the one-to-many relationships you used earlier, you can create lookups (Section 5.2.5) for the AuthorID and BookID fields in the Authors_Books table. However, you’ll always need to add the Authors_Books record by hand to link an author to a book.

Multi-value fields

Up until Access 2007, junction tables were the only option for many-to-many relationships. But to support the SharePoint integration features (Chapter 21), Access 2007 adds a new feature: multi-value fields.

As its name suggests, a multi-value field can store more than one value. This capacity neatly solves the problem of many-to-many relationships. The trick’s to configure the linked field in the child table as a multi-value field. Reconsider the authors and books example. Without the junction table, you’d need to add an AuthorID column to the books table to indicate which author wrote a given Book:

Table 5-9. 

ID

Title

Published

AuthorID

402

Fun with Letters

January 1, 2006

10

403

How to Save Money by Living with Your Parents

February 24, 2005

11

404

Unleash Your Guilt

May 5, 2006

11

But an ordinary field holds a single value. Thus, this table can indicate only one of the two authors for book #403.

However, if you change AuthorID to allow multiple values, you can enter a list of authors, like this:

Table 5-10. 

ID

Title

Published

AuthorID

403

How to Save Money by Living with Your Parents

February 24, 2005

11, 12

Behind the scenes, a multi-value field actually uses a junction table. However, Access hides that detail from you, which makes it a bit easier to link related records.

In order to create a multi-value field, you need to use a lookup. As you’ve already seen (Section 5.3), you can choose to turn on this option in the last step of the Lookup wizard. Alternatively, if you already have a lookup in a field, you just need to make one minor modification. Open the table in Design view, choose the field that has the lookup (like ManufacturerID), and then, in the Field Properties section, click the Lookup tab. Look for the Allow Multiple Values property, and change it from No to Yes.

Note

Once you change your field to support multiple values, you can’t switch back.

Figure 5-17 shows a multi-value lookup list in action.

This lookup list uses checkboxes, because it’s on a multi-value field. You can select several values for a single record by checking more than one item. So you can indicate that a single doll was created by a two-manufacturer partnership.

Figure 5-17. This lookup list uses checkboxes, because it’s on a multi-value field. You can select several values for a single record by checking more than one item. So you can indicate that a single doll was created by a two-manufacturer partnership.

Multi-value fields are available only if you’re using the new .accdb database format (Section 1.2.2). You can’t use them with an .mdb file (a database that was created in Access 2003 and hasn’t been converted yet).

Multi-value fields also cause headaches if you want to upsize your database to SQL Server (as described in Chapter 20), because SQL Server doesn’t support them. So if there’s a possibility that you’ll need to share your database with lots of people (say, in a large company), and you might move your data to a high-powered SQL Server database someday, avoid multi-value fields.

Note

Multi-value fields don’t pose a problem if you want to upsize your database to SharePoint Server (as described in Chapter 21).

Relationship Practice

Every database designer needs to see the world in terms of tables and relationships. Savvy database designers can quickly assess information and see how it’s related. With this ability, they can build just the right database for any situation.

The following sections provide two scenarios that help you practice more realistic relationship building. Both databases used in these scenarios are available with the samples for this chapter, and they’ll turn up again in the following chapters, when you start to build more sophisticated database objects like queries, reports, and forms.

The Music School

Cacophoné Studios runs a medium-sized music school. They have a fixed series of courses in mind, and a roster of teachers that can fill in for most of them. They also have a long list of past and potential customers. Last year, a small catastrophe happened when 273 students were crammed into the same class and no teacher was assigned to teach it. (Next door, a class of 14 had somehow ended up with three instructors.) They’re hoping that Access can help them avoid the same embarrassment this time around.

Tip

Want to play along with Cacophoné Studios? Try to pick out possible tables and their relationships before reading ahead.

Identifying the tables

Every business is a little different, and it would take a long, detailed analysis to get the perfect table structure for Cacophoné Studios. However, even without knowing that much, you can pick out some fairly obvious candidates:

  • Teachers. A table to store a list of all the teachers on their roster, complete with contact information.

  • Students. A table to store all class-goers past, present, and potential. You don’t need to distinguish between these different groups of people in the Students table—instead, you can sort out the current students from the others by looking for related data (namely, their class enrollments). So you can keep things simple in the Students table, and just store name and contact information.

  • Classes. A table to store the classes that Cacophoné Studios is running. This table should include the class name, date it starts, date it ends, maximum enrollment number, and any other key information.

Note

Course requirements are stored using a multi-value lookup field named PreviousClassRequirements. This field contains the ID values of each required class. (In other words, every record in the Classes table has the nifty ability to point to other classes in the same table.)

Cacophoné Studios will certainly want many more tables before long. But these tables are enough to get started.

Identifying the relationships

It’s fairly easy to pick out the relationships you need. Students take classes. Teachers teach classes. This suggests two relationships—one between Students and Classes, and one between Teachers and Classes.

But there’s a bit of a hitch. Cacophoné Studios certainly doesn’t want to stop a single student from taking more than one class, so you’ll need a many-to-many relationship between the two tables. And even though Cacophoné Studios plans to have only one teacher in each class, they want to keep open the possibility that two or more teachers might co-teach. So Teachers and Classes are also locked in a more complex many-to-many relationship. To support these two relationships, you can create two junction tables, named Students_Classes and Teachers_Classes (respectively).

Figure 5-18 shows a snapshot of this arrangement.

Two many-to-many relationships form the basis of the Cacophoné Studios music school.

Figure 5-18. Two many-to-many relationships form the basis of the Cacophoné Studios music school.

Note

Each record in the Students_Classes table represents a student enrollment in a class. You may want to add some additional fields to Students_Classes to track information like the enrollment date, an enrollment discount you might have offered for early booking, and so on.

Getting more detailed

Cacophoné Studios is off to the right start, but there’s a lot more they still need to think about. First of all, each time they offer a class, they need to create a separate record in the Classes table. This method makes sense, but it causes a potential problem. That’s because when a class (like Electro-Acoustic Gamelan) ends, it’s usually offered again in a new session, with new students. Although this is a whole new class, it has some information in common with the previous class, like the description, fee, course requirements, and so on.

To deal with this requirement, you need to create another table, named ClassDescriptions. The ClassDescriptions record should have all the descriptive information for a class. The Classes record represents a single, scheduled session of a particular class. That way, the school can offer the same class multiple times with-out confusion.

To make this design work, each record in Classes links to a single record in ClassDescriptions. There’s a one-to-many relationship between ClassDescriptions and Classes (Figure 5-19).

Thanks to the ClassDescriptions table, you can use the same description for several classes, thereby avoiding redundant data.

Figure 5-19. Thanks to the ClassDescriptions table, you can use the same description for several classes, thereby avoiding redundant data.

Cacophoné Studios also needs to think about the sticky financial side of things. Each time they put a student in a class, they need to collect a set fee. Each time they assign a teacher to a class, they need to pay up.

Two tables can fill in these details: TeacherPayments and StudentCharges. Obviously, these tables need relationships—but maybe not the ones you expect. You may assume that you should link the StudentCharges record directly to the records in the Students table. That linking makes sense, because you need to know which student owes money. However, it’s also important to keep track of what the money’s for—namely, the class that the student’s paying for. In other words, every record in StudentCharges needs to link to both the Students and the Classes table.

But there’s an easier approach. You can save some effort by linking the StudentCharges table directly to the Students_Classes table. Remember, each record in Students_Classes has the student and class information for one enrollment. Every time you add a record in Students_Classes, you need to add a corresponding charge in StudentCharges. One record in the Students_Classes table should link to exactly one record in the StudentCharges table. A similar relationship exists between the Teachers_Classes and TeacherPayments tables. Figure 5-20 shows the whole shebang (not including the ClassDescriptions table shown in Figure 5-19).

Every assigned class results in a payment in the TeacherPayments table (top left). Every enrollment results in a charge in StudentCharges (top right). Although this picture’s a bit intimidating at first glance, you should be able to work your way through all the tables and relationships one by one. When building a database, it’s easiest to start with a few tables, and then keep adding on.

Figure 5-20. Every assigned class results in a payment in the TeacherPayments table (top left). Every enrollment results in a charge in StudentCharges (top right). Although this picture’s a bit intimidating at first glance, you should be able to work your way through all the tables and relationships one by one. When building a database, it’s easiest to start with a few tables, and then keep adding on.

Note

Remember, to create a one-to-one relationship, you need to use a primary key or an index that doesn’t allow duplicates (Section 4.1.3). In this example, you need to add a no-duplicates index to the Student_ClassesID field in the StudentCharges table, and the Teacher_ClassesID field in the Teacher-Payments table. These indexes make sure that students get charged only once for each class they take, and teachers get only a single payment for each class they teach.

This database has quickly become quite sophisticated. And Cacophoné Studios probably isn’t done yet. (For example, it’ll more than likely want a table to track student payments.) As with most realistic databases, you can keep adding on new tables and relationships endlessly.

The Chocolate Store

A sales database that stores the products, customers, and orders for a company that sells something is one of the most common databases. In fact, this pattern turns up so often that it’s worth looking at a quick example. As you’ll see, there are a few basic principles that apply to every sales-driven business, whether the business is selling collectible books or discount pharmaceuticals.

In this example, you’ll meet Boutique Fudge, a mail-order company that serves decadent treats to a large audience of chocolate-crazed customers. Their daring chefs are always innovating, and they need a better way to manage their ever-growing catalog of chocolate goodness. They also need a way to keep track of customers and the orders they make.

The product catalog and customer list

Even though you don’t know much about Boutique Fudge, you can already think of a few key tables that it’ll need. In order to put anything up for sale, they should have the following tables:

  • Products lists the sinful chocolate delicacies they have for sale. This table records the name, description, and price of each item available. A few optional details also make sense—for example, why not keep track of the current stock using two numeric fields (UnitsInStock and UnitsOnOrder) and a Yes/No field (named Discontinued) to identify products that aren’t available any longer?

    Note

    In many databases, you can’t delete old information. A company like Boutique Fudge can’t simply delete old products from their catalogs, because these products might be linked to old orders. Also, it makes sense to keep historical information to allow data analysis. (Boutique Fudge could use a query to uncover the top selling products in 1999, and check if declining cocoa levels are linked to lessening sales.) For this reason, you need tricks like the Discontinued field. When you list the products for sale, you can leave out all the discontinued ones, using the filtering skills you picked up in Section 3.2.2.

  • ProductCategories splits products into a few descriptive groups. That way, customers can browse just the products in the category they want (whether it’s Beverages, Candies, Chocolate, or Personalized Choco-wear).

  • Customers holds the list of chocoholics that have signed up to make an order. You need all the customary information here, like customer names, shipping information, and billing information.

Note

Many companies let customers supply multiple shipping addresses and credit cards. If you allow this flexibility, then you’ll need (surprise) more tables. You could create a table of CustomerCreditCards. Every record in Customers could then link to one or more records in CustomerCreditCards. Boutique-Fudge takes the easy way out, and stores a customer credit card and address directly in the Customers table.

So far, there’s only one relationship at work: a one-to-many relationship between ProductCategories and Products. Figure 5-21 shows this design.

A product (like Chocolate Jasmine Tea) can be placed in one category (like Beverages), but a single category holds many products.

Figure 5-21. A product (like Chocolate Jasmine Tea) can be placed in one category (like Beverages), but a single category holds many products.

Ordering products

It doesn’t matter how fancy your sales database is—if it doesn’t have a way for customers to order the items they’re interested in, then Boutique Fudge will run out of money fast.

Database newbies often make the mistake of assuming that they can use one table to store order information. In truth, you need two:

  • Orders records each order a customer places. It links to the customer who made the order, and adds information like the date the order was placed.

  • OrderDetails lists the individual items in an order. Each record in the OrderDetails table includes the ID of the product that was ordered, the number of units ordered, and the price at which they were ordered.

Because the average order includes more than one item, a single record in the Orders table is usually linked to multiple records in the OrderDetails table (as shown in Figure 5-22). This setup may sound a bit awkward (because it means you’ll need to create a batch of new records for just one order), but the process doesn’t have to be that difficult. Access has two features that help out: the subdatasheet feature you’ve already seen (Figure 5-23) and the forms feature (Chapter 12).

Every order can hold an unlimited number of order items. This ability makes Boutique Fudge happy.

Figure 5-22. Every order can hold an unlimited number of order items. This ability makes Boutique Fudge happy.

Thanks to the subdatasheet feature (Section 5.2.4), you can add an order record and the linked order items in the same place.

Figure 5-23. Thanks to the subdatasheet feature (Section 5.2.4), you can add an order record and the linked order items in the same place.

Notice that the OrderDetails record stores the price of each ordered item. This system may seem to violate the redundant data rule. After all, the product prices are always available in the Products table. However, product prices change, and companies offer discounts. For those reasons, it’s absolutely essential that you keep track of the price of an item when it was ordered. Otherwise, you’ll have to guess how much each customer owes you.

Note

Database nerds call this sort of information point-in-time data, because it varies over time.

You should also notice that the Order record doesn’t store the total cost of the order. That’s because the total cost is simply the sum of all the ordered items. If you stored a total cost, you’d open up the possibility of inconsistent data—in other words, you’ve got a problem if the order total you store doesn’t match the cost of all the items.

You still have more work to do before Boutique Fudge can become a true database-driven company. For example, you’ll probably need to create a Shipments table that tracks orders that it’s mailed and a Payments table that makes sure customers pay up. Conceptually, there’s nothing new here, but the more tables you add, the more complex your databases become. Now that you know the basics of relationships and good table design, you can stay cool under the pressure.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.217.199.122