update existing entry practices - php

I have an application that allows users to enter reports, there are multiple tables that keep track of the data.
I am working on making an edit form to allow the user to edit an existing entry.
I need help with handeling the update query. Not the actual query, but understanding the best way to handle this.
For example:
A user adds an entry, they could select multiple departments.
Next, they edit that same entry, and select more departments and unselect a couple departments (from when they originally added that entry).
There is a table that keeps track of the entry and what departments it relates to: entry_id, department_id
When doing an update query, how do I update that table appropriately? Do I delete all entries where entry_id = 4 (just using any old number), and then just do an insert w/ all the departments that were selected? I am looking for best practices.
I am not asking for code that does, but just theory.

That looks like a good strategy to me. The alternative is to get the set of existing IDs, remove the IDs of this set that are not in the new set, and add the IDs that are in the new set but not in the old one.
But unless you need to keep some additional metadata on the association (time of creation, for example), the delete all and recreate approach is much simpler.

Related

Maintaining history table for PHP Application

I want to maintain the history table for my application to track what all the fields were changed by the user.
The following is my bugs_history table structure -
id, bugsid, userid, field_changed, old_value, new_value, created_on, created_by
So my query is, when I'll update my form and submit, how to get the field name that was changed along with old value and new value. And add the modified changes in the above history table.
I have googled a lot for this but didn't get as per my requirments. Please let me know how to achieve this.
If you know the field names (you have a HTML form containing them, so you probably know the names) then build a list of them that you then loop through, building a new SELECT query to get old_value and then an INSERT query to save it. The select would order on created_on DESC and LIMIT 1.
But I see a clear problem here: concurrency. What happens when two users try to edit the same bug (with the same bugsid) at the same time? They would expect the old_value to be the same for both? Or should the two operations be executed sequentially? Or should the last one to edit be warned that he's trying to edit stale data? Which one would get the "latest" created_on?
This right here is your real problem, not writing the code that generates two SQL queries.

Tagging pages with PHP and MySQL

I'm fairly new to MySQL and PHP, but I'm getting the hang of it slowly.
I'm working on a site with profile pages. I have a users table in my database and I intend to create a profile table too.
Before I explain my 'problem' I'd like to say I haven't actually began coding an attempted solution. I like to plan my work before I start it, especially when it is going to be complex. Therefore, I can't really display any snippets of code.
What I would like to create is a tagging system for the user profiles. ie. let the profile owner select keywords from an existing list, and associate them with his profile page.
After pondering plenty and reading up on relational databases I gathered I should start by creating two additional tables:
1. tags (tag_id, tag_name)
2. tag_rel (tag_id, user_id)
and create a relationship between each profile to the different tags a user assigned to it, on seperate rows:
(Tag1, UserA)
(Tag2, UserA)
(Tag1, UserB)
etc.
Then when I search for profiles I simply have to select all user_ids with a specific tag_id. Easy enough.
My issue is the PHP and MYSQL Query code when inserting or changing the list.
I would essentially want the user to be able to either choose from a check-list or from a drop-down select list (or anything equivalent) of existing Tags, check or uncheck his selection, and send to enter it to the database.
I can imagine the initial entry of the selected tags is easy enough to achieve with a foreach() function and a simple INSERT query, and enter the array from the form one value at time.
But when the user goes back to change the tags, how would I instruct a query to keep some tags, delete others, and insert new ones in? What is the best method to do something like this?
An Idea:
Should I delete all the existing rows the user has in tag_rel, and insert the new array?
I would use a procedure like this:
at first you fetch the tags a user selected out of the db and pass them to an array (SELECT from tag_rel where user_id = $userId)
then you would go over to let the user operate on the array (adding new tags, deleting old one)
at last you would delete the old entries and insert the completely new ones from the array provided
the simplest method is to delete tag_rel data for that particular user_id then re-insert the new ones

Check for value in CSV MySQL row

I am storing user ID values in a table field separated by a | (user_id1|user_id2|user_id3|user_id17).
A user ID will be added and removed from this field at certain points.
How can I check if the current users ID exists in the field or not using a query?
And it of course needs to be an exact match. Can't look for user_id1 and find user_id17.
I know I could use a SELECT query, explode the field, then use in_array but if there's a way to do it using a query it'd be better.
I guess I'll explain what I am doing: I made a forum for a small private website (7 users), but coding it for larger scale.
My table structure is pretty good: forum_categories, forum_topics, forum_posts. Using foreign keys between the tables for delete and update queries.
What I am seeking help on is to mark Topics as unread for each user. I could create a new table with topic_id & user_id, each one being a new row but that wouldn't be good with alot of users & topics.
If somebody has a better solution I am all for it. Or can prove to me that 1 row per user_id is the best way then I'll be more than willing to do that.
I think you want to track read messages, not the other way around. If you tracked unread messages, every time you add a user you'll have to add that user to every topics "unread list".
I looked into SMF like my comment suggested. They are using a separate table to track read messages.
A simple table that holds user_id and topic_id are you are need. When a user reads a topic, make sure there is a row in the table for that user.
Another reason to use a separate table. It's going to be faster to query against 2 int values in the database than to use LIKE % statements.

Besy way to store data about data that is already stored in a database?

I am working on creating a favorites section on my website where users can simply store certain items in their favorites section for easy access. Each of the items are already well-defined and have multiple attributes. So my question is lets say I had 10,000 users and I would like to implement a 'favorites' system, what would be the best way to keep track of what favorite items have been added by each user?
I was thinking implementing this the following way: link each favorited item id to a username and then run a query for if the user with a particular username is logged in than retrieve all the favorited items by that username.
I appreciate any help with figuring out of a good way to do this. My goal is to store in a way that is later easy to retrieve and use the data and minimize redundant information.
It's pretty easy, you need to create a new table with 3 fields:
id
favoriteID
userID
Every time a user adds a new favourite, it adds a new record to this table, storing both the ID of the favorite, and the ID of the user. There is no redundant information and it's easy to retrieve the details of either the favorite or the user by implementing a join query. This is what relational databases are for.
Within an RDBMS you would probably have a many to many table with the user id and article id. You do not need an independent id column:
create table favourites (user_id int, article_id int);
These of course reference your user table and articles table. (Or whatever you have in place of articles.)
You would then need to retrieve all rows for a single user when wanting to show that user's favourites. You might also want to make a combined UNIQUE index on the columns to prevent duplicates.
You may have faster response with something like cassandra where you can simply retrieve based on the key of the user_id and get all their favourites in one easy spot. But then you're dealing with mutilple systems.
I've heard, but haven't had a chance to look into, that MySQL can now support a Key-Value system similar to Cassandra and that may be your best bet.

How can I update multiple tables while guaranteeing no duplicate ids?

I'm used to building websites with user accounts, so I can simply auto-increment the user id, then let them log in while I identify that user by user id internally. What I need to do in this case is a bit different. I need to anonymously collect a few rows of data from people, and tie those rows together so I can easily discern which data rows belong to which user.
The difficulty I'm having is in generating the id to tie the data rows together. My first thought was to poll the database for the highest user ID in existence, and write to the database with user ID +1. This will fail, however, if two submissions poll the database before either of them writes to it - they will each share the same user ID.
Another thought I had was to create a separate user ID table that would be set to auto-increment, and simply generate a new row, then poll that table for the id of the last row created. That also fails for the same reason as above - if two submissions create a row before either of them polls for the latest user ID, then they'll end up sharing an ID.
Any ideas? I get the impression I'm missing something obvious.
I think I'm understanding you right; I was having a similar issue. There's a super handy php function, though. After you query the database to insert a new row and auto-incrementing their user ID, do:
$user_id = mysql_insert_id();
That just returns the auto-increment value from the previous query on the current mysql connection. You can read more about it here if you need to.
You can then use this to populate the second table's data, being sure nobody will get a duplicate ID from the first one.
You need to insert the user, get the auto-generated id, and then use that id as a foreign key in the couple of rows you need to associate with the parent record. The hat rack must exist before you can hang hats on it.
This is a common issue, and to solve it, you would use a transaction. This gives you the atomic idea being being able to do more than one thing, but have it tied to either a success or fail as a package. It's an advanced db feature, and does require awareness of some more advanced programming in order to implement it in as fault-tolerant a manner as possible.

Categories