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']);
Related
I have a author table and a publication table. Both are related to each other in a many to many relation. When I'm inserting the publications the authors of the publications are inserted in the pivot table by the order of authors id. But I need to insert it by the order i'm selecting the authors in the front-end. Whatever the order of the authors in the front end is it is getting ordered by the author's id in the pivot table. How can i stop this automatic ordering
You can't add rows in a specific order into a pivot table, because it doesn't really make sense.
Let's consider an users table:
The first user you enter will have the id 1
The second will be assigned to the id 2
And so on...
So you can enter the users in a specific order and retrieve them by their id.
However, in a standard pivot table, the primary key is composed by two columns, in your case the author_id and publication_id. Nothing new is created here, you just associate the primary key of two existing rows in two differents tables in order to achieve one - and unique - composed primary key.
If i explained well (and i hope so :p), you should understand why saying
But I need to insert it by the order i'm selecting the authors in the front-end.
doesn't really make sense.
But, don't worry, it is still possible to achieve your goal here.
Instead of using a pivot table, you can use a normal table with an id. This way, the order of insertion will be preserved. It will work but that's not very nice.
A better approach would be to add an additional column to the pivot table. A column like position. This column could be incremented for each author you insert. Then, you can order the table by the position column, by simply adding ->orderBy('position') to your relationship or every queries that needs to.
Here is an example to illustrate what i said above:
foreach($authors as $position => $author)
{
$publication->authors()->attach($author, ['position' => $position]);
}
If $authors contains the authors in the order you selected them on the front-end, they will be added accordingly.
If you need to sync instead of attach, that's also possible, it's just a little bit more verbose:
$syncData = $authors->mapWithKeys(function($author, $position){
return [$author->id => ['position' => $position]];
});
$publication->authors()->sync($syncData);
Don't forget that you can add false as a second parameter on the sync method so it'll only add new authors.
After that, just change your authors relationship in your Publication model like this:
public function authors(){
return $this->belongsToMany(Author::class)->orderBy('position');
}
Or everywhere you need to:
$publication->authors()->orderBy('position')->get();
I hope it helps !
I am working on a game where the user can register, has an inventory and has weapons in that inventory. I want to store this information in my database.
Here is how I have set it up so far:
My user table contains a UserID column (along with other information).
My inventory table contains an InventoryID column and a UserID column
(the UserID corresponds to the owner of the inventory)
My Weapons table contains an InventoryID column which references the
Inventory it belongs to.
Is this the standard way of doing things? Can I change my layout and make it simpler? It just seems a little tedious to work with databases like this.
It would be so much easier if my User table had a reference to an inventory entry and that entry had an array of weapons. I've achieved this by storing references to the ID's of each entry but I can't just create a "User" php class (which has a reference to an Inventory object, which has an array of Weapon objects) by running one query to the database.
Maybe there is a framework to achieve this?
What You described is simple one-to-many relationship.
You don't need inventory table.
You need a user table with userID as primary key and use it as a foreign key in weapons table.
With help of joins You can use one query to get all records.
Have you considered a NoSQL database? :)
Relational databases often require "join" tables as you describe. You can probably accomplish this without a join table if user to inventory is 1:1 - and 1 weapon can only belong to 1 inventory/user - just have weapons store a user ID.
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'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'";
I've been toying with MySQL today and reading their documentation, gotten some handy information of optimization and a lot of things I didn't know. Now I've been adding foreign keys to my web application because it add constrains and I see it quite helpful.
My doubt is, right now there is a Roles table and a Users table, I set a relation on user's RoleID that when the role ID is removed (from the Roles table, parent) it should the user is deleted.
Now I kinda have the answer but I prefer someone to confirm, the ID has to match? or does the foreign key takes action regardless if it matches or not?
The foreign key constraints will only take place where the ID is matched. In other words, it won't remove users of different RoleIDs, only those users which have the RoleID of the deleted Role.