i dont know how to exactly describe it, but my MYSQL tables are losing their Primary Keys + Auto Increment and have data with 0 as an Id(prim+AI). After looking at these tables, the similar thing is that all of tables have duplicate entries of the same entries that they have inside of them.
As you can see in image 1.png, there are no Primary keys (there was a primary key when i first made the table and it was working the whole time). and as you can see in the 2nd image 2.png, entries are duplicated(dont know how) and there are records with 0 in the id.
Update 2:
When this table was first created, the ID column was set as Prim+AI and it was working great. HOW DID IT LOSE THE PK+AI, i have no idea that is why am asking.
Also, in my project there are no codes(MYSQL) to add/remove PKs, Duplicate Tables etc.. the only codes i have are INSERT/UPDATE/DELETE/SELECT.
Related
It's a daily struggle to work with the previous programmer his code... And now, apparently, also his database.
Problem description
So here we've got a table to store the availability of a user and normally you would assign a unique id to every row of data. Except... he didn't. He made the user_id the first primary key (probably a composite).
So the user changes his availability for each weekday (monday to friday) and every timeslot in that week.
This is made into one row each:
user_id,day,hour_nr,hour_type,location_id
But you might see this one coming, I can't manually insert fake data for developing purposes. I'm trying to add a period and college year (it's for an educational institution) Which worked fine but because the old data didn't require this it's all set to 0.
The new row will consist of:
user_id,day,hour_nr,hour_type,location_id,period_id,collegeyear_id
I've tried uploading data to the table containing the period and college year information but I get an instant error telling me that there is a duplicate entry.
That's correct there is but there already were duplicates as well.
Question
And so the question is: how do I force this without altering the tables keys? I don't feel much for altering the indexed properties of the composite primary key.
Lastly, I know this is wrong and I know that it should have been done differently. Again it's not my work or design and I don't have any time on hand to fix or alter it during this project.
Edit
As requested, hereby a snapshot of the table with data and a snapshot of how it should be
The snapshot shows different headers than mentioned, they're the same but in Dutch.
Current data snapshot (I forgot to put the last 2 columns that are in the Desired data result snapshot on the snapshot but they're already there containing nothing but 0's)
Desired data result
I do need anINSERT, the data has to be added not altered. Or another fix for this issue ofcourse but the data has to be added.
Fix
So in a perfect example of tunnel vision I fixed and therefore answered my own question.
Instead of looking blindly at inserting the data I should have looked more towards the composite key part. I've added the 2 new columns to the key and now all is fine and dandy.
I said that I didn't want to mess with the keys but that was pointed towards the already existing keys not adding to the composite key.
I still dislike the fact that there isn't a single unique id but it is workable.
Q.
And so the question is: how do I force this without altering the tables keys? I don't feel much for altering the indexed properties of the composite primary key.
A.
You cannot force the primary key to have multiple values of the same ID.
The best thing for you to do would be to add an extra column with a new ID and reference that within the software.
A primary key is a special relational database table column (or combination of columns) designated to uniquely identify all table records.
A primary key’s main features are:
It must contain a unique value for each row of data.
It cannot contain null values.
A primary key is either an existing table column or a column that is specifically generated by the database according to a defined sequence.
Resources:- techopedia
So in a perfect example of tunnel vision I fixed and therefore answered my own question.
Instead of looking blindly at inserting the data I should have looked more towards the composite key part. I've added the 2 new columns to the key and now all is fine and dandy.
I said that I didn't want to mess with the keys but that was pointed towards the already existing keys not adding to the composite key.
I still dislike the fact that there isn't a single unique id but it is workable.
I know this has something to do with maybe the Primary Key and Unique Keys, but I'm not sure how to how to make it work. Basically I want MySQL to generate a new row even if data in it is duplicate of last rows. Right now, any duplicate data from previous rows result in the row not being generated. Help is very appreciated.
The table you have defined has all columns as primary key and unique. It's ideal to maintain one column as primary key (perhaps with auto increment) and the rest as non-indexed columns. Check the table definition with the following mysql query if you are not familiar with using phpMyAdmin
desc tablename;
I would like write a php script that merges several databases, and I would like to be sure of how to go around it before I start anything.
I have 4 databases which have the same structure and almost same data. I want to merge them without any duplicate entry while preserving (or re-linking) the foreign keys.
For example there is a db1.product table which is almost the same as db2.products so I think I would have to use LIKE comparison on name and description columns to be sure that I only insert new rows. But then, when merging the orders table I have to make sure that the productID still indicates the right product.
So I thought of 2 solutions :
Either I use for each table insert into db1.x as select * from db2.x and then make new links and check for duplicate using triggers.
Either I delete duplicate entries and update new foreign keys (after having dropped constraints) and then insert row into the main database.
Just heard of MySQL Data Compare and Toad for mySQL, could they help me to merge tables ?
Could someone indicate to me what should be the right solution ?
sorry for my english and thank you !
First thing is how are you determining whether products are the same? You mentioned LIKE comparison on name and description. You need to establish a rule what says that product is one and the same in your db1, db2 and so on.
However, let's assume that product's name and description are the attributes that define it.
ALTER TABLE products ADD UNIQUE('name', 'description');
Run this on all of your databases.
After you've done that, select one of the databases you wish to import into and run the following query:
INSERT IGNORE INTO db1.products SELECT * FROM db2.products;
Repeat for the remaining databases.
Naturally, this all fails if you can't determine how you're going to compare the products.
Note: never use reserved words for your column names such as word "name".
Firstly, good luck with this - sounds like a tricky job.
Secondly, I wouldn't do this with PHP - I'd write SQL to do the work, assuming this is a one-off migration task and not a recurring task.
As an approach, I would do the following.
Create a database with the schema you want - it sounds like each of your 4 databases have small variations in the schema. Just create the schema for now, don't worry about the data.
Create a "working" database, with the same schema, but with columns for "old" primary keys. For instance:
table ORDER
order_id int primary key auto increment
old_order_id int not null
...other columns...
table ORDER_LINE
order_line_id int primary key auto increment
old_order_line_id int not null
order_id int foreign key
...other columns...
Table by table, Insert into your working database from your first source database. Let the primary keys auto_increment, but put the original primary key into the "old_" column.
For instance:
insert into workingdb.orders
select null, order_id, ....other columns...
from db1.orders
Where you have a foreign key, populate it by finding the record in the old_ column.
For instance:
insert into workingdb.order_line
select null, ol.order_line_id, o.order_id
from db1.order_line ol,
workingdb.order
where ol.order_id = o.old_order_id
Rinse and repeat for the other databases.
Finally, copy the data from your working database into the "proper" database. This is optional - it may help to retain the old IDs for lookups etc.
My db table looks like this pic. http://prntscr.com/22z1n
Recently I've created delete.php page. it works properly but when i deleted 21th user next registered user gets 24th id instead of 21.
Is it possible to put newly registered users info to first empty row? (In this situation 21th row)
In my registration form, newly registering user can write names of existing users, and be friends with them after registration. For this friendship i have another table that associates id of newly registered user and existing user.
For this purpose i'm using mysql_insert_id during registration to get id for new user. But after deletion of 21th row during nex registration process mysql_insert_id gave me number 21. but stored in 24th row. And put to associations table 21 for new user. I wanna solve this problem
When you use an autoincrement id column, the value that the next entry will be assigned will not be reduced by deleting an entry. That is not what an autoincrement column is used for. The database engine will always increment that number on a new insert and never decrement that number on a delete.
A MySQL auto_increment column maintains a number internally, and will always increment it, even after deletions. If you need to fill in an empty space, you have to handle it yourself in PHP, rather than use the auto_increment keyword in the table definition.
Rolling back to fill in empty row ids can cause all sorts of difficulty if you have foreign key relationships to maintain, and it really isn't advised.
The auto_increment can be reset using a SQL statement, but this is not advised because it will cause duplicate key errors.
-- Doing this will cause problems!
ALTER table AUTO_INCREMENT=12345;
EDIT
To enforce your foreign key relationships as described in the comments, you should add to your table definition:
FOREIGN KEY (friendid) REFERENCES registration_table (id) ON DELETE SET NULL;
Fill in the correct table and column names. Now, when a user is deleted from the registration, their friend association is nulled. If you need to reassociate with a different user, that has to be handled with PHP. mysql_insert_id() is no longer helpful.
If you need to find the highest numbered id still in the database after deletion to associate with friends, use the following.
SELECT MAX(id) FROM registration_table;
Auto increment is a sequence key that's tracked as part of the table. It does not go back when you delete a row.
Easily, no. What you can do (but I don't suggest doing) is making an SQL function to determine the lowest number that isn't currently occupied. Or you can create a table of IDs that were deleted, and get the smallest number from there. Or, and this is the best idea, ignore the gaps and realize the database is fine.
What you want to do is achievable by adding an extra column to your table called something like user_order. You can then write code to manage inserts and deletions so that this column is always sequential with no gaps.
This way you avoid the problems you could have messing around with an auto_increment column.
It's not a good practice to reset auto_increment value, but if you really need to do it, so you can:
ALTER TABLE mytable AUTO_INCREMENT = 1;
Run this query after every delete. Auto_increment value will not be set to 1, this will set the lowest possible value automatically.
I have created a PHP script and I am lacking to extract the primary key, I have given flow below, please help me in how can i modify to get primary key
I am using MySQL DB, working for Joomla, My requirement is tracking the activity like insert/update/delete on any table and store it in another audit table using triggers, i.e. I am doing Auditing. DB's table structure: Few tables dont have any PK nor auto increment key
Flow of my script is :
I fetch out all table from DB.
I check whether the table have any trigger or not.
If yes then it moves to check for next table and so on.
If it does'nt find any trigger then it creates the triggers for the table, such that,
it first checks if the table has any primary key or not(for inserting in Tracking audit table for every change made)
if it has the primary key then it uses it further in creation of trigger.
if it doesnt find any PK then it proceeds further in creating the trigger without inserting any id in audit table
Now here, My problem is I need the PK every time so that I can record the id of any particular table in which the insert/update/delete is performed, so that further i can use this audit track table to replicate in production DB..
Now as I haave mentioned earlier that I am not available with PK/auto-incremented in some table, then what should I do get the particular id in which change is done?
please guide me...GEEKS!!!
If I understand your question right, you need a unique identifier for table rows that have no primary key and no other kind of unique identifier. That's not easy to do as far as I can see. Other databases have unique Row IDs, but mySQL does not. You could use the value of every column to try and identify the row, but that is far from duplicate-safe - there could be two or more rows containing the exact same values. So I'd say, without a unique identifier, this is something that simply cannot be done.
Some ideas in this SO question:
MySQL: is there something like an internal record identifier for every record in a MySQL table?