views:

29

answers:

3

Here's a layout of my data:

Heading 1:
   Sub heading
   Sub heading
   Sub heading
   Sub heading
   Sub heading

Heading 2:
   Sub heading
   Sub heading
   Sub heading
   Sub heading
   Sub heading

Heading 3:
   Sub heading
   Sub heading
   Sub heading
   Sub heading
   Sub heading

Heading 4:
   Sub heading
   Sub heading
   Sub heading
   Sub heading
   Sub heading

Heading 5:
   Sub heading
   Sub heading
   Sub heading
   Sub heading
   Sub heading

These headings need to have a 'Completion Status' boolean value which gets linked to a user Id.

Currently, this is how my table looks:

id  |  userID  |  field_1  |  field_2  |  field_3  |  field_4  | etc...
-----------------------------------------------------------------------
1   |     1    |    0      |     0     |     1     |     0     |
-----------------------------------------------------------------------
2   |     2    |    1      |     0     |     1     |     1     |

Each field represents one Sub Heading. Having this many columns in my table looks awfully inefficient...

How can I go about optimizing this? I can't think of any way to neaten it up :/

+3  A: 

Don't use boolean values but simple relations:

table completion_status

id user_id field_id

1  1       3
2  2       1
3  2       3
4  2       4
...

From that it's easy to see that user 1 has completed field 3, and user 2 fields 1, 3 and 4.

This way you don't have to change your database schema whenever you want to change the amount of fields.

Tatu Ulmanen
I was using a similar method to begin with but the table ended up having 27 rows for the one user. This number will likely grow in the future. Is this not bad? Shouldn't I try to limit the table size as much as possible?
Steffan
Yup. But this way, you only use the rows that have data - your way, you have lots of unused columns. Also, imagine having to add a new type - this way it's a blink of an eye - your way would involve changing the table and the queries.
Konerak
i don't think having multiple rows for the same user is a problem. modern DBMS can handle millions of rows without issues. just make sure that you add proper indexes.
NimsDotNet
No, this is not bad, as long as you define proper indices. Have a look at [this Wikipedia article on first normal form](http://en.wikipedia.org/wiki/First_normal_form)
Martijn
@Steffan, the amount of rows does not have any significance in your case. Actually this way you end up _saving_ space as in your example all users have all the fields defined either 0 or 1. With my proposed solution, users' fields will only take as much space as minimally required.
Tatu Ulmanen
I'll change up my structure. Thanks for the help :}
Steffan
@Steffan, don't forget to mark the answer accepted so others don't have to bother any more :)
Tatu Ulmanen
A: 

You could have the sub-headings in a different table, and then link that table to the first table.

id  |  userID  |  field_id | 
-----------------------------
1   |     1    |    0      | 
-----------------------------
2   |     2    |    1      | 

where table field looks like this

id  | field_1 | field_2   | etc..
-----------------------------
1   |     1   |    0      | etc..
Lars Andren
That doesn't really change anything, just splits the data into two tables. The problem with too many columns still exists.
Tatu Ulmanen
A: 

Why dont you make a table like this?

id  | User Id | Field ID | Status
---------------------------------
1   |   1     |   1      | 0   
2   |   1     |   2      | 1  

You can have another master table for Fields with the field names

NimsDotNet
No need for `status`, if the `field_id` exists, it's done, otherwise it's not.
Tatu Ulmanen
Well, if you decide to add an "in-progress" status later, this will help. :)
NimsDotNet