So I need to make a checklist for a web app where an administrator can edit a checklist for a user. The administrator can check those when a certain condition is met and also write a comment about it if necessary.
I set up 3 tables:
A user table which stores all the user information like name, birthplace and so on. Primary key is user_idnr
Then I have a table called CHECKLIST_properties. It stores all the different items of the checkbox. It has the following columns:
property_idnr | type | description
Finally, I have a table called CHECKLIST_user_property. It is used to link a property to a user, when a row is created, it is checked. It has the following columns:
link_idnr | user_idnr | property_idnr | comments
I am having trouble planning out how to save the checked boxes in the database. You need to determine when a row needs to be added or removed from the table. Can anyone give me some tips on how to set this up properly?
I see a couple of options:
remove all the rows and add the currently selected ones back in. This can have unintended side-effects (new auto incrementing numbers, etc).
add a column that is used to track the status of the rows. Use INSERT ... ON DUPLICATE KEY UPDATE to add rows to the table and/or update existing rows. The new/updated rows would have a different value in the new column (like a timestamp). Then delete all the rows with an older value (as they weren't added/updated, they're not needed).
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 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.
I have a table dislikes which contains two columns, idone and idtwo.
These are unique ids' from users, for example:
| idone | idtwo |
-----------------
| 5 | 4 |
This means that user with id=5 does not like user with id=4. What I have in PHP is an array containing the ids' of all the users that the current user has selected as not liking them.
So say dislikes={1,2,3}, this means that the current user does not like user 1,2, or 3. There is an unknown number of users in the database.
So if user 1 chooses to dislike user 2 and user 3 (this is done via HTML dropdown), I pass dislike={2,3} to a PHP page which processes this data.
I want the PHP page to then add entries (1,2) and (1,3). Here is the first problem, how can I make sure only to add unique entries?
Also say that user 1 changes the fact that he dislikes user 2. Then I pass dislike={3} to the php page and must somehow remove all entries (1,!3), i.e. all entries in which user 1 dislikes anyone except user 3. How can I achieve this? Or is there a better way?
Since you're using MySQL the easiest thing is probably to use REPLACE INTO instead of INSERT with a primary key or unique index on the pair of columns (idone, idtwo).
Alternatively, on update, you can run a transaction that does any one of:
Remove existing rows for this user, add all rows, commit
Select existing rows, remove the rows from your local set that you would duplicate, add only new rows, commit
I'm currently having a single activity table that references other tables depending on the type of activity.
id | type | user_id | source_id | misc_id | date
The type column tells me what kind of activity the user has performed (follow, liked, befriend, status etc.) and the source id contains the table id relative to the type of action.
This is working well for a user activity stream, but the only problem is, I can't figure out what to do about rows that no longer exist in the relative tables?
E.g. a user creates a status and then deletes it, or a user becomes friends with somebody that is later deleted from the database.
If the activity was relative to a single type, then I would be able to add a foreign key constraint, which would remove the row; but as it's relative to different tables, how else could I go about doing this?
You will have to take either of these approaches.
When the user deletes, just do the soft delete on the backend by marking them as deleted instead of hard deleting from the table. You will have to introduce a new column "delete_flag" in this approach.
Archive the tables and move the records to a different table when deleted. But this would be complex coding wise as well as the performance might not be as expected.
Here are my thoughts.
If users can delete something, you can record this also in your activity table.
I you want to hide that activity, you can add ReversedOn field and update it with the relevant date. Then you will just have to filter out activities that don't exist.
If that does not cause any user experience problems, then you can just let it be.
I have a MySQL database with a growing number of users and each user has a list of items they want and of items they have - and each user has a specific ID
The current database was created some time ago and it currently has each users with a specific row in a WANT or HAVE table with 50 columns per row with the user id as the primary key and each item WANT or HAVE has a specific id number.
this currently limits the addition of 50 items per user and greatly complicates searches and other functions with the databases
When redoing the database - would it be viable to instead simply create a 2 column WANT and HAVE table with each row having the user ID and the Item ID. That way there is no 'theoretical' limit to items per user.
Each time a member loads the profile page - a list of their want and have items will then be compiled using a simple SELECT WHERE ID = ##### statement from the have or want table
Furthermore i would need to make comparisons of user to user item lists, most common items, user with most items, complete user searches for items that one user wants and the other user has... - blah blah
The amount of users will range from 5000 - 20000
and each user averages about 15 - 20 items
will this be a viable MySQL structure or do i have to rethink my strategy?
Thanks alot for your help!
This will certainly be a viable structure in mysql. It can handle very large amounts of data. When you build it though, make sure that you put proper indexes on the user/item IDs so that the queries will return nice and quick.
This is called a one to many relationship in database terms.
Table1 holds:
userName | ID
Table2 holds:
userID | ItemID
You simply put as many rows into the second table as you want.
In your case, I would probably structure the tables as this:
users
id | userName | otherFieldsAsNeeded
items
userID | itemID | needWantID
This way, you can either have a simple lookup for needWantID - for example 1 for Need, 2 for Want. But later down the track, you can add 3 for wishlist for example.
Edit: just make sure that you aren't storing your item information in table items just store the user relationship to the item. Have all the item information in a table (itemDetails for example) which holds your descriptions, prices and whatever else you want.
I would recommend 2 tables, a Wants table and a Have table. Each table would have a user_id and product_id. I think this is the most normalized and gives you "unlimited" items per user.
Or, you could have one table with a user_id, product_id, and type ('WANT' or 'HAVE'). I would probably go with option 1.
As you mentioned in your question, yes, it would make much more sense to have a separate tables for WANTs and HAVEs. These tables could have an Id column which would relate the row to the user, and a column that actually dictates what the WANT or HAVE item is. This method would allow for much more room to expand.
It should be noted that if you have a lot of of these rows, you may need to increase the capacity of your server in order to maintain quick queries. If you have millions of rows, they will have a great deal of strain on the server (depending on your setup).
What you're theorizing is a very legitimate database structure. For a many to many relationship (which is what you want), the only way I've seen this done is to, like you say, have a relationships table with user_id and item_it as the columns. You could expand on it, but that's the basic idea.
This design is much more flexible and allows for the infinite items per user that you want.
In order to handle wants and have, you could create two tables or you could just use one and have a third column which would hold just one byte, indicating whether the user/item match is a want or a need. Depending on the specifics of your projects, either would be a viable option.
So, what you would end up with is at least the following tables:
Table: users
Cols:
user_id
any other user info
Table: relationships
Cols:
user_id
item_id
type (1 byte/boolean)
Table: items
Cols:
item_id
any other item info
Hope that helps!