MySQL trigger to create and delete tables, make inserts and delete rows - mysql

The Situation:
So, on my website, I want to give users the opportunity to save complex sets of data from their excel tables. Since there will be a large number of users and limited resources, I don't want to store all the data in one single table.
My idea is to have tables where descriptive information is stored for the dataset the user wants to create. E.g.
Table: UserDatasets_sets
id, name, userid
Table: UserDatasets_columns
id, fk_UserDatasets_sets, name, type, length, etc...
And then at some place to run a mysql trigger that would
a) create a table of the name that is passed to be inserted with a certain prefix. E.g. 'UD_' + UserDatasets_sets.name and all the columns from the ..._columns table and an extra column fk_Acl.
b) Because I want to also give my users the opportunity to set permissions on the individual entries of their tables, I would then like to store a trigger for this newly created table. So that whenever a row is inserted, a corresponding row is created in the ACL table and the id is then set as the fk_Acl value on the user's table.
c) Last but not least, I would also like to store the same triggers in reverse, so that whenever a user deletes his dataset in the UserDatasets_sets table, the corresponding table gets deleted. The rest that is connected to this action could be deleted by cascading, right?
My Question:
Is this even possible to do as a trigger? (The reason why I would like to do this: I don't want to waste cpu and memory on running the more demanding php alternative.)
What would a query to store this trigger look like?

Related

Database design and layout

I want to revisit a project I made to store user data into a database and improve on the way it is stored. I currently went the hard way about it and stored user data in JSON format within a MySQL database field making it difficult to complete CRUD actions. The reason I did this was to keep all the user's data within the user's field. And was reasonably new to this.
I didn't want to store the data mixed with other user's data and as I thought there may be issues with increased users. for example,
If I had 1000 users with 500 rows of data for each, that's 500 000 rows to sort through when reading the data and displaying it on a web page. And is there a risk of mixing the data up or performance issues?
I basically just want a user database that stores the user's id, name, and credentials. Then another database that will store data from a user's activity(run). So at least 5 fields for each event: Time, location, date, duration, etc. And this will be saved for different events(runs) which could end up in the 100's over a period of time.
My question is, Should I design the table as above. Or would it be better to have a table for each user? Or are there other options that I have not explored?
Given the information shared, I believe below mentioned design may be suitable.
Create a Table called User_Details with columns as id (auto increment),user id, name and credentials.
Now create a User_Activity Table with these columns id, user_id, event name, data(json field).
Explanation:
The User Activity table will store the event data for you related to each user through user_id field to user_details table. The data which is a json field will help you to store all the fields for the event. As you are using json field in DB it will allow you to dump any number of fields for the event which may/may not be structured. You can then map this in your middle layer as required.
Also, in case you have finite number of events then you can also create a table called user_event_types and have column id, event name and then in user_activity table you can refer the id instead of event name.

MySQL count selected rows in one table to update value in another table

I have created a table ("texts" table) for storing ocr text from scanned documents. The table now has 100,000 + records. It stores a separate record for each page in the document. I set up the table originally so it stored the documents' title and its location against each record, which was obviously bad design as the info was duplicated for many records. I have subsequently created a separate table which now only stores one record for each document ("documents" table). The original table still contains a record for each page in the document, but the only columns now are the ocr text and the id of the document record in the documents table.
The documents table has a column "total_pages". I am trying to update this value using the following query:
UPDATE documents SET total_pages=(SELECT Count(*) from texts where texts.docs_id=documents.id)
This just seems to take forever to execute and I have had to crash out of it on a couple of occasions. There are over 8000 records in the documents table.
I have tested the query by limiting it to just one document
UPDATE documents SET total_pages=(SELECT Count(*) from texts where texts.docs_id=documents.id and documents.id=1)
This works eventually with just one record, but it takes a very long time to execute. I am guessing that my full query needs a bit of optimization! Any help greatly appreciated.
This is your query:
UPDATE documents
SET total_pages = (SELECT Count(*)
from texts
where texts.docs_id = documents.id)
For performance, you want an index on texts(docs_id). That will probably fix your performance problem. In fact, it might make it unnecessary to store this value in the master table.
If you do decide to store the count, be sure that you keep the value up-to-date. That would typically require a trigger to handle inserts and dates (and perhaps updates, if doc_id changes).

Need help on Mysql Database Structure

I have 200 users each user will eventually have a "reviewINFO" table with certain data.
Each user will have a review every 3 to 4 months
So for every review, it creates a new row inside the "reviewINFO" table.
This is where i'm stuck. I'm not sure if I need to serialize a table inside each row or not.
Example:
-> links
"USER1reviewINFO"-row1->USER1table1
-row2->USER1table2
-row3->USER1table3
-row4->USER1table4
-row5->USER1table5
"USER2reviewINFO"-row1->USER2table1
-row2->USER2table2
-row3->USER2table3
-row4->USER2table4
-row5->USER2table5
using this method it will make a couple of thousand rows within two years. And I think its harder to manage.
"Userxtablex" is a table with dynamic rows of children names,ages,boolean
What i'm think of doing is serialize each USERxtable into its corresponding row.
Please help as I would not like to make this complicate or inefficient
Generally, you should never have to serialize data of this nature into a table row to accomplish what your goal is (which I am assuming is an implicit link between a user and a review)
What you need to do is key the reviews by a user_id such that all the reviews are packaged in one table, and relate numerically back to the users table.
Assuming you have an AUTO_INCREMENT primary key in the user table, all you would need is a user_id field in the reviews table that represents what user the review relates to. There is no need for a separate structure for each user, if that's what you are suggesting. Reviews can have date fields as well, so you can perform queries for a specific year or window of time.
You can then use a JOIN query to select out your data set relating to a particular user or review, and apply the usual WHERE clause to determine what result set you want to fetch.

sync records of two tables in the same database in MYSQL

I have two tables with some same fields like:
Table A: fname, lname, address, age, email, mobile, website, blog
Table B: fname, lname, address, age, email
Both these tables are used by different modules on my website. I want to sync the first five fields of both tables in such a way that whenever a new row is added or an existing row is modified in Table A, the Table B is updated automatically and vice versa.
For Example.
A user created a new record in Table A. Now the Table B should also be updated with this new information. and vice versa if a user creates a new record in Table B, the Table A should also be updated with this new information.
A user modified a record in Table A. Now the Table B should also be updated with this modified information. and vice versa if a user modifies a new record in Table B, the Table A should also be updated with this modified information.
How can I achieve this. I thought of using triggers but would it not create an inifinite loop resulting is server error!
Is any field among those 5 guaranteed to be unique? You could add a conditional to the trigger to check to see if that field exists before inserting the record in the table.
You might want to rethink the design also. Storing duplicate records in 2 places seems a little scaring. You're going to have to have triggers for updates, inserts, and deletes.
If u just need to update one table in case the other table gets updated, Instead of creating a table (as a part of some other table), create a View which is also like a table but virtual (not real).
but since u've asked for both sides update.
What I believe is that you should go back little back of this problem....and tell us why u need to update both the tables according to the other table,,,
Because you are just keeping duplicate data at two places that is of no need.
So, try to think whether it can be done without creating two tables, or something like create one table and one view for partial columns requirement.
It is not an answer to your problem, but I am trying to solve your problem in an optimized way which is good for everyone's health....
Hope you understood what i tried to tell. :)

MYSQL Trigger to update table that is based on two other tables

I've created a table name 'combined_data' using data from two tables 'store_data' and 'hd_data'. The two tables share a common column which I used to link the data when creating the new table and that is 'store_num'. What happens is when a user submits information to 'store_data' I want info from that submit such as store_num, store_name, etc to move into the 'combined_data' table as well as pull information from the 'hd_data' that pertains to the particular store_num entered such as region, division etc. Trying to come up with the structure to do this, I can fill in table names and column names just fine. Just curious if this is doable or if another solution should be sought out?
This is a common situation when saving data and requires to be split into 2 or more different repositories. I would create a stored procedure, and pass everything into a transaction, so if at any time something fails, it would roll back, and you would have consistency between your tables.
However, yes you can also do it with a trigger on insert of data on either store_data, or hd_data, if you would like to keep it simple.