I'm building a backpanel to my TV series website I have 2 tables. One called shows and the other called seasons.
Structure:
Shows - show_id PK, show_title
Seasons - season_id PK, show_id (Foreign key), season
I'm listing all the tv show names in a table in the backend with a delete button however when i press delete it will not delete the show because it has seasons attached too it. If i try delete a show that has no seasons attached it removes it from the database with no problem.
My code looks like this on remove.php:
$id=$_GET['id'];
// Delete show
$sql="DELETE FROM shows WHERE shows_id='$id'";
$result=mysql_query($sql);
I'm guessing i would also need to remove the seasons assigned too the same show but i'm unsure on how to go about doing this.
If you are using InnoDB for your MySQL table, life could be really simple for you here if you checked / changed the constraints on your Foreign Key.
Changing these depends on how you set it up, whether you're using command line interface or some GUI to manage your db.
But when you created the foreign key field in your seasons table, you set up constraints. If you update that constraint to be as follows:
On Update: Do Nothing
\\ On Delete: Cascade
Now any time you delete a row from shows, whatever associated season rows exist will be deleted automatically because of the cascade rule. Very helpful, and a must for setting up normalized databases.
http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
$id=$_GET['id'];
// Delete all seasons for this show first.
$sql="DELETE FROM seasons WHERE show_id='$id'";
// Now, Delete show
$sql="DELETE FROM shows WHERE id='$id'";
Related
What is the advantage of having a foreign key relationship if I am not having any delete or update constraints set?
Suppose I have a table for items that users can post for reselling.
item_id item_product_id item_title other_fields
1 1 New TV for sale ...
1 1 Old TV for sale ...
1 2 Radio for sale ...
And the product table would be:
product_id product_name
1 TV
2 Radio
Now if a product is removed from the product table, I would not want the items to be deleted as well. The user can see that his item's product exists no longer and can select another closest appropriate product. So my question is - if this is the structure and logic I have, is there any advantage I get by linking the items and product tables using foreign keys?
Or, will I even be able to delete from products if there is a foreign key entry in items?
One advantage is that your RDMS won't let you insert invalid data to begin with. If there is no product with ID 5, then you will be absolutely unable to create an item for it (whether from a script or from the mysql command line). This goes under the heading of data integrity.
Also, it might be worthwhile for you to checkout this question
Or, will I even be able to delete from products if there is a foreign key entry in items?
No, you won't, unless you specify ON DELETE CASCADE or ON DELETE SET NULL.
Neither you will be able to insert into items unless you have a matching record in products.
Creating a comment system with a simple rating system for each comment.
tables : 1.For the comments and it is called comments and it has three columns : id, name, comment
2. for the IP of the user that did the rating and it is called voted_ipand it has three columns id, comment_id, user_ip
The purpose of the voted_ip table is that i need to save the IP address for each rate to validate it that it cannot rate again if it exists.
I created a foreign key from the child table voted_ip in the column comment_id connecting it to the parent table comments in the column id following the steps at this link and this video on how to create a working foreign key except that the child table still do not update after a comment or a rate is inserted.
as follow :
I thought about that there might be another step or I have to do something in the php side of the project. What am I missing?
Data is not inserted in the other table "voted_ip" on insertion in "comment" by itself you have to add it explicitly this constraints are just for checking not for adding data in other table automatically.
I wish to know what SQL is needed to be passed to implement multiple categories for an article.
I have created 3 tables.
ARTICLES:
id, title, content
CATEGORIES:
id, name
RELATION:
article_id, cat_id
I am successfully able to create the first two tables, and store data in them when user submits the form. But, I have no clue how to update the RELATION table. I searched on stackoverflow, and I learned that I need to use a many to many relationship. I have idea about it. But, I do not know how to do it practically i.e. the SQL.
The Categories are obviously added while the post is published, So i need to update this table only after the first two tables have been updated.
If someone can guide me to a tutorial or in the right direction I shall be greatful.
Assuming that post and article are synonyms, then each time a new post is published and its category is determined you need to 'INSERT' a record into 'RELATION' table.
When you originally create tables you will need to identify Primary and Foreign keys (CONSTRAINTS) and (if so desired) specify whether CASCADE should be enabled.
Apparently you already know how to CREATE tables and INSERT rows.
You may want to Google for PRIMARY KEY, FOREIGN KEY, CASCADE ON DELETE in conjunction with MYSQL and PHP.
Also see if the following helps any: How do I use on delete cascade in mysql?.
This should be taken care of by your SQL DBMS. For example, if you set your relationship's foreign keys to cascade delete or update, when something changes in the parent, the children will also be deleted/updated. Can you give me an example of an update that you would expect to make to the first two tables and the resulting update to the RELATION table?
I am trying to understand relationships fully, and have gone through alot of tutorials. Still i linger on a few things (using MySQLWORKBENCH):
1. Every user can upload a product
2. Every product can have multiple categories, bids, ratings, etc
3. Every user can have multiple phonenumbers
(there are more, but this is the basic setup)
Is this correct?:
1 - I used a 1:n relationship, since every user can upload multiple products.
2 and 3. I used n:m relationship, since there can be multiple products with multiple categories, bids, ratings, etc.
DELETE/UPDATE:
I used ON UPDATE CASCADE and ON DELETE CASCADE everywhere where there is a foreign key...that being 'product', 'category_tags_has_products', 'bid_price_has_product', 'phone_has_user'.
I tried to delete a product like this (php): mysql_query("DELETE FROM product WHERE id='$id'");
I get a 1054 error, which is a foreign key error.
What are the best practises here? It is to my understanding that i shouldn't need to do deletions in any other than the parent-table?
Thanx!
You have a lot of identifying relationships, which mean that the foreign key form part of the primary key on the second table. This is not necessary in most instances, and is only really useful in instances such as link tables.
To this end I would change the user->product link to be non-identifying, which will make user_id a Foreign Key instead of being part of the Primary Key. In workbench the shortcut for a 1:n non-identifying relationship is key '2' (where as '4' is identifying). This in turn should remove the user_id fields from the tables which product links onto.
When you delete a product, it should cascade to the 3 link tables that it links to. At present it may be that it is trying to delete from users also depending on how the FK is set up. The following should cascade deletions (assuming a deletion is permanent and you just want to clear out all linked records)
DELETE FROM product -> deletes from any table with product_id in
DELETE FROM user -> deletes from any table with user_id in
The same applies for phone, rating, bid_price, category_tags.
I hope this if of use, if you need any further pointers feel free to shout :)
The relations look correct.
To find out what is wrong with your query check the $id variable.
Or check the whole query and then run it in the console/phpMyAdmin/etc:
$query = "DELETE FROM product WHERE id='$id'";
var_dump($query);
mysql_query($query);
P.S.: and don't forget to escape all data got from the users! Like this:
$id = mysql_real_escape_string($_GET['id']);
On my website several vendors can import their articles.
I want to give them the option to cleanup their articles (e.g. remove articles not in importfile).
The first thing I thought of is to just first delete all the articles of the vendor before import, however this might bring up a situation that a customer is visiting the site and don't see any products (of the specific vendor).
So after some more thinking I've came up with two other solutions:
import the products and remember what products were imported / updated (if they already existed) and delete the products of the vendor which weren't in the import afterwards
import the products in another temp table, remove the current products of the vendor and then copy the products in the temp table to the 'real' table.
However there might be some issues with both options.
is let's say remembering all imported / updated products really a good idea since sometimes it can be > 1 million products?
will it be possible to delete the current products and copy the products from the temp table to the real table be so fast that there is only a tiny chance that a visiting customer won't see any products?
Perhaps there are any more issues with the options I figured out.
Or perhaps there are some other options to do this?
PS
'Locking' the site / locking out customers while importing is not an option.
When I read your questions, two solutions came to my mind:
Fire up a "maintenance mode" while importing, but thats probably not what you want. Sorry didn't read your last statement.
Import (or delete) the items one by one, because that way the user would be missing at most one product at any given instant. There are a couple of caveats to consider here, though:
What happens if a product is deleted while it is inside the users shopping basket?
The references in already made purchases need to stay intact, in order to be able to reconstruct a bill after the product bought has been deleted.
Also, you can rename a table in PostreSQL like this:
ALTER TABLE TableB RENAME TO TableC;
In case you want to go with your "temporary table" solution, which I too have used, though under much less critical circumstances, admittedly. But note that, at least in MySQL InnoDB, you have to worry about foreign keys, which will still point to the old table if renamed, e.g. if there is a foreign key from TableA to TableB, and you rename TableB to TableB_old and TableB_new to TableB, than the foreign key will point to TableB_old. I don't know if this is the case with PostgreSQL though.
I have a variation on on of your suggested methods:
Have a table called vendortables setup that has columns for vendorname or id and the name of the table that lists their products.
When a vendor wants to import, create a new table for the input (possibly vendorname + upload start time). Upload all of the data into it. Once that's done, grab the name of the current vendor's table (in vendortables) and update so the name of the new table is associated with the uploading vendor. Then delete the old table (that you grabbed before the update).
This way, no table data is every copied.
Example:
SELECT * FROM vendortables
+--+-----+
|id|table|
+--+-----+
|01|test |
+--+-----+
SELECT * FROM test
+--+----+
|id|name|
+--+----+
|01|car |
+--+----+
//Import & upload new data
CREATE TABLE test1 USING('?', 'new car')
SELECT * FROM test1
+--+--------+
|id|name |
+--+--------+
|01|new car |
+--+--------+
//Phase in new data
UPDATE vendortables SET table='test1' WHERE id='1'
//Delete old table
DROP TABLE test
And just have PHP ask vendortables for the name of the table responsible for displaying a vendor's products.
Also, since you mention your site's high usage, have you considered that caching will probably make requesting during an import very unlikely.
make a delete table
delete from del_vendor_article where vendorid='vendorid'
do this on article update
insert into del_vendor_article SET vendorid='vendorid', article_id='articleid'
possibly show them what will be deleted. then they can remove anything they might want to keep
SELECT item FROM articles WHERE NOT EXISTS (SELECT * FROM del_vendor_article WHERE articles.articles_id = del_vendor_article.articles_id);
delete not imported items
delete from articles WHERE NOT EXISTS (SELECT * FROM del_vendor_article WHERE articles.articles_id = del_vendor_article.articles_id);