Handling deletion and renaming of relational records - php

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.

Related

Warehouse Inventory Database Modal

I got my first professional project where I have to create a warehouse inventory web application. I have completed the front-end however I am stuck on the database modal - I'm not entirely sure if I got it right.
(ignore the scribble)
Basically, the company only needs to keep track of their stock level in each of their warehouse and do not need to add supplier details or any cost/sale prices.
These are all the tables and links I could think of however, even though this might work (or not), is this the correct design modal? (specifially the central table)
.
.
Right and Wrong are not absolute. That being said, here is my opinion on your model:
1) Are you sure purchases and sales should be two different tables? They have the same fields. Make them one and add a field that determines whether it's a purchase or sale.
2) The fact that the stock table has the same keys (warehouse,item) that the sales/purchases,inventory, and transfers table does not make it a logical centre table. My design would be:
Tables barcodes,items,warehouses as you already have them.
The remaining tables should have foreign keys on items,or warehouses, or both, whatever exists. There is no reason to make a 2-field FK towards the stock-locations table
The transfers item should have both warehouse_from and warehouse_to FK referenceing warehouses. And item, of course.

Database set up for multi-way relationships and form data collecting

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.

Handling one-to-many references in MySQL

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.

User's custom profile fields

I am currently working on a system that would allow users to add additional custom fields for the contacts that they add.
I wondered what is the best and most efficient approach to add such ability?
Right now what I was thinking was to have 1 table per users (with foreign keys to a "main" contacts table) and then adding a column for each custom fields that the user adds (since I don't expect to have more then 100-200 users per database shards [sharding is easy since every users never see each-other's content in this system]), although I am not 100% sure that this would be the right solution for such problems.
Maybe you could try to have one separated table to store a reference to the user, plus the field name and value, this way you will be able to have lots of custom fields.
If you go with Boyce-Codd, you separate the information and store them into a table.
Means one table for all users with a foreign key.
One table per user would lead to hundreds or more tables with possible repeated information.
You need to have one table named USERS that stores the id of a user and fixed info you might want. Then, you could have a CONTACT table, that stores the type of contact user might create, and one matching table USER_CONTACT that matches the user unique id with the id of the contact that was created.
With this, you could have advanced data mining on all the information stored, like nowing how many contacts each user created, who created more, etc...

CakePHP: HABTM + 1

I have a site that scrapes all the episodes from tv.com from certain series.
So my database has a User table, a Show table, an Episode table, a Show_User table (to associate shows with users, HABTM), an Episode_Show table (to associate episodes with shows, HABTM), a Episode_User table (to associate episodes with shows, only as a way of marking them as 'watched').
Now I want to add a way of marking an episode as 'downloaded' too.
So at the moment, the Episode_User table has two fields, Episode_Id and User_Id. Should I create a new table entirely for this? Or just add a field to the Episode_User table?
I'm using CakePHP's automagic features, and don't particularly want to break it. But if I have to, I have to...
Thanks for any advice.
I don't see why you would want to create a new table for episodes a user has downloaded. To me it would make the most sense to modify the Episode_User table to have a field for watched and a field for downloaded, since it's all relating back to the same pair of entities, users and episodes.
However, any time I've stored information about a relationship between two tables in that manner, I've found that regardless of the framework I'm using, the ORM inevitably become more complicated, but I don't think there's any way around there.
With CakePHP for handling those kinds of complicated situations, read up about the model behavior, Containable. It's not very well documented in the CakePHP book, but is really quite useful in a situation where you need to use the fields in Episode_User, for example, if you needed to find all of the users that had watched a particular episode, but not downloaded it.
Also, it occurred to me, while reading your post, that you could possibly make your data model more simple by having a hasMany relationship between shows and episodes. An episode will never belong to more than one show, so your episodes table could just have another field, show_id, which related back to the show table, and you wouldn't even need the Episode_Show table.

Categories