Question

Someone suggested moving a table full of settings, where each column is a setting name(or type) and the rows are the customers & their respective settings for each setting.

ID | IsAdmin | ImagePath
------------------------------
12 | 1          | \path\to\images
34 | 0          | \path\to\images

The downside to this is every time we want a new setting name(or type) we alter the table(via sql) and add the new (column)setting name/type. Then update the rows(so that each customer now has a value for that setting).

The new table design proposal. The proposal is to have a column for setting name and another column for setting.
ID | SettingName | SettingValue
----------------------------
12 | IsAdmin        | 1
12 | ImagePath   | \path\to\images
34 | IsAdmin        | 0
34 | ImagePath   | \path\to\images

The point they made was that adding a new setting was as easy as a simple insert statement to the row, no added column.

But something doesn't feel right about the second design, it looks bad, but I can't come up with any arguments against it. Am I wrong?

Was it helpful?

Solution

This is a variation of an "Entity Attribute Value" schema (Joel and random SO question)

It has a few pros and more cons, and it pretty much guaranteed to end in tears.

OTHER TIPS

The second approach actually resembles a dictionary. I found this to be a more convenient choice for an application I am working on for the reasons you mentioned. There are a few caveats to this approach, so you need to be careful about them:

  • Keep your key strings static, never rename.
  • Make sure each time the settings dictionary is retrieved you update it to the newest version (usually by adding keys and setting default values/prompting the user).
  • It's tricky to mix string and e.g. decimal data, you'll either need to choose one or provide multiple, nullable columns so you can store data in the appropriate format. Keep that metadata around somewhere.
  • The code that deals with the dictionary should wrap it in a strongly typed fashion, never expose it as a real dictionary (in the sense of a datastructure), provide a class instead.

Using column names to distinguish settings is usually a terrible idea. The entity you are dealing with is the SETTING, and it has the attributes NAME and VALUE. If you need to use the same name in different contexts, make the SETTING hierarchical, i.e. each setting except the root gets a parent. You customers could then have the root as their parent, and the path under each customer would be the same for each setting. You can use different columns for additional data types if you want.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top