views:

87

answers:

4
+1  Q: 

Database Design

This is a general database question, not related to any particular database or programming language.

I've done some database work before, but it's generally just been whatever works. This time I want to plan for the future.

I have one table that stores a list of spare parts. Name, Part Number, Location etc. I also need to store which device(s) they are applicable too.

One way to do is to create a column for each device in my spare parts table. This is how it's being done in the current database. One concern is if in the future I want to add a new device I have to create a new column, but it makes the programming easier.

My idea is to create a separate Applicability table. It would store the Part ID and Device ID, if a part is applicable to more than one device it would have more than one row.

Parts
-------
ID
Name
Description
Etc...

PartsApplicability
-------
ID
PartID
DeviceID

Devices
------
ID
Name

My questions are whether this is a valid way to do it, would it provide an advantage over the original way, and is there any better ways to do it?

Thanks for any answers.

+4  A: 

You're describing the standard setup of a many-to-many relationship in an RDBMS, using an intermediate join table. Definitely the way to go if that's how your model will end up working.

Rex M
+3  A: 

I agree with Rex M's answer, this is a standard approach. One thing you could do on the PartsApplicability table is remove the ID column, and make the PartID/DeviceID a composite primary key. This will ensure that your Part cannot be associated to the same Device more than once, and vice-versa.

Andy White
That could potentially cause the pagefile to become severely fragmented if we're talking about a large number of parts and any kind of churn with new and changing data. I'd recommend keeping the autoincrementing field as the PK and indexing on the others.
Rex M
+1 definitely get rid of `PartsApplicability.ID`.
just somebody
@Rex M: I don't understand the pagefile remark. also: changing data? the two relevant attributes are foreign keys.
just somebody
@just somebody: making the two IDs the PK means the table is physically sorted on the disk in that order. So if we insert (Part1/Device1), (Part1/Device2), (Part2/Device3), then (Part 1/Device3) the database will have to break the table apart and insert the last one between entries 2 and 3. For many records, this becomes very problematic as it involves shuffling hundreds, thousands, or millions of records every time one is added. By contrast, an autoincrementing PK allows the new records to be tacked on to the end.
Rex M
@Rex, do you think the indexes are stored as an array that needs shifting up and down when records are added and deleted? They're far more likely to use efficient balanced multi-way trees which would definitely _not_ involve shuffling even thousands of records around.
paxdiablo
@Rex M: you're talking about an implementation detail of something that's not very smart. it's true that SQL databases usually provide a way to make a table physically organized according to an index, but that's an implementation-specific including the DDL syntax, and the current question hasn't been labelled with any specific SQL RDBMS (or `physical-database-design`). besides, what paxdiablo said.
just somebody
@paxdiablo exactly, rebuilding the indexes is far preferable to resorting the table. So, use indexes instead of PK.
Rex M
+1  A: 

Using a separate table to hold many-to-many relationships is the right way to go.

Some of the benefits for join tables are

  1. Parts may be applicable to any device and creating new devices or parts will not lead to modifications to the database schema
  2. You don't have to save nulls or other sentinental values for each part-device mapping that doesn't exists i.e. things will be cleaner
  3. Your tables remain narrow which makes them easier to understand

You seem to be on your way to discover the database normal forms. The 3rd normal form or BNF should be a good goal to have although sometimes it's a good idea to break the rules.

Aleksi
+1  A: 

Your second design is a very good design, and similar to what I've done (at work and on my own projects) many times in terms of describing relationships between things. Lookup tables and their equivalent are often far simpler to use than trying to stuff everything in one table.

Would also agree on making the programming easier. Ultimately, you'll find that learning more makes programming far easier than trying to push things into what you already know even when they really don't fit. Knowing how to properly join tables and the like will make your programming with databases far easier than continually modifying columns would be.

Todd