I'm coding a website where users can add concerts/events and other users can modify the informations provided for every concert/event added on the website.
I want to save every modification that has been made and the user that made the modification. For instance there is this functionnality on Wikipedia where every article has saves of every modification made and the user who made it.
For now, I just save the name of the user who made the last modification(s), and the modifications aren't saved: when a modification is made it will just overwrite the previous value of the corresponding column.
You can see under the current state of the tables I'm talking about. One for concerts with different informations: artist, date of the event, hour, links related to the event etc...
and another one for users.
Current sql tables
I think a first step would to create separate tables for every element of a concert that can be modified, with 2 foreign keys (one linked to user, one linked to concert) plus the value of the element. But still, if a modification is made I still don't know how to save the previous value and previous user.
I've thought of puting values inside an array but I don't know if this is possible in SQL and if this is the best solution.
Thanks for reading/helping
You should add a column that mark the create/update time to the concert table.
Then create a new history table (same schema of concert) for storing concert changes.
When a user edit a concert:
Save the current state of concert content to the history table.
Update the new change to the concert table with the user_id of the user who perform this action
That's it! When you want to list the changes history, just query the history table!
If you want to log the delete operations as well, add another column and mark the end period of each version (a little bit more complex)
Related
currently I found myself wondering if this is the right thing to do in this case.
You see I have a database called for example Warehouse
I this database I have two tables:
[the table items is for saving the items of the system add-modify-delete records]
Items (which its columns are )
TAG_ID
P_NUMBER
QUANTITY
TYPE
LOCATION
DESCRIPTION
REASON
USERID
DATE
[the table lastchanges is for saving the items of the system that has been changed]
lastchanges (which its columns are )
ID
TAGID
PNUMBER
USERID
ACTION
DATING
Now I have been asked to add "exactly what has been changed" to the current form, for example if the quantity changed I have to show that before and after in a bootstrap form.
My brain told me to just add all the columns of the table items into lastchanges and save on those columns the data before changing and into items the new modified data, but performance-wise I see this as a bad action and I want your opinion.
If I understand you correctly you need a history of your DB changes.
If thats the point I would recommend you to create a new row for each entry and soft delete the old one. Then nothing gets lost and you can always get differences or older values.
Adding a the field deleted_at, and created_at as dates would do that trick for you. If deleted_at is null its the current entry, if there is a date set you know exactly when it got "overwritten"
I've posted a few questions on here and have gotten very great help and support. I'm still fairly new to programming and I'm putting together what I thought would be a simple website for the company I work at. I apologize in advance for my lengthy post/question, I just want to be thorough and clear in what I'm asking. My question is more of needing some help getting pointed in the right direction of how to get started and some best practices to be aware of. What I'm working on right now is to create a system where a user can submit a questionnaire/online form to inquire about a specific product (in this case it's a hard money loan product). The way I am planning on setting it up is to have a database with multiple tables (users, user_info, loan_app, property) and connect these together by referencing each other. I've read about table joins and I understand them conceptually but I have no idea how to implement in practice. I've had a hard time finding actual examples.
Specifically, this is what I am doing and how I am thinking it should work (correct me if I'm wrong or if there's a better way to do it):
1- the user (aka the borrower) signs in to the website. The user log in system references the user table where things like first name, last name, user name, password and user ID are stored. I have included an "active" column in this table so that when a user logs in the condition for them to get into the website is that the username and password match AND the user is activated. This way we can control on the back end certain user accounts access. I have this part working.
2- when the user registers, they only fill out the information that creates a new record in the "user" table. I have created a second table called "user_info" that will contain other data like home address, phone number email etc. But I need to be able to associate the correct record with right user. This is my first issue to wrap my head around. My thinking behind doing this instead of simply putting all this information in the user table is that for one, I might keep adding to that table and make it very big, and two for security reasons, I would like to keep the information separate. I don't know if this thought process has any merit to it though. Again, that's why I'm posting this here.
3- The user, once logged in, clicks on a button on their home screen/dashboard that will take them to the loan "pre-approval application" form, which is the questionnaire. On this form their basic information will be echoed/posted from the "user_info" table to pre-populate certain fields like first name, last name, email, phone number, address etc. So going back to #2 making sure I can associate the user with the correct record in the "user_info" table is critical. THEN, there are additional fields that the user has to fill out in order to submit the application/questionnaire. These form fields will create a new record in the "loan_app" table. This table will have a loanid column that is the primary key for that table, and an auto generated/randomized 6 or 7 digit loan number (loannum). The loanid will be a hidden value but the loan number will be like a reference number that is associated with the loan for the life of it and used for later accounting and recording purposes internally, whether or not it actually becomes a loan. The loanid, I'm assuming here, is the Foreign key in the "user" table and the userid is the Foreign key in the "loan_app" and "user_info" tables correct? If so, how do I incorporate being able to simultaneously associate all these records when the loan application/questionnaire is submitted? My thought would be write individual php scripts that does each of these things separately then have a "master" php that includes all of those individual ones that is placed as the form action associated with the submit button on the form.
Thanks for taking the time to read through this. I'd really appreciate any advice or reference material that I can read up on to learn more about this stuff. My job has a pretty crazy schedule and I travel a lot so I don't have the time to take actual classes to learn this stuff formally. I'm pretty much doing this as I go.
Also, I'm using MAMP with mysql, not sure if that helps any or not...
The user table's primary key userid can be the primary key of the user_info table as well, since each user will have only one user_info record, right? A foreign key constraint is good to ensure only valid userids get recorded in user_info.
The loan_app table can contain a denormalized relationship from loanid to userid so that each loan application is associated with a user. Again, use an FK constraint for integrity.
Don't include loanid in the user table - that would mean each user has a relationship to a single loan application. You already have the one-to-many relationship you need in the loan_app table.
I didn't know how to give title to this but I have the following database:
accidentDetain(id, location, weather_conditions desc (and few more columns));
weatherConditions(id, title)
acc_weat_cond(id, wc_id, ad_id)
wc_id = weatherConditions ID, ad_id = accidentDetain ID
Now the situation is the user can store multiple weather conditions such as (rain, wet, snow Ice Fog etc)
Let's say user chooses 3 out of those 6 options and those will be stored in acc_weat_cond table, with accident Detail id and weather conditions id.
After saving, the user decided to change and to unchecked one of the option and then presses the save button. The issue is, there are 3 records already stored into acc_weat_cond table how would I would change and make them to two records.
Will I have to delete the first records from the database and then store again newly checked options? Or is there any easier way doing the above mentioned situation.
One last option is that I violate the role of database normalization and stored directly in the accidentDetails table and separate the values with a comma.
Feel free to ask if any more information is required...
I would have an <input type='hidden'name='checkedflds' value='1,2,3' />-field which contained the values that were checked before the user updated. Then after postback, you can compare the new list against this and will easily see what additions he made and which elements he removed...
I would call all of the options and compare to what is checked, and delete what you need. If you store it on the form, then there is a potential for out of date data.
In my database, I have two tables that are dedicated to handling recurring events.
An 'Events' table currently store names, descriptions, locations, start time and end time of events.
Another table, 'Episodes', takes the parent Event id as foreign key and stores event dates which are generated based on recurrency rules set with the PHP recursion library When. Recurrency logic and creation of all events-related database items is intended to happen in an Add/Edit/Delete-type interface.
This database structure follows what I consider a good suggestion from a forum thread on Devshed (the 6th post). My problem is that while this as far as I can understand allow the changing of date in single Episodes easily, the same is not the case if the user wants to change start and end times to a single Episode.
I want users to be able to easily modify the start and end time of all Episodes of an Event through a button in the UI, but at the same time be able to edit the start time and end time of single Episodes of an Event by clicking the event in a calendar, while also avoiding redundant start_time and end_time fields in the database. As I am relatively inexperienced with such issues in MySQL, some suggestions would be most welcome.
I'm developing a relational system, that involves the following entities:
Enquiry
Quote
Supplier
Town
Vehicle
Enquiry is the main model for the system and contains foreign keys for all the other entities.
Now what I'm concerned of is for example if the client goes and deletes a Town - the Enquiry record has a reference to the town id and would therefore break the system. Similarly if the client goes and deletes a Vehicle then Supplier records would break.
So what is the best way to handle deletions of relational records? Should we even offer the facility to delete records (perhaps have a enabled/disabled boolean switch instead?).
Similarly when renaming records how can we preserve original data for older records (for example if the client decided to rename Vehicle "Bus" to "Minibus").
If you want to handle this at the database level, Foreign Key constraints with Cascading Updates and Deletes is what you are looking for. For handling this within your application, use an ORM, like Doctrine.
what is the best way to handle deletions of relational records?
Only allow deletions of orphaned records? If I delete records from ENQUIRY that relate to a specific Vehicle, then someone should be able to remove that vehicle. But not before the child references have been dealt with... Pretty easy to handle using NOT EXISTS:
DELETE FROM VEHICLES
WHERE NOT EXISTS(SELECT NULL
FROM ENQUIRY e
WHERE e.vehicle_id = VEHICLES.vehicle_id)
Similarly when renaming records how can we preserve original data for older records (for example if the client decided to rename Vehicle "Bus" to "Minibus").
This is why you make the name/description separate from the primary key for using as a foreign key. If the VEHICLES table has two columns--vehicle_id and vehicle_description--then the description can change without referential integrity impact because you define the foreign key on the vehicle_id column.
There are several issues you have raised with this post. First, it may be beneficial to allow users with low permissions to soft-delete a record by toggling a isLive column as you indicated with a bit value. Secondly, you might benefit from the creation of a shadow table that will be used to record CRUD operations performed by the user. Through this, you will be able to record WHO made the change, WHAT type of change (Create/Update/Delete), WHERE the change was made (Table A, Column 1). Thirdly, you will want to handle the deletion of values bound by a foreign key carefully. You must delete all related connections prior to deleting from the source table. So you would delete the record in Enquiry before deleting the record in Town. Hope this helps..
This is a common problem. The user wants to delete 'Bus' because they don't use it any longer and don't want to see it on the Enquiry form. But you need the record because it's tied to five hundred older Enquiries.
Add an enabled/disabled or active/inactive flag to the record. Allow the user to disable records when they want. (Also allow them to reenable the records when they realize they were wrong.) Don't show disabled records on the Enquiry form, but keep them in the database to be able to show older data properly.
If you like, you can also allow deletion (actual removal from the database) if there is no Enquiry tied to the record. I personally don't show a delete button unless I'm sure a record can be deleted because I find users get frustrated if they can click the delete button but then are told they can't delete. So I check whether the record can be deleted before giving the option.
The problem of a user editing a record and changing the value from 'Bus' to 'Minibus' or from 'ACME Wallpaper, Inc.' to 'XYZ Catering' is one you have to live with. User education and making it easy to add new records is the only real way to handle it. Users have to be taught that ADDING and EDITING are different. Sometimes they have to be reminded with help-text on forms, warning messages, etc. I'm unaware of anything you can do programmatically that can accurately distinguish between a correction to a field, and a total change to the field.