I have a 2 tables that I wish to update articles and articles_entities articles has a PK of id and articles_entities has the FK article_id both these fields are char(36) currently a UUID. I am looking to convert these fields to int(10).
Is there a way I can update the 2 tables with 1 query and key the keys matching? or do I have to write a script to look through each articles and update all references?
I am using InnoDb if that helps.
Two steps:
Ensure your foreign key is set to "ON UPDATE CASCADE", then update the mother table's ID field so it contains numbers. The ON UPDATE CASCADE constraint will have InnoDB update the child table as it updates the mother... If you have a lot of rows, be prepared that this will be extremely slow.
Change the type of both columns to INT. You may need to drop the foreign key before you do so and re-create it afterwards.
Related
I want to add complex unique key to existing table. Key contains from 4 fields (user_id, game_id, date, time).
But table have non unique rows.
I understand that I can remove all duplicate dates and after that add complex key.
Maybe exist another solution without searching all duplicate data. (like add unique ignore etc).
UPD
I searched, how can remove duplicate mysql rows - i think it's good solution.
Remove duplicates using only a MySQL query?
You can do as yAnTar advised
ALTER TABLE TABLE_NAME ADD Id INT AUTO_INCREMENT PRIMARY KEY
OR
You can add a constraint
ALTER TABLE TABLE_NAME ADD CONSTRAINT constr_ID UNIQUE (user_id, game_id, date, time)
But I think to not lose your existing data, you can add an indentity column and then make a composite key.
The proper syntax would be - ALTER TABLE Table_Name ADD UNIQUE (column_name)
Example
ALTER TABLE 0_value_addition_setup ADD UNIQUE (`value_code`)
I had to solve a similar problem. I inherited a large source table from MS Access with nearly 15000 records that did not have a primary key, which I had to normalize and make CakePHP compatible. One convention of CakePHP is that every table has a the primary key, that it is first column and that it is called 'id'. The following simple statement did the trick for me under MySQL 5.5:
ALTER TABLE `database_name`.`table_name`
ADD COLUMN `id` INT NOT NULL AUTO_INCREMENT FIRST,
ADD PRIMARY KEY (`id`);
This added a new column 'id' of type integer in front of the existing data ("FIRST" keyword). The AUTO_INCREMENT keyword increments the ids starting with 1. Now every dataset has a unique numerical id. (Without the AUTO_INCREMENT statement all rows are populated with id = 0).
Set Multiple Unique key into table
ALTER TABLE table_name
ADD CONSTRAINT UC_table_name UNIQUE (field1,field2);
I am providing my solution with the assumption on your business logic. Basically in my design I will allow the table to store only one record for a user-game combination. So I will add a composite key to the table.
PRIMARY KEY (`user_id`,`game_id`)
Either create an auto-increment id or a UNIQUE id and add it to the natural key you are talking about with the 4 fields. this will make every row in the table unique...
For MySQL:
ALTER TABLE MyTable ADD MyId INT AUTO_INCREMENT PRIMARY KEY;
If yourColumnName has some values doesn't unique, and now you wanna add an unique index for it. Try this:
CREATE UNIQUE INDEX [IDX_Name] ON yourTableName (yourColumnName) WHERE [id]>1963 --1963 is max(id)-1
Now, try to insert some values are exists for test.
I have table mTable(page_id,parent_page_id,,,). Page_id and parent_page_id are char(36) uuid(). And also have children tables linked with mTable with key Page_id. I used Inno_db_per_table. After inserting records the size of database is grown upto 12 gb of all tables (mTable and its Children).
Now my problem is that when i want to do any alteration in tables it hangs and mostly mysqld.exe stopped working.
I want to change this primary key and also want to update the base table so that automatically the children table's keys updated efficiently.
Please help me.
Thanks
i have three tabs in my Db:
1.pers_info(id(primary), name ,....)
2.contacts(c_id(primary), phone, email, ...)
now 1 person can have multiple rows in contacts tab.
thus to minimize redundancy i made another tab contact_relation(id (foregin key references pers_info(id), c_id (foregin key references contacts(c_id))
i successfully created the relation and also was able to insert apt entries(related id and c_id) to it "using last_insert_id();" to extract id and c_id required.
now the problem..
i dropped tab contacts_rel. and created it this way :
CREATE TABLE contacts_relation (
id INT NOT NULL,
cid INT NOT NULL,
FOREIGN KEY (id)
REFERENCES pers_info(id)
ON UPDATE CASCADE ON DELETE RESTRICT,
FOREIGN KEY (c_id)
REFERENCES contacts(c_id)
);
if now i try to insert into tab cont_rel, it gives error :
cannot add or update a child row foreign key constraint fails.
which makes sense..
i was hoping that adding constraints in the defn of tab cont_rel would save the hassle of inserting entries in it manually using "last_insert_id();"
so is there a way, i could maintain ref integrity with new data
coming.. thanks.
Why the third table? When you many to many relation you need intermediate table. You have one to many relation so two tables are sufficient. Table contacts need FK to table pers_info. Add it if you don't have already.
Here's a simple transaction example with LAST_INSERT_ID(): SQL INSERT INTO multiple tables
Some info about foreign keys and altering table:
Add Foreign Key to existing table
http://dev.mysql.com/doc/refman/5.0/en/alter-table.html
**Table 1**
BOOK(bookID,bookEdition,bookName)
where combination of (bookID,bookEdition) is used as key
**Table2**
SHELF(id,shelfCode,book)
now i want my column "book" in table2 to reference the composite key(bookID,bookEdition) in Table1.
Can any one may please guide me what is the correct way of doing this. Or may please correct me if my approach wrong
Or we cannot add foreign key constraint to tables with composite keys??
If you have a compound primary key (made up of mulitple columns), all your foreign keys also must use all columns of the PK to reference that table. So, foreign key constraints can only be added referencing to whole of the key, not to a part of key.
Either you add both bookID and bookEdition to the SHELF table (which to me makes more sense as bookID and bookEdition together can uniquely identify a book) or create a separate master table for Book (with key bookID) and reference that table in all your other tables.
The table
I got a table that contains price for some 1 000 000 articles. The articles got a uniques ID-number but the table contains prices from multiple stores. Thus if two stores got the same article the uniques ID will not be unique for the table.
Table Structure
table articles
id INT
price IN
store VARCHAR(40)
Daily use
Except for queries using the ID-number by users I need to run daily updates where data from csv-files insert/update each article in the table. The choosen procedure is to try to select an article and then perform either an insert or an update.
Question
With this in mind, which key should I choose?
Here are some solutions that Ive been considering:
FULLTEXT index of the fields isbn and store
Add a field with a value generated by isbn and store that is set as PRIMARY key
One table per store and use isbn as PRIMARY key
Use a compound primary key consisting of the store ID and the article ID - that'll give you a unique primary key for each item on a per-store basis and you don't need a separate field for it (assuming the store id and article id are already in the table).
Ideally you should have 3 tables... something like:
article
--------------------------------------------
id | isbn | ... etc ...
store
--------------------------------------------
id | description | ... etc ...
pricelist
--------------------------------------------
article_id | store_id | price | ... etc ...
With the PRIMARY KEY for pricelist being a compound key made up of article_id and store_id.
EDIT : (updated to incorporate an answer from the comment)
Even on a million rows the UPDATE should be OK (for a certain definition of OK, it might still take a little while with 1 million+ rows) since the article_id and store_id comprise the PRIMARY KEY - they'll both be indexed.
You'll just need to write your query so that it's along the lines of:
UPDATE pricelist SET price = {$fNewPrice}
WHERE article_id = {$iArticleId}
AND store_id =` '{$sStoreId}'
Though you may want to consider converting the PRIMARY KEY in the store table (store.id - and therefore also pricelist.store_id in the pricelist table) to either an unsigned INT or something like CHAR(30).
Whilst VARCHAR is more efficient when it comes to disk space it has a couple of drawbacks:
1: MySQL isn't too keen on updating VARCHAR values and it can make the indexes bloat a bit so you may need to occasionally run OPTIMIZE TABLE on it (I've found this on an order_header table before).
2: Any (MyISAM) table with non-fixed length fields (such as VARCHAR) will have to have a DYNAMIC row format which is slightly less efficient when it comes to querying it - there's more information about that on this SO post: MySQL Row Format: Difference between fixed and dynamic?
Your indexes should be aligned with your queries. Certainly there should be a primary key on the articles table using STORE and ID - but the order in which they are declared will affect performance - depending on the data in the related tables and the queries applied. Indeed the simplest solution might be PRIMARY KEY(STORE, ID) and UNIQUE KEY(ID, STORE) along with foreign key constraints on the two fields.
i.e. since it makes NO SENSE to call this table 'articles', I'll use the same schema as CD001:
CREATE TABLE pricelist (
id INT NOT NULL ,
price INT,
store VARCHAR(40) NOT NULL
PRIMARY KEY(store,id),
UNIQUE KEY rlookup (id, store)
CONSTRAINT id FOREIGN KEY articles.id,
CONSRAINT store FOREIGN KEY store.name
);
Which also entails having a primary key on store using name.
The difference between checking a key based on a single column and one based on 2 columns is negligible - and normalising your database properyl will save you a LOT of pain.