tags:

views:

77

answers:

2

Hi, i have few questions for SQL gurus in here ... Briefly this is ads management system where user can define campaigns for different countries, categories, languages. I have few questions in mind so help me with what you can.

Generally i'm using ASP.NET and i want to cache all result set of certain user once he asks for statistics for the first time, this way i will avoid large round-trips to server.

any help is welcomed

Click here for diagram with all details you need for my questions

1.Main issue of this application is to show to the user how many clicks/impressions were and how much money he spent on campaign. What is the easiest way to get this information for him? I will also include filtering by date, date ranges and few other params in this statistics table.

2.Other issue is what happens when user will try to edit campaign. Old campaign will die this means if user set 0.01$ as campaignPPU (pay-per-unit) and next day updates it to 0.05$ all will be reset to 0.05$.

3.If you could re-design some parts of table design so it would be more flexible and easier to modify, how would you do it?

Thanks... sorry for so large job but it may interest some SQL guys in here

+2  A: 

For #1, you might want to use a series of views to show interesting statistics. If you want to cache results, you could store the results to a reporting table that only gets refreshed every n hours (maybe up to 3 or 4 times a day? I don't know what would be suitable for this scenario).

Once all the data is in a report table, you can better index it for filtering, and since it will be purged and re-populated on a schedule, it should be faster to access.

Note that this will only work if populating the stats table does not take too long (you will have to be the judge of how long is "too long").

For #2, it sounds like an underlying design issue. What do you mean by "edit"? Does this edit operation destroy the old campaign and create a new "clone" campaign (that is obviously not a perfect clone or there wouldn't be a problem)? Is there historical data that is important, but getting orphaned or deleted by the edit? You might want to analyze this "edit" process and see if you need to add history-tracking to some of these tables. Maybe a simple datetime to old records, or a separate "history" table(s) that mirrors the structure of the tables being modified by the "edit" operation.

For #3, It looks alright, but I'm only seeing a sliver of the system. I don't know how the rest of the app is designed...

FrustratedWithFormsDesigner
@FrustratedWithFormsDes,1.Views are fine but each join will contain about 5-8 joins with this level of normalization. Maybe you see any way to de-normalize tables to avoid 5-8 joins2.What should i do in case user edits campaign. I wouldn't be able to show correct statistics because PPU will be different. If i create another table, ie. HistoryOfCampaigns i will be needed to loop thought versions to get correct statistics for current campaign.
eugeneK
@FrustratedWithFormsDes, can you give me an advice on how to design reports table ? I have no clue yet. It should have datetime, campaign status, clicks, impressions filtering options.
eugeneK
@eugeneK: The report table should contain columns that will be needed for the stats reporting for your users. So maybe UserID, CampaignID, CampaignName, CampaignDate, AmountSpentToDate (this might be a calculated column, at the time the data is generated), ... Then you'd have to populate the report table with the data you want. *Many* ways to do this. Could be scheduled hourly, or only on-demand per-user... Simplest way might be to do it once a day, at midnight (if it takes a long time to run). And yes, the data in the report table might be a bit de-normalized, but that's OK.
FrustratedWithFormsDesigner
@eugeneK: It's still not clear to me *why* editing a campaign destroys old stats. You might want to explain what this edit procedure involves.
FrustratedWithFormsDesigner
@FrustratedWithFormsDes, ok ! User set campaign with ppu of 0.01$ and dailyBudget of 10$. Whichc means he will be able to have 1000 clicks a day. Tomorrow he edits to ppu of 0.02 and dailyBudget of 2$ which will give him 100 clicks. Now i need to work with the data. ie. User enters statistics on 3rd day and sees 1100 click and 12$ wasted but his current ppu is 0.02 and dailyBudget is 2$ while after two days he has different stats .
eugeneK
@FrustratedWithFormsDes, Other example is how do i calculate whether totalCampaignBudget is reached. I take all clicks and multiply by current ppu which will be wrong as some clicks cost to user 0.01$ and some 0.02$
eugeneK
+1  A: 

Eugene,

If you plan to keep the edited campaigns around consider not removing them. Instead make the campaigns date sensitive. For example UserA started campaign 1 on 1/1/2010 and ended it on 2/1/2010 then started campaign2 on 2/2/2010.

Or if you dont like the notion of end dating your campaigns. You could consider a history table for your campaigns. Basically the same table structure but an added UniqueIdentifier to make rows unique.

I should also note that estimated size of this campaign table and its related tables are important on your design. If you expect to have only 1000s of rows keeping old and current records in one table isnt a problem. however if you plan to have 1000000s or more then you may want to separate the old from the new for faster queries, or properly plan statistics and indicies on fields you know will need to be filtered on. Also remember indicies are usefule for reads but they slow down writes.

John Hartsock
@John Hartsock, I've thought of History table. Thing is it doesn't make sense when i design it.Let's say each change in ppu or dailyBudget is saved to CampaignsHistory table, things like campaignName doesn't worth the save in HistoryTable. Now i want to get how much user spent in some time frame. I will be needed to loop thought all Rows in HistoryTable that correspond to current campaign and generate that report to the user. TBH it will be CPU overload.Another way i thought to solve the issue is by setting parentCampaignID for any change which will be more or less the same as HistoryTable
eugeneK
If your going to manage things in this way.. use a GUID/UniqueIdentifier for the primary key. This way the ID of the record in the history table will still have reference back to your detail tables. Note do not use a clustered primary key on a GUID PK. It is not efficient becuase guids are not sequential
John Hartsock
@John Hartsock, how i supposed to get information from History table and Current table so i can build report if GUID connects both ?
eugeneK
You history would contain a HistoryTableID as primary key but also contain the guid that represented the original primary key value from the live table. It wouldnt be the same primary key in both tables just a reference in the history table to the original primary key.
John Hartsock