1 The column naming has a few errors:
• Do not prefix the column name with the [shortened] table name. It is completely redundant in SQL, just write the code for a joined couple of tables and you will see why. Whenever the column name is ambiguous, the table name prefixes the column name to resolve the ambiguity.
• Use full column names for all Keys (PKs are a special case which need to be identified as FKs when used as such). rId will be a problem when you add a table starting with 'R'.
2 Since you are discussing Normal Forms, you are dealing with the Logical level. However, you have assumed:
• that every table needs a Surrogate key, an Identity column, and
• (worse!) it will be the PK in every table
That is a Physical implementation issue, and an additional index. At the Logical level, stick with natural Relational keys (people do not think in terms of a Recipe Id). You can always add your additional surrogate keys and indices later, on a table basis (they will not always be required).
Another way of stating the same point is, the PKs are all incorrect. In order to prevent duplicates, and to allow people to find rows by identifiable means, you will need unique indices on the following columns (which may well be the real PKs, the Surrogate keys which may be added later being the Alternate, nor Primary, Keys):
Recipe.Name
Ingredient.Name
Cook.Name
CookPhone.PhoneNumber
CookRecipe.CookId+RecipeId
3 As stated at 3NF, Cook and CookPhone have the same dependencies, so they are [both] not at 3NF [in the same database].
• Either: a cook has only one PhoneNumber, and therefore it should be placed in Cook; CookPhone is eliminated
• Or: a cook has more than one PhoneNumber; and the PK for CookPhone is (CookId, PhoneNumber), (CookId) will fail on entry of the second PhoneNumber. Again to prevent duplicate entries.
• The use Surrogate keys do not eliminate compound keys; compound keys are normal.
4 Ingredient is broken at 3NF, but I suspect the resolution was not complete at 2NF:
• What you have is fine for the reference table (one row per Ingredient) and therefore Amount is meaningless and can be removed.
• There is nothing that relates Recipe to Ingredient (ie. there is a segment missing at 2NF).
• The Amount of Ingredient is specific to a Recipe
• The resolution is one row per Recipe-Ingredient, at 3NF:
RecipeIngredient (
RecipeId -- PK.1
IngredientId -- PK.2
Amount
)