I have a small ARCHIVE engine table that I want to submit logs into whenever someone does something. I am not giving a unique "id" to every row; instead my "id" column is the user's ID.
I use this->model->save() and the first insert is fine. The problem is Cake thinks I'm trying to UPDATE on the second time that someone does something, when really all I want is to create another record, with the same user's ID, with a different action or timestamp.
How do I force CakePHP to INSERT only, without using query()? And without having to make 5th column for "row ID"?
Always make sure to unset the primary key. For instance in the beforeValidate. This will trigger a save instead of an update.
See the documentation
Related
I am wondering how I could, using PHP and mysql, create a table with a unique name every time.
So example if i click submit, a table will be created that is named "1".
then if i do it again another table is added and it is named "2"
I searched around but could only find answers to how to auto_increment the columns inside the table so I hoped it would be the same code, I tried this:
mysql_query("CREATE TABLE INT NOT NULL AUTO_INCREMENT PRIMARY KEY(TestColumn CHAR(30))");
It did not work.
So how do you create an auto_incremented table ???
Create a simple file which store a serial number. Then when your script creates a table, you increment the counter in the file with one. Next time, you read the number and use that for the table name. Naturally, you could do this in a table or a flat file.
Just for knowing which tables exist, and what they are for, you'd best create one master table storing not just the latest, but all tables created.
I am lost as to why you would want to do this.. I see no good reason for wanting this.
Create a table of tables and store the number or the number name in that table. Then you can look up MAX number there.
First at all, this function don't exist in PHP or in MySQL. Or maybe I don't know it.
There is 2 solutions to your problem :
Solution number 1 :
As AlanChavez said, you can use this request :
CREATE TABLE IF NOT EXIST ....
But, if you have to create 1000000000 table (it's an example), it will not be optimized.
Solution number 2 :
You can create a table with a single row, where is stored the last name used for your table.
I don't know if it's really optimized, but I think it can work.
I will never recommend to name a database table just with a digit. To keep track of number of click / page-load you can use file, session or another table.
In a customer CMS the customer can update their personal information, like change their address and first/last name. I use a mysql UPDATE query for that.
Problem with working like this is, is that people can change their information. E.g. change their name from john doe to asdfdas. I would like to SAVE their old information.
What are my options? What is the best way to do this?
Assuming the user has a unique ID you could have an old_user_information table and when you do an update also do a new entry into that table. The table would have an autogenerated ID as well as the unique user ID and the rest of that users past information.
A user could have multiple rows in this table but only one row in the real Users table.
Edit: If I were you I would write a stored procedure that does both of these things so that it is easier to manage if things change.
You can make table that contains something like this
`yourTableID, field, value, date`
and update this with a trigger. You write an update trigger that adds the old value if it is changed. Look at the manual here to find out more about triggers.
If you don't want to use triggers you could obviously do the same in your logic: just update the history table with the old value. But this needs some trickery to find out if you need to update it, but nothing to complicated.
For easy retrieval what happened you might want to add something like "oldvalue" AND "newvalue", but the latter isn't really needed, as it is either in the next update as 'old' value, or it is the current value.
Create new columns for the data being updated column would be prior_to_update_column
On update, move the old info into prior_to_update_column
If the user updates again, append to the prior_to_update_column seperated by , (to look like an array).
This should keep all the previous info the user updates
add an additional field name version
and use Insert instead of update
あの答えのとうりに、やってない。
UPDATE table name SET column=column+'new value' WHERE condition
I've got a PHP script pulling a file from a server and plugging the values in it into a Database every 4 hours.
This file can and most likely change within the 4 hours (or whatever timeframe I finally choose). It's a list of properties and their owners.
Would it be better to check the file and compare it to each DB entry and update any if they need it, or create a temp table and then compare the two using an SQL query?
None.
What I'd personally do is run the INSERT command using ON DUPLICATE KEY UPDATE (assuming your table is properly designed and that you are using at least one piece of information from your file as UNIQUE key which you should based on your comment).
Reasons
Creating temp table is a hassle.
Comparing is a hassle too. You need to select a record, compare a record, if not equal update the record and so on - it's just a giant waste of time to compare a piece of info and there's a better way to do it.
It would be so much easier if you just insert everything you find and if a clash occurs - that means the record exists and most likely needs updating.
That way you took care of everything with 1 query and your data integrity is preserved also so you can just keep filling your table or updating with new records.
I think it would be best to download the file and update the existing table, maybe using REPLACE or REPLACE INTO. "REPLACE works exactly like INSERT, except that if an old row in the table has the same value as a new row for a PRIMARY KEY or a UNIQUE index, the old row is deleted before the new row is inserted." http://dev.mysql.com/doc/refman/5.0/en/replace.html
Presumably you have a list of columns that will have to match in order for you to decide that the two things match.
If you create a UNIQUE index over those columns then you can use either INSERT ... ON DUPLICATE KEY UPDATE(manual) or REPLACE INTO ...(manual)
I have a MySQL database where I am storing information that is entered from a PHP web page. I have a page that allows the user to view an existing row, and make changes and save them to the database. I want to know the best way to keep the original entries, as well as the new update and any subsequent updates.
My thought is to make a new table with the same columns as the first, with an additional timestamp field. When a user submits an update, the script would take the contents of the main table's row, and enter them into the archive table with a timestamp when it was done, and then enter in the new values to the main table. I'd also add a new field to the main table to specify whether or not the row has ever been edited.
This way, I can do a query of the main table and get the most current data, and I can also query the archive table to see the change history. Is this the best way to accomplish this, or is there a better way?
You can use triggers on update, delete, or insert to keep track of all changes, who made them and at what time.
Lookup database audit tables. There are several methods, I like the active column which gets set to 0 when you 'delete' or 'update' and the new record gets inserted. It does make a headache for unique key checking. The alternative I've used is the one you have mentioned, a separate table.
As buckbova mentions you can use a trigger to do the secondary insert on 'delete' or 'update'. Otherwise manage it in your PHP code if you don't have that ability.
You don't need a second table. Just have a start and end date on each row. The row without an end date is the active record. I've built entire systems using this method, and just so long as you index the date fields, it's very fast.
When retrieving the current record, AND end_date IS NULL gets added to the WHERE clause.
In this situation, I would recommend you to consider all properties in one table after adding it few columns:
active/ not active
ID of the person who kept these parameters
timestamp of adding
How can we re-use the deleted id from any MySQL-DB table?
If I want to rollback the deleted ID , can we do it anyhow?
It may be possible by finding the lowest unused ID and forcing it, but it's terribly bad practice, mainly because of referential integrity: It could be, for example, that relationships from other tables point to a deleted record, which would not be recognizable as "deleted" any more if IDs were reused.
Bottom line: Don't do it. It's a really bad idea.
Related reading: Using auto_increment in the mySQL manual
Re your update: Even if you have a legitimate reason to do this, I don't think there is an automatic way to re-use values in an auto_increment field. If at all, you would have to find the lowest unused value (maybe using a stored procedure or an external script) and force that as the ID (if that's even possible.).
You shouldn't do it.
Don't think of it as a number at all.
It is not a number. It's unique identifier. Think of this word - unique. No record should be identified with the same id.
1.
As per your explanation provided "#Pekka, I am tracking the INsert Update and delete query..." I assume you just some how want to put your old data back to the same ID.
In that case you may consider using a delete-flag column in your table.
If the delete-flag is set for some row, you shall consider program to consider it deleted. Further you may make it available by setting the delete-flat(false).
Similar way is to move whole row to some temporary table and you can bring it back when required with the same data and ID.
Prev. idea is better though.
2.
If this is not what you meant by your explanation; and you want to delete and still use all the values of ID(auto-generated); i have a few ideas you may implement:
- Create a table (IDSTORE) for storing Deleted IDs.
- Create a trigger activated on row delete which will note the ID and store it to the table.
- While inserting take minimum ID from IDSTORE and insert it with that value. If IDSTORE is empty you can pass NULL ID to generate Auto Incremented number.
Of course if you have references / relations (FK) implemented, you manually have to look after it, as your requirement is so.
Further Read:
http://www.databasejournal.com/features/mysql/article.php/10897_2201621_3/Deleting-Duplicate-Rows-in-a-MySQL-Database.htm
Here is the my case for mysql DB:
I had menu table and the menu id was being used in content table as a foreign key. But there was no direct relation between tables (bad table design, i know but the project was done by other developer and later my client approached me to handle it). So, one day my client realised that some of the contents are not showing up. I looked at the problem and found that one of the menu is deleted from menu table, but luckily the menu id exist in cotent table. I found the menu id from content table that was deleted and run the normal insert query for menu table with same menu id along with other fields. (Id is primary key) and it worked.
insert into tbl_menu(id, col1, col2, ...) values(12, val1, val2, ...)