select, insert and loop for rows in cronjob - mysql

I have a small giveaway table and I need cronjobs in MySQL to make it automatic.
giveaways_participants table
This is where your user id gets added when you participate in a giveaway.
id | user_id | giveaway_id
__________________________
1 | 1 | 4
2 | 67 | 39
giveaways table
All giveaways available
id | user_id | contents | expires
__________________________
1 | 1 | 4,189,45,7 | 1512484213
2 | 67 | 39 | 1512484213
3 | 67 | 8,2,645 | 1512484213
inventory table
The users inventory
id | user_id | item_id
__________________________
1 | 1 | 4
2 | 67 | 2
3 | 67 | 7
I want the cronjob to daily go through giveaways that have expired (ended), pick a random winner from giveaways_participants for that specific giveaway and insert the contents from giveaways into inventory as a new row for every item separated by a comma for that user.
How can this be achieved in the most efficient way possible?

I would just create a php page (if it's possible for you) which can be called from crontab, like php dailyga.php.
What would be in that page? Select from giveaway's table, which data has just expired and pick it's id. Then select all ids from your users and pick random one, then insert into inventory that user's ID and giveaway ID.
Setting a cron job for every morning would do the job (or midnight etc.).
How to pick just expired giveaway? Just select those which expiry date is in the past (even a minute), but the youngest - or the one for which there is no entry in inventory table.
Hope I helped a little.

Related

Users queue in mysql

I'm trying to create queues table
id | queue_id | user_id | is_active_to_vote
1 | 14 | 1 | 1
2 | 14 | 2 | 0
3 | 14 | 3 | 0
4 | 15 | 1 | 1
5 | 15 | 2 | 0
6 | 15 | 3 | 0
the users list in result looks like this (for queue_id=14)
Sam (user_id=1 votes now)
John (user_id=2)
Bill (user_id=3)
But if user did not vote in time I need to resort the queue like this
John (user_id=2 votes now)
Bill (user_id=3)
...
Sam (user_id=1 last user in queue)
What is the good way to do this?
Since you're using "did not vote in time" information in order to sort your queue, you need that information on voting time somewhere - either in a new field in your current table, or in a separate table.
Once you have that, you'll be able to sort the queue based on the criteria you want (which aren't clear to me at this point - is it user_id by default ?).
Note that in general I would advise you to perform queue management in your application controller, not directly in MySQL.

Improve relationship between 3 tables in MySQL

I have 3 tables on my database: users, payment_methods and user_blocked_pm. The users table speaks for itself, the payment_methods stores all the payment methods the company uses, and the user_blocked_pm has the payment methods blocked for a specific user.
+------------------+
| users |
+-----+------------+
| id | user_name |
+-----+------------+
| 1 | John |
| 2 | Davis |
+-----+------------+
+-----------------------+
| payment_methods |
+-----+-----------------+
| id | payment_method |
+-----+-----------------+
| 1 | credit_card |
| 2 | cash |
+-----+-----------------+
+-----------------------------------+
| user_blocked_pm |
+-----+---------+-------------------+
| id | user_id | payment_method_id |
+-----+---------+-------------------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 2 |
+-----+---------+-------------------+
So, following the structure above, both payment_methods are blocked for the user John and cash is blocked for Davis.
Following this structure when there are multiple users and payment methods I'll have multiple records on user_blocked_pm because each user will be allowed to use only a few of the payment methods.
Is there a better way to work this relationship between the users and the user_blocked_pm so that the table doesn't get gigantic?
You do not need the id column in user_blocked_pm table because you going to select on user_id or pm_id
If the number of the allowed pm is less then the number of the not allowed, why not to make a user_allowed_pm table instead of user_blocked_pm
If you have a fixed number of pm for each user then you do not need a table just you create a column for every pm and you put the key of the pm (like a foreign key)
If you have a few user "types", then perhaps you can replace the user_blocked_pm with a user_type_blocked_pm. A "type" is a set of blocked/permitted payment methods. So the user_type_blocked_pm table is small -- has entries for the different types (users who can pay with cash only, users who can pay with credit and cash, etc. ) Then, you can add a column to the users table to indicate the user type.
Your method is fine, and the other ideas so far suggested are also fine. If the number of payment types is small (not more than 7, say - and certainly less than 64!), and finite, then you might also consider a bitwise method, where 1 = credit_card, 2 = cash, and 3 = both. I do this for days of the week, which are unlikely to ever be more than 7.

How to create mysql db for account balace, add and subtract amounts

I have project like online service, i have made some part and stopped. If user use service it must take some amount (e.g. 5$ per service). I don't know how to build MySQL tables. I have made 2 tables 1st for rest amount 2nd for add and subtract amounts. May be this is wrong way, what is the best practice?
action_table
id | userId | reason | amount
1 | 4 | for service 3 | -5
2 | 2 | refill account | 100
3 | 13 | for service 3 | -5
balance_table
1 | 4 | 23
2 | 2 | 125
3 | 13 | 0
After using service query adds one row to action_table and updates balance_table
Personally, if I was making an account database, I would have one table for an account and one for transactions, like this:
Accounts:
| id | user | name | balance |
Transactions:
| id | account_id | description | amount | is_withdrawal |
The reason I came up with this is because it helps to think of database tables like real world objects sometimes, and in this case you have a Transaction and an Account.
Then, you can use a TRIGGER to update the account table anytime you add a transaction.

How to delete half the records of a table?

I have this table that holds user relations of a social network website with the following structure.
+--------+----------------+
| user_id| friend_user_id |
+--------+----------------+
And there is 2 record for every individual relationship in the table. Something like the following:
+--------+----------------+
| user_id| friend_user_id |
+--------+----------------+
| 1 | 2 |
| 2 | 1 |
| 4 | 7 |
| 8 | 15 |
| 7 | 4 |
| 15 | 8 |
+--------+----------------+
Now what I need to do is for every single relationship to be only one record present. Meaning I need to delete every second record of every relationship.
I have tried various queries to no avail. If anyone could come up with the suitable query I'll be truly grateful.
It looks like the relationships exist in pairs. So user A has user B as a friend and user B has user A as a friend. If I read your question right, you want to remove one of the relationships but leave the other.
Since they have different user_ids, you could delete all the rows where user_id is greater than friend_user_id. That would delete one of the relationships but keep the other.
delete table where user_id > friend_user_id

Manage popularity trends of database records

I need to create a system to order some articles by they popularity, like a trend.
I have this table:
| Id | Title | View |
| 1 | aaa | 232 |
| 2 | bbb | 132 |
| 3 | ccc | 629 |
This way I can easilly order by number of view, but if I want to show the populars articles in the last period (not definited) and not the articles that have a lot of views but they are not longer visit? Exist a technique? I have to track all visits?
You could have a daily_views/hourly_views table according to your needs with :
ID startTime endTime number_of_views
and INSERT/UPDATE that table every time you have a new view. That way you don't have to insert a record for each view and you can have queries for different time periods.