Using cascade with composite primary key - mysql

My question is that can I use cascade with composite Primary key?
I have a table FbUser and a table FbFriends. FbFriends table has UID and FID as composite primary key, In other tables it is represented as foreign key(UID,FID)
If I make statement delete from FbFriends where UID="10" and FID="2" CASCADE, Will that delete the child rows as well?

ON DELETE CASCADE is an attribute of the foreign key. It is not a clause that you add to your DELETE statement. If the foreign key is defined to delete child rows when the parent is deleted, it doesn't matter whether the foreign key is defined on a single column or on multiple columns, the delete will cascade.
Personally, though, I'm not a big fan of cascading deletes or any other "magic" that happens outside of the logic in a piece of code. I've seen way too many cases where an ORM is misconfigured to do a DELETE followed by an INSERT rather than an UPDATE or where a developer builds a script that deletes and reloads some number of rows in a table inadvertently create a mess when a cascading foreign key or a trigger that wasn't looked at caused modifications to some number of other tables. If the original developer fails to realize that those tables are potentially impacted by his change, he'll certainly fail to test the data in those tables and the change can rather easily get promoted to production before users start seeing the problem and crying. Sure, it's more verbose to explicitly delete from the child table before the parent table. But doing so generally makes it much more likely that someone can read and follow your code in its entirety.
In the Oracle realm, for example, Tom Kyte is against cascade deletes. You can also find various cases where cascading constraints caused unexpected behavior because the developers maintaining a system didn't remember that someone long ago had configured the constraints in a particular way. Personally, I'd much rather get an error telling me that the database can't delete a row because there are child rows rather than potentially losing data that I didn't intend to lose.

Related

What is the cost of deletion of a record from a Child table having foreign key constraint with parent table

For instance there are 20 tables which have foreign key of a table let's call it Child. Now when i delete a record from Child it will check whether the record is referenced from somewhere or not, is it so or some other scenario.
My question is how this foreign key relation impacting performance of deletion operation.
Actually i'm using hibernate and i have an entity which has got only 3 columns and is used in many other Entities(one-to-one) mapping.
I'm thinking to make this entity embeddable for performance tuning because if i keep it entity then mapping between tables is done using foreign key. Although when i delete an entity there are only two query are running :- delete parent , then delete child. But as child's foreign key is referenced from many other tables with lot of records so it will check whether reference of record in child exists in some tables or not if not then delete while deleting child record. So i want to target this issue by making child embeddable which will result columns of child will be included in parent tables. Whether this will help?
Performance depends very much on which DBMS you're using, how your tables are designed, indexed and stored, and how much data you have.
In general, foreign key constraints save time and effort and prevent mistakes. Without a foreign key constraint, you would have to enforce integrity yourself.
For example, manually cascading a delete or update would be done in multiple round-trips to the database which would normally be wrapped in a transaction. Manually checking for related records to restrict changes would also require additional queries and data transferred between server and client.
If you missed anything or another user modified related data between your queries, you might end up with invalid data, which can be very costly - both in terms of DBA time as well as customer satisfaction.

Which gets deleted first? Primary or Foreign key?

When we delete a primary key which is foreign key in other table, which gets deleted first? Primary key in first table or Foreign key in the other table? I was asked this question in interview. Please provide some reason with answer too :)
In general, you would need to delete the foreign key references before deleting the primary key. Otherwise, the foreign key constraint would be invalid.
I might guess that this is the answer the interviewer is looking for.
In practice, though, the answer would be "at the same time". The normal way to accomplish this is using a cascading delete foreign key reference. The deletes would all take place in the same transaction (on most databases at least), so they would not take effect until the commit.
If you were doing this manually, you do typically do:
Drop the foreign key constraint.
Re-set the values in the columns for the foreign key reference (typically to NULL).
Delete the appropriate row(s) in the primary key table.
Well to me looks like a tricky question.
My answer would be neither, you will get an error unless you define a DELETE CASCADE constraint
In that case row reference that PK would be delete first.
The PK record cannot be deleted until the FK records are gone. That is part of the very definition of what having such relationships is and one of the main reasons for having a FK relationship. The reason is that you don't want to have orphaned child records that no longer have a parent and thus do not make sense. This is the data integrity issue.
Databases will give an error if you try to delete the PK without first deleting the child records. Cascade delete can hide this by deleting them first in the background, but this is very bad thing much of the time and should be avoided. You do not want to willy nilly delete child records, there are many times when the existence of a child record is telling you that the parent should not be deleted.

MySQL fixed ids for categories, how to ensure they are static

I have a system that has categories that are joined to events. All of these categories are simple, they have an id, and name. One thing that worries me is that when I am creating these categories, the ids should always remain the same, be static. If I deleted one, let's say "Politics" at id=1, all of those events would have an orphaned category. One solution I thought of is to just assign string ids to them, so if they do happen to get deleted, it wouldn't really matter. What kind of solution do you recommend?
From my perspective it seems like you could keep the ids and just put a constraint that doesn't allow you to delete the record, only edit them. Another, is to use string ids, but that seems like a pain, although it seems to solve the problem of worrying about the ids being messed with.
Yes, this is what foreign key constraints are for. They also allow for rules on how to handle deletes -- for example, allowing a delete to cascade through dependent records, which is of course very dangerous and not what you would want in this situation. A simple basic constraint will do.
HOWEVER!!!! This is the important thing to understand about mysql. The default mysql engine (myisam) has absolutely no support for foreign key constraints. You need to use an engine that supports them -- most commonly innodb.
If you specify a constraint when you're generating your DDL, a myisam table will accept the constraint but simply ignore it, so make sure all your related tables are setup/altered to be innodb tables before you add your constraint(s).
How do you add a constraint?
ALTER TABLE `event` ADD CONSTRAINT `category_event`
FOREIGN KEY (`category_id`) REFERENCES `category` (`category_id`);
In this example, it assumes your event table has the foreign key category_id in it, to create your linkage. After adding this constraint, if you attempt to delete a row from the category table, and an existing event row contains that key, mysql will disallow the DELETE and return an error. This is discussed in great detail here: http://dev.mysql.com/doc/refman/5.6/en/innodb-foreign-key-constraints.html

What is the meaning of self referencing foreign key?

I went over a legacy database and found a couple of foreign keys that reference a column to itself. The referenced column is the primary key column.
ALTER TABLE [SchemaName].[TableName] WITH CHECK ADD
CONSTRAINT [FK_TableName_TableName] FOREIGN KEY([Id])
REFERENCES [SchemaName].[TableName] ([Id])
What is the meaning of it?
ALTER TABLE [SchemaName].[TableName] WITH CHECK ADD
CONSTRAINT [FK_TableName_TableName] FOREIGN KEY([Id])
REFERENCES [SchemaName].[TableName] ([Id])
This foreign key is completely redundant and pointless just delete it. It can never be violated as a row matches itself validating the constraint.
In a hierarchical table the relationship would be between two different columns (e.g. Id and ParentId)
As for why it may have been created quite likely through use of the visual designer if you right click the "Keys" node in object explorer and choose "New Foreign Key" then close the dialogue box without deleting the created foreign key and then make some other changes in the opened table designer and save it will create this sort of redundant constraint.
In some cases this is a preferred way to reduce redundancy in your model. In using the self referencing foreign key (as shown in you example) you create a hierarchical relationship between rows in your table. Pay attention to what happens when you delete a row from the table, cascading on delete might remove rows you still want.
Using these sort of keys moves some of the data validation to the DB model as opposed to making this a responsibility of the program/programmer. Some outfits prefer this way of doing things. I prefer to make sure programs and programmers are responsible - data models can be hard to refactor and upgrade in production environments.

In MySQL, why do I have to define ForeignKey relationships?

Why can't I just leave those relationships out?
What's the point of them?
I can stil run queries and treat them like it a relationship myself...
Yes, you can always leave the foreign key constraints out but then you will be responsible about the integrity of your data. If you use foreign key constraints, then you won't have to worry about the referential integrity among tables. You can read more about referential integrity from Wikipedia. I will also try to explain it with an example below.
Think of a shopping cart scenario. You have three tables: item, shopping_cart and shopping_cart_item. You can choose not to define any relationship between these tables, that's fine for any SQL solution. When user starts shopping, you create a shopping cart by adding a shopping_cart entry. As user adds items to his shopping cart, you save this information by adding rows to shopping_cart_item table.
One problem may occur at this step: If you have a buggy code that assigns incorrect shopping_cart_id's to shopping_cart_items, then you will definitely end up with incorrect data! Yes, you can have this case even with a foreign key constraint if the assigned id actually exists in the shopping_cart table. But this error will be more detectable when a foreign key exists since it would not insert shopping_cart_item record when the foreign key constraint fails.
Let's continue with the assumption that your code is not buggy and you won't have first type of referential integrity. Then suddenly a user wants to stop shopping and delete the cart and you chose to implement this case by deleting the shopping_cart and shopping_cart_item entries. Then you will have to delete entries in both tables with two separate queries. If something goes wrong after you delete shopping_cart entries, then you will again have a referential integrity problem: You will have shopping_cart_items that are not related to any shopping_cart. You will then have to introduce transaction managing, try to provide meaningful data to your business logic about the error happened in data access layer, etc..
In this type of scenario's, foreign keys can save life. You can define a foreign key constraint that will prevent insertion of any sort of incorrect data and you can define cascade operations that will automatically perform deletion of related data.
If there is anything unclear, just leave a comment and I can improve the answer.
Apart from what the others have said about why you technically want (actually: need) them:
foreign key constraints also document your model.
When looking at a model without FK constraints you have no idea which table relates to which. But with FK constraints in place you immediately see how things belong together.
You create FOREIGN KEYs to instruct the database engine to ensure that you never perform an action on the database that creates invalid records.
So, if you create a FOREIGN KEY relationship between users.id and visits.userid the engine will refuse to perform any actions that result in a userid value in visits that does not exist in users. This might be adding an unknown userid to visits, removing an id from users that already exists in visits, or updating either field to "break" the relationship.
That is why PRIMARY and FOREIGN KEYs are referred to as referential integrity constraints. The tell your database engine how to keep your data correct.
It doesn't allow you to enter an id which does not exist in another table, for example, if you have products and you keep owner Id, by creating a foreign key ton the owner id to id field of the owners table, you do not allow users to create an object record which has an owner id which does not exist in the owner table. such things are called referential intergrity.
The foreign key constraint helps you ensure referential integrity.
If you delete a row in one table, mysql can automatically delete all rows in other tables that the deleted row refers to via the foreign key. You can also make it reject the delete command.
Also when you try to insert a row, mysql can automatically create new rows in other tables, so the foreign key does not refer to nothing.
That is what referential integrity is all about.
Databases can be affected by more than just the application. Not all data changes go through the application even if they are supposed to. People change stuff directly on the database all the time. Rules that need to apply to all data all the time belong on the database. Suppose you can update the prices of your stock. That's great for updating anindividual price. But what happens when the boss decides to raise all prices by 15%. No one is going to go through and change 10,000 prices one at a time through the GUI, they are going to write a quick SQL script to do the update. Or suppose two suppliers join together to have one company and you want to change all of thie items to be the new company. Those kinds of changes happen to databases every day and they too need to follow the rules for data integrity.
New developers may not know about all the places where the foreign key relationships should exist and thus make mistakes which cause the data to be no longer useful.
Databases without foreign key constraints have close to a 100% chance of having bad data in them. Do you really want to have orders where you can't identify who the customers were?
THe FKS will prevent you from deleting a customer who has orders for instance or if you use a natural key of company_name and the name changes, all related records must be changed with the key change.
Or suppose you decide to put a new GUI together and dump the old one, then you might have to figure out all the FK relationships again (because you are using a different datalayer or ORM) and the chances are you might miss some.
It is irresponsible in the extreme to not put in FK relationships. You are risking the lifeblood of your company's business because you think it is a pain to do. I'd fire you if you suggested not using FKs because I would know I couldn't trust my company's data to you.