MySQL - checking max rows during insert - mysql

We have a table where we limit the number of rows per user to a certain number. Before insert, we check if user has exceeded the storage capacity (number of rows) and then insert as appropriate. For example,
select count(id) from items where user=123;
say, if count < 10,
insert into items set user=123, a=xyx;
However, this approach requires two queries. Is there a way in which is can be done in a single query.
Thanks

Pretty much any approach you take will require two queries. Whether you do this in a trigger or in application code is a matter of choice.
If you use your method, then add an index on items(user). This will make it cheap to count the number of rows.
An alternative is to increment a value in the user table for each item. So, when a user inserts an item, then increment users.itemcount. Remember, though, to reduce the count when you delete items.

If you just want to have 1 query in a code you can try to use conditional insert with approach described here MySQL Conditional Insert

Related

Limit identical input in database to a certain count

I know that we can limit an identical input in database to only one by the keyword UNIQUE, but how about limiting it to more than one? For example, 3,4? Is there a way to achieve this?
The only way is to do it on your way by checking that amount before doing a new insert.
Before insert a new row, check how many identical rows there are and handle that case (e.g. don't perform the insert and/or show a message to the user).

How to adjust Auto Increment?

Good day to all. So I have lots of data in excel that i needed to insert in the db but I didn't notice I inserted a duplicate value (cause hr didn't sort it out).
So anyways, here is the deal
[id][name]
[1][name1]
[2][name2] // I want to delete this row
[3][name3]
[4][name4]
I want to delete row 2. I want to make the id auto adjust like,
[id][name]
[1][name1]
[2][name3] // The id will adjust
[3][name4]
Is this possible to achieve? Or if not is there a work around I can do?
PS: My data is already at 50k and I want to delete the rows in the 7k
In general, you should avoid manually intervening with an auto increment column. This means, among other things, that when you insert data into your table, you should omit the auto increment column, thereby allowing MySQL to automatically assign a value to it.
Perhaps the best solution here would be to have a third timestamp column which records when each record were inserted. Then, you may use ROW_NUMBER to generate the sequence you want, e.g.
SELECT
ROW_NUMBER() OVER (ORDER BY ts_column) id,
name
FROM yourTable
ORDER BY
id;
You might be able to also order ROW_NUMBER using the id column, and get the same result. If you are using a version of MySQL earlier than 8+, then you may simulate ROW_NUMBER using user variables.

MySql Triggers and performance

I have the following requirement. I have 4 MySQL databases and an application in which the user needs to get the count of number of records in tables of each of these databases. The issue is that count may change in every minute or second. So whenever the user mouse-hovering the particular UI area, I need to have a call to all these databases and get the count. I don’t think it is a best approach, as these tables contain millions of records and every time on mouse over, a dB call is going to all these databases.
Trigger is the one approach I found. Rather than we are pulling data from the database, I feel like whenever any insert/update/delete happening to these tables, a trigger will execute and that will increment/decrement the count in another table (which contain only the count of these tables). But I have read like triggers will affect database performance, but also read some situation trigger is the only solution.
So please guide me in my situation triggers are the solution? If it affects the database performance I don’t need that. Is there any other better approach for this problem?
Thanks
What I understood is you have 4 databases and n number of tables in each of them and when the user hovers over a particular area in your application the user should see the number of rows in that table.
I would suggest you to use count(*) to return the number of rows in each table in the database.Triggers are used to do something when a particular event like update,delete or insert occurs in a database.It's not a good idea to invoke triggers to react to user interactions like hovering.If you can tell me in which language you are designing the front end I can be more specific.
Example:
SELECT COUNT(*) FROM tablename where condition
OR
SELECT SQL_CALC_FOUND_ROWS * FROM tablename
WHERE condition
LIMIT 5;
SELECT FOUND_ROWS();
The second one is used when you want to limit the results but still return total number of rows found.Hope it helps.
Please don't use count(*). This is inefficient, possibly to the point of causing a table scan. If you can get to the information schema, this should return the result you need sub-second:
select table_rows from information_schema.tables where table_name = 'tablename'
If you can't for some reason, and your table has a primary key, try:
SELECT COUNT(field) FROM tablename
...where field is part of the primary key. This will be slower, especially on large tables, but still better than count(*).
Definitely don't use trigger.

How to create SQL table with limited entries?

I have a table that is used to store the latest actions the user did (like a ctrl+z for the program), but I want to limit this table to about 200 entries, and after that, every new entry would delete the oldest in the table.
Is there any option to make the table behave this way on SQL or do I need to add some code to the program to do it?
I've seen this kind of idea before, but I've rarely seen a case where it was a good idea.
Your table would need these columns in addition to columns for the normal data.
A column of type integer to hold the row number.
A column of type timestamp (standard SQL timestamp) to hold the time of the last update.
The normal approach to limit this table to 200 rows would be to add a check constraint to the column of row numbers. For example, CHECK (row_num between 1 and 200). MySQL doesn't enforce check constraints, so instead you'll need to use a foreign key reference to a table of row numbers (1 to 200).
All insert statements will need to determine whether the table is full, examine the time of the last update, and either a) insert a new row with a new row number, or b) delete the oldest row or overwrite it.
My advice? Renegotiate this requirement.
Assuming that "200" is not a hard limit, in other words if the number of entries occasionally went over that by a small amount it would be OK...
Don't do the pruning on line, do it as an off line process, run as often as needed to keep the totals per user from not getting "too high".
For example, one such solution would be to fire the SQL that does that query every hour using crontab.

Insert random number into table upon new record creation

I would like to store random numbers in one MySql table, randomly retrieve one and insert it into another table column each time a new record is created. I want to delete the retrieved number from the random number table as it is used.
The random numbers are 3 digit, there are 900 of them.
I have read several posts here that describe the problems using unique random numbers and triggering their insertion. I want to use this method as it seems to be reliable while generating few problems.
Can anyone here give me an example of a sql query that will accomplish the above? (If sql query is not the recommended way to do this please feel free to recommend a better method.)
Thank you for any help you can give.
I put together the two suggestions here and tried this trigger and query:
CREATE TRIGGER rand_num before
INSERT ON uau3h_users FOR EACH ROW
insert into uau3h_users (member_number)
select random_number from uau3h_rand900
where random_number not in (select member_number from uau3h_users)
order by random_number
limit 1
But it seems that there is already a trigger attached to that table so the new one cause a conflict, things stopped working until I removed it. Any ideas about how accomplish the same using another method?
You are only dealing with 900 records, so performance is not a major issue.
If you are doing a single insert into a table, you can do something like the following:
insert into t(rand)
select rand
from rand900
where rand not in (select rand from t)
order by rand()
limit 1
In other words, you don't have to continually delete from one table and move to the other. You can just choose to insert values that don't already exist. If performance is a concern, then indexes will help in this case.
More than likely you need to take a look into Triggers. You can do some stuff for instance after inserting a record in a table. Refer this link to more details.
http://dev.mysql.com/doc/refman/5.0/en/create-trigger.html