views:

54

answers:

1

Hi Guys,

I'm creating an virtual stamp card program for the iphone and have run into an issue with implementing my database. The program essentially has a main points system that can be utitlized through all merchants (sort've like air miles), but i also want to keep track of how many times you've been to EACH merchant

So far, i have created 3 main tables for users, merchants, and transactions.

1) Users table contains basic info like user_id and total points collected.

2) Merchants table contains info like merchant_id, location, total points given.

3) Transactions table simply creates a new row for every time someone checks into each merchant, and records date-stamp, user name, merchant name, and points awarded.

So the most basic way to deal with finding out how many times you've been to each merchant is to query the entire transaction table for both user and merchant, and this will give me a transaction history of how many times you've been to that specific merchant(which is perfect), but in the long run, i feel this will be horrible for performance.

The other straightforward, yet "dumb" method for implementing this, would be to create a column in the users table for EACH merchant, and keep the running totals there. This seems inappropriate, as I will be adding new merchants on a regular basis, and there would need to be new columns added to every user for every time this happens.

I've looked into one-to-many and many-to-many relationships for mySQL databases, but can't seem to come up with something very concrete, as i'm extremely new to web/PHP/mySQL development but i'm guessing this is what i'm looking for...

I've also thought of creating a special transaction table for each user, which will have a column for merchant and another for the # of times visited. Again, not sure if this is the most efficient implementation.

Can someone point me in the right direction?

+1  A: 

You're doing the right thing in the sense of thinking up the different options, and weighing up the good and bad for each.

Personally, I'd go with a MerchantCounter table which joins on your Merchant table by id_merchant (for example) and which you keep up-to-date explicitly.

Over time it does not get slower (unlike an activity-search), and does not take up lots of space.

Edit: based on your comment, Janan, no I would use a single MerchantCounter table. So you've got your Merchant table:

id_merchant        nm_merchant
12                 Jim
15                 Tom
17                 Wilbur

You would add a single additional table, MerchantCounter (edited to show how to tally totals for individual users):

id_merchant    id_user     num_visits
12             101         3
12             102         8
15             101         6007
17             102         88
17             104         19
17             105         1

You can see how id_merchant links the table to the Merchant table, and id_user links to a further User table.

Brian
If i have, say 50 merchants, wouldn't that mean i have to have 50 new tables (one for each) which link to the main merchant table, in addition to the 3 original ones. Is that what you meant? Also, is that a good "programming practice"?
Janan Rajeevikaran
+1 Brian. @Janan: if the performance does degrade with higher volumes eventually, you could consider archiving and/or partitioning, as well as the denormalisation technique that you mention. If you can establish this up-front during your testing with expected volumes, so much the better!
richaux
I actually have that part figured out. Sorry if i wasn't clear with my explanation earlier, but picture this scenario: I have 100 users and 100 merchants.I want to find out exactly how many times user 15 has gone to merchant 50. The implementation so far can tell me how many times everyone has visited merchant 50, but can't tell me how many times user1, user2, and user3 have visited individually.
Janan Rajeevikaran
Have edited again to show user counts. Btw this is a fundamental concept; if you're not familiar with such joins, you would really benefit from spending some time reading about relational concept, e.g. http://dev.mysql.com/tech-resources/articles/intro-to-normalization.html
Brian
Perfect! This was exactly what i was looking for. And yes, i definitely agree, i'm going to take some time to read up on how to utilize joins effectively. Thanks again Brian, really appreciate it!
Janan Rajeevikaran
You're welcome, happy to help. Btw, in the above example you should include *both* of id_merchant and id_user as your primary key: each merchant can appear many times, and each user can appear many times, but it's only valid to have one instance of [merchant A, user B].
Brian
Yup, already set up both of them as primary keys. The article outlined everything perfectly.
Janan Rajeevikaran