How to store events for an online game in mysql - php

As part of an online text based game, I will be simulating game events for a cricket game (or you can consider baseball). There will be an event generated for each delivery bowled (or pitch). Events will be of the type 4 runs, 2 runs, wickets, etc. For each event, there will be multiple players involved, bowler, fielder and batsman.
The design that I have in mind is such:
**Table 1 - MatchEvent**
EventID
EventType
BowlerID
BatsmenID
FielderID
**Table 2 - Commentary**
CommentaryID
GameID
Innings
DeliveryNum
EventID
The concern that I have is that, there will be at least 600 rows per match simulated.
Is there a better way to design the table, considering that I need to replay the results to the users per delivery.

Related

Creating Matching bonus using PHP

How can I create a networking system where
User A registers person 1 and person 2 in a week and he gets a matching bonus and then when person 1 registers another two people User A gets matching bonus from those two people.
How can I structure the database???
I'm finding it difficult to structure the database. Please can anyone help me?
This is a diagram showing what I'm actually talking about
Diagram 1
Diagram 2
Normally I would assign any bonuses the moment a person get registered. The algorithm assigning the bonuses has to deal with the complexities, not the structure of the database.
Using an algorithm for this is also more flexible, because you can change, and test, the algorithm without changing the structure of the database.
A basic setup for the database could be:
Table USERS:
UserID
Name
RegisteredByUserID
1
person A
0
2
person 1
1
3
person 2
1
4
person X
3
5
person Y
3
Table BONUSES:
BonusID
RewardedToUserID
ForRegisteringUserID
Amount
1
1
2
2,500
2
1
3
2,500
3
3
4
2,500
4
3
5
2,500
This is a very crude example. Basically when a new person is registered an algorithm sorts out which bonuses have to be given to which users and these bonuses are stored in a table.
The 'BONUSES' table can then be used to compute the total bonuses given to each user, and the total of bonuses given out for registering an user.

Database design: implementing several types of the same entity

I'm coding a Classified Ads web application. The application has several types of Ads:
General ads(electronics, toys, pets, books...)
Real estate (houses, apartments, terrains...)
Vehicles (motocycles, cars, vans, trucks...)
Each type has several common fields (id, title, description) and also some that are exclusive to its kind:
General Ads (no exclusive fields)
Real estate (area, type-of-property...)
Vehicles (type-of-vehicle, cubic-capacity, kilometers...)
What is the most recommended approach to this situation?
A table that contains all fields and leave empty the fields that
don't apply to the current recordset.
A main table with the fields common to all Ads, and an additional table for each type of Ad that has exclusive fields.
One table for each type of Ad.
Other
I would build a solution depending on various criteria :
If you believe the table will be large in the future (a lot of ads to be published), you may want to minimize the number of JOINs for better performance => option 1. "one table with empty fields when not relevant to ad type"
Previous comment applies especially if your data storage cost is low.
If you have to query the data against certain field values (e.g. house size, car kilometers), you might avoid the solution described by phpalix (ad_type | property | value) or Andy Gee since your SQL syntax will be a nightmare, and prefer to have all your data in the same table (again).
If there are A LOT of custom fields per ad type, you might prefer to separate each ad type in their own table, for easier maintenance and data storage optimization. Then you can either JOIN or UNION to query your ads lists.
I'll add to my answer if i think of something else.
You can normalise (a table for the abstract concept and a table the the specialised one) or denormalise (a table with all the fields)
As always, the choice must be done according to the cost of each solution, reprensented by the speed of the queries (normalised model means more joins (buffer/cpu) whereas denormalised more disk reads usually because the columns are sometimes retrieved when it is not necessary) or the storage required in both cases.
All solutions are acceptable and a matter of preference, performance, complexity and design needs. The terms for what you are discussing are Table-Per-Type, Table-Per-Class and Table-Per-Hierarchy. If you google on these you are guaranteed to get a ton of Entity Framework results, but the underlying design considerations are much the same.
For flexibility I would have all the field in a separate table then allow the assigning of each field to each ad type. This would also allow you to add and remove fields easily at a later date.
Each field may have different types of data so this information should also be in a separate table.
Something like this (not very clear sorry)
Table: fields
field_id, field_type, field_name
1 1 title
2 1 price
3 2 size
4 3 description
5 1 square meters
Table: field_types
field_type_id, type
1, textbox
2, select_box
3, text_area
Table: field_data
field_data_id, ad_id, field_id, field_type_id, field_data
1 1 1 1 Cool t-shirt
2 1 2 1 5.99
3 1 3 2 L,XL,XXL,XXXL
4 1 4 3 Some description
5 2 1 1 Nice house
6 2 2 1 250000
7 2 4 3 Some description
8 2 5 1 1024sq/m
Table: ad_types
ad_type_id, ad_type_name, fields
1 general 1,2,3,4
2 real_estate 1,2,4,5
Well, store the values in columns and not in rows, so create a table and have 3 columns:
ad_type, property, value
define your properties for each type of ad and query the ad type for its fields.
Hope that helps

php/mysql classifieds view counter by date

Im building a classifieds website of adverts where I want to store a count of the number of views of each advert which I want to be able to display in a graph at a later date by day and month etc.. for each user and each of their adverts. Im just struggling with deciding how best to implement the mysql database to store potentially a large amount of data for each advert.
I am going to create a table for the page views as follows which would store a record for each view for each advert, for example if advert (id 1) has 200 views the table will store 200 records:
Advert_id (unique id of advert)
date_time (date and time of view)
ip_address ( unique ip address of person viewing advert)
page_referrer (url of referrer page)
As mentioned I am going to create the functionality for each member of the site to view a graph for the view statistics for each of their adverts so they can see how many total views each of their adverts have had, and also how many views their advert has had each day (between 2 given dates) and also how many views per month each advert has had. I'll do this by grouping by the date_time field.
If my site grows quite large and for example has 40,000 adverts and each advert has on average 3,000 page views, that would mean the table has 120 Million records. Is this too large ? and would the mysql queries to produce the graphs be very slow?
Do you think the table and method above is the best way to store these advert view statistics or is there a better way to do this?
Unless you really need to store all that data it would probably be better to just increment the count when the advert is viewed. So you just have one row for each advert (or even a column in the row for the advert).
Another option is to save this into a text file and then process it offline but it's generally better to process data as you get it and incorporate that into your applications process.
If you really need to save all of that data then rotating the log table weekly maybe (after processing it) would reduce the overhead of storing all of that information indefinitely.
I was working with website with 50.000 unique visitors per day, and i had same table as you.
Table was growthing ~200-500 MB/day, but i was able to clean table every day.
Best option is make second table, count visitors every day, add result to 2nd table, and flush 1st table.
first table example:
advert_id
date & time
ip address
page referrer
second table example (for graph):
advert_id
date
visitors
unique visitors
Example SQL query to count unqiue visitors:
SELECT
advert_id,
Count(DISTINCT ip_address),
SUBSTRING(Date,1,10) as Date
FROM
adverts
GROUP BY
advert_id,
Date
Problem is not even perfomance (MySQL ISAM Engine is quite smart and fast), problem is storage such big data.
90% statistics tools (even google analytics or webalyzer) is making graphs only once per day, not in real-time.
And quite good idea is store IP as INT using function ip2long()

The right way to implement multiple selects from database data (list menu or radio button?)

I am making a website that will show night club revelers events and night establishments in a big city. Events could number in the hundreds.
A user should be able to add certain details when adding their event on the site e.g.(in the events table) event_name, event_description, event_date, event_photo_url etc.
I want users to be able to search or find certain events or establishments based on interests or music genre.
I have an interest table and a genre table in MySQL:
interests table
interest_id interest-name
1 Shoot Pool
2 Karaoke
3 Lounge
4 Live Band
5 Dance
6 Watch Sports
genre table
genre_id genre_name
1 Hip Hop
2 Soul
3 Reggae
4 Pop
5 Bangra
6 Rock
7 House
8 Country
9 Gospel
10 Carribean
11 Bongo
12 Genge
13 Mugithi
14 Dholuo
15 Kamba
16 Classical
17 Childrens
18 Latin
19 Jazz
20 Musicals
21 Middle Eastern
I have 2 other tables to link events with genres and events with interests ie;
event_genre table
event_genre_id
event_id
genre_id
and event_interest table
event_interest_id
event_id
interest_id
An establishment or event can have more than one interest e.g a club where one can play pool and watch the game. The same goes with music genres. A wide variety of music can be played in an establishment or event.
A user whould be able to make multiple selects from genres and interests.
My question is, do I have drop down list menus for each of the interests and genres? Can I have multiple selects for a drop down list menu and/or radio buttons? Is there a better way of implementing what I need?
I would go with a mess of checkboxes. The user would be able to check all of the interests or whatever that they are interested in. To process this you would just build a list of checked values and then pass that list into the query to filter the results. Make sense?
You could do two list boxes. This would allow you to select multiple genres and multiple interests in two simple controls which would save realestate and allow you to easily display and sort the available selections...
then on your server side you would just have to parse the values to build your query... THAT will probably be the hard part.
your value will more likely be returned as an array... not sure how that all works in php, but you would split your items down to an array object and basically loop through them.
you would then add AND genre = arItem(x) to your query and the same with interests.

Achievements / Badges system

I have been browsing this site for the answer but I'm still a little unsure how to plan a similar system in its database structure and implementation.
In PHP and MySQL it would be clear that some achievements are earned immediately (when a specialized action is taken, in SO case: Filled out all profile fields), although I know SO updates and assigns badges after a certain amount of time. With so many users & badges wouldn't this create performance problems (in terms of scale: high number of both users & badges).
So the database structure I assume would something as simple as:
Badges | Badges_User | User
----------------------------------------------
bd_id | bd_id | user_id
bd_name | user_id | etc
bd_desc | assigned(bool) |
| assigned_at |
But as some people have said it would be better to have an incremental style approach so a user who has 1,000,000 forum posts wont slow any function down.
Would it then be another table for badges that could be incremental or just a 'progress' field in the badges_user table above?
Thanks for reading and please focus on the scalability of the desired system (like SO thousands of users and 20 to 40 badges).
EDIT: to some iron out some confusion I had assigned_at as a Date/Time, the criteria for awarding the badge would be best placed inside prepared queries/functions for each badge wouldn't it? (better flexibility)
I think the structure you've suggested (without the "assigned" field as per the comments) would work, with the addition of an additional table, say "Submissions_User", containing a reference to user_id & an incrementing field for counting submissions. Then all you'd need is an "event listener" as per this post and methinks you'd be set.
EDIT: For the achievement badges, run the event listener upon each submission (only for the user making the submission of course), and award any relevant badge on the spot. For the time-based badges, I would run a CRON job each night. Loop through the complete user list once and award badges as applicable.
regarding the sketch you included: get rid of the boolean column on badges_user. it makes no sense there: that relation is defined in terms of the predicate "user user_id earned the badge bd_id at assigned_at".
as for your overall question: define the schema to be relational without regard for speed first (that'll get you rid of half of potential perf. problems, possibly in exchange for different perf. problems), index it properly (what's proper depends on the query patterns), then if it's slow, derive a (still relational) design from that that's faster. like you may need to have some aggregates precomputed, etc.
I would keep a similar type structure to what you have
Badges(badge_id, badge_name, badge_desc)
Users(user_id, etc)
UserBadges(badge_id, user_id, date_awarded)
And then add tracking table(s) depending on what you want to track and # what detail level... then you can update the table accordingly and set triggers on it to "award" the badges
User_Activity(user_id, posts, upvotes, downvotes, etc...)
You can also track stats from the other direction too and trigger badge awards
Posts(post_id, user_id, upvotes, downvotes, etc...)
Some other good points are made here
I think this is one of those cases where your many-to-many table (Badges_User) is appropriate.
But with a small alteration so that unassigned badges isn't stored.
I assume assigned_at is a date and/or time.
Default is that the user does not have the badges.
Badges | Badges_User | User
----------------------------------------------
bd_id | bd_id | user_id
bd_name | user_id | etc
bd_desc | assigned_at |
| |
This way only badges actually awarded is stored.
A Badges_User row is only created when a user gets a badge.
Regards
Sigersted

Categories