I am currently working on restructuring my site’s database. As the schema I have now is not one of the best, I thought it would be useful to hear some suggestions from you.
To start off, my site actually consists of widgets. For each widget I need a table for settings (where each instance of the widget has its user defined settings), a table for common (shared items between instances of the same widget) and userdata (users’ saved data within an instance of a widget).
Until now, I had the following schema, consisting of 2 databases:
- the first database, where I had all site-maintenance tables (e.g. users, widgets installed, logs, notifications, messages etc.) PLUS a table where I joined each widget instance to each user that instanciated it, having assigned a unique ID (so, I have the following columns:
user_id,widget_idandunique_id). - the second database, where I kept all widget-related data. That means, for each widget (unique by its
widget_id) I had three tables:[widget_id]_settings,[widget_id]_commonand[widget_id]_userdata. In each of these tables, each row held thatunique_idof the users’ widget. Actually here was all the users’ data stored within a widget.
To give a short example of how my databases worked:
First database:
- In the
userstable I haveuser_id = 1 - In the
widgetstable I havewidget_id = 1 - In the
users_widgetstable I haveuser_id = 1, widget_id = 1, unique_id = 1
Second database:
- In the
1_settingsI haveunique_id = 1, ..., where … represents the user’s widget settings - In the
1_commonI have several rows which represent shared data between instances of the same widget (so, no user specific data here) - In the
1_userdataI haveunique_id = 1, ..., where … represents the user’s widget data. An important notice here is that this table may contain several rows with the sameunique_id(e.g. For a tasks widget, a user can have several tasks for a widget instance)
Hope you understood in the rough my database schema.
Now, I want to develop a ‘cleaner’ schema, so it won’t be necessary to have 2 databases and switch each time from one to another in my application. It would be also great if I found a way NOT to dinamically generate tables in the second database (1_settings, 2_settings, … , n_settings).
I will greatly appreciate any effort in suggesting any better way of achieving this. Thank you very much in advance!
EDIT:
Shall I have databases like MongoDB or CouchDB in my mind when restructurating my databases? I mean, for the second database, where it would be better if I didn’t have a fixed schema.
Also, how would traditional SQL’s and NoSQL’s get along on the same site?
A possible schema for the users_widgets table could be:
You don’t need the
unique_idfield in theusers_widgetstable, unless you want to hide the primary key for some reason. In fact, I would rename this table to something a little more memorable likewidget_instances, and usewidget_instance_idin the remaining tables of the second database.One way to handle the second set of tables is by using a metadata style:
widget_instance_settings
This would include the userdata, because user_id is related to the widget_instance_id, unless you want to allow a user to create multiple instances of the same widget, and have the same data across all instances for some reason.
widget_common_settings
This type of schema can be seen in packages like Elgg.