[ale] Database design
George Carless
kafka at antichri.st
Mon Nov 13 10:39:53 EST 2006
On Mon, Nov 13, 2006 at 09:57:09AM -0500, Christopher Fowler wrote:
> I'm giving a Perl DBI talk at Atlanta PM on Thursday. I need to create
> a sample database design for the code but am at a stand still. My idea
> is to create a Recipe database and I'm going to use this recipe in the
> talk:
[snip]
> Here is the schema:
>
> CREATE TABLE ingredient (
> ingredient_id INTEGER(11) NOT NULL AUTO_INCREMENT,
> name VARCHAR(20) NOT NULL,
> description VARCHAR(250) NULL,
> PRIMARY KEY(ingredient_id),
> INDEX XAK1level(name)
> );
>
> CREATE TABLE recipe (
> recipe_id INTEGER(11) NOT NULL AUTO_INCREMENT,
> name VARCHAR(20) NOT NULL,
> description VARCHAR(250) NULL,
> directions MEDIUMTEXT NULL,
> PRIMARY KEY(recipe_id),
> INDEX XAK1level(name)
> );
>
> CREATE TABLE recipe_ingredient_map (
> recipe_id INTEGER(11) NOT NULL,
> ingredient_id INTEGER(11) NOT NULL,
> amount VARCHAR(20) NOT NULL,
> PRIMARY KEY(recipe_id, ingredient_id)
> );
>
>
> Based on this design the recipe can not have two rows in the
> recipe_ingredient_map that are the same ingredients. In the example
Don't key on ingredient_id+ingredient_id. With this schema I would create a separate ID for the
"ingredient map" as a primary key, and I think you need a field to identify the order of the step
in the ingredient_map (see my comments below on direction_steps). But I have to say that your
schema looks a little odd to me -- when it comes to a recipe you're not just throwing your
ingredients in all at once, and you're also typically going to have lots of different measures
for your "amount" field (i.e. 1 package; 1/3 cup; 1 teaspoon)-- so I don't see why you would
bother to have a separate field for "amount": you're not going to want to do queries on the
amount field, and you won't be able to do any meaningful comparisons between different records,
so why bother separating it? (I know you're looking for a semi-complex example, but I think it's
best to only follow practices that make sense in the real world; it's not at all uncommon for
people to make overly complicated tables for no good reason.)
Also, if you are going to split off your ingredients into separate tables, I suppose it would
make sense to get more relational on your directions -- rather than having "directions" as a
field within the recipe table, you might want to have a direction_steps table. Something like:
recipe_id INTEGER NOT NULL,
step_id SMALLINT NOT NULL,
ingredient_id INTEGER NOT NULL,
directions SMALLTEXT,
PRIMARY KEY(recipe_id,step_id)
To my mind this would replace the recipe_ingredient_map and would do away with the directions
field. With this schema you have a relational structure where it makes sense - e.g. you could
say "find me all recipes that contain eggs" (I don't think most people would typically want/need
to say "find me all recipes that contain two eggs") - and you could also open up room for future
expansion on the "steps" (e.g. a field to indicate a step could be skipped, or additional tables
to allow people to comment on individual steps, etc.)
--George
--------------------------------------
George Carless ... kafka at antichri.st
Words are just dust in deserts of sound
More information about the Ale
mailing list