Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Table Design For SystemSettings, Best Model

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?

like image 381
Chris L Avatar asked Mar 08 '10 17:03

Chris L


2 Answers

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.

like image 143
gbn Avatar answered Oct 01 '22 00:10

gbn


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.
like image 31
Johannes Rudolph Avatar answered Sep 30 '22 23:09

Johannes Rudolph