Update: How to implement Foreign Key concept in MySQL when we do not have referential integrity features in MySQL?

StackOverflow https://stackoverflow.com/questions/1574102

Question

My question is regarding referential integrity concept in MySQL Database. Due to some kind of restrictions from our DBA we are not allowed to use referential integrity features of MySQL and so my question is "How can we implement Foreign Key concept in MySQL when we do not have referential integrity features in MySQL ?"

Thanks.

Was it helpful?

Solution

I assume you are using MyISAM tables? You're pretty much stuck with doing the checks yourself.

So if tableB depends on tableA, then before you delete from tableA you have to delete from tableB (or perform other update) first. With inserts you'd create the record in the main table and then create the record in the dependant table.

It's cumbersome and the only reason I've ever found for keeping a MyISAM table was FULLTEXT indexing. If I knew more about your db restrictions I could possibly make other suggestions.


ETA:

If he's restricting you from using InnoDB tables, I'd wonder about your DBA. In any event, if he won't let you create and use Innodb tables for security reasons, it's really unlikely he'll let you use stored procedures or triggers. So you'll essentially be stuck writing an application to do your CRUD operations in some scripting language.

Therefore you need to think about what the restrictions on these operations have to be for each specific case. Probably the easiest way is to map out your db schema as though it did enforce referential integrity. Include details on what, if any, actions may happen due to a change in any table. Operation sequelae options are RESTRICT, SET NULL and CASCADE.

Once you know how your db ought to respond, you can programs you queries accordingly.

So if Employees have Addresses, and addresses should disappear when an Employee is deleted:

Innodb version (where Addresses has foreign key for Employees, and ON DELETE CASCADE action)

DELETE FROM Employees WHERE employee_id=7;

MyISAM version:

DELETE FROM Employees WHERE employee_id=7;
DELETE FROM Addresses WHERE employee_id=7;

I hope this makes things a bit clearer.

OTHER TIPS

What this means is that all developers must know specifially the relationships that should be there and work from the parent table down through all the child tables when doing inserts or updates and work from the child tables up through the parent tables when doing deletes. Of course the problem is that not every developer will be aware of all the tables involved in constraints aren't set. And if you have layers of relationships, you need to go allthe way to the bottom of the chain to do a delete.

If you use an ORM, I think you can define relationships there? Not sure never used one but I think you can. Worth looking into at any rate.

If you aren't using an ORM and you can't define referential integrity, at least store the relationships in a tables somewhere so the developers can look up what tables would be affected.

Another approach if you can't define referential integrity specfically would be to enforce it through triggers.

edited to expand on triggers: If you create an instead of trigger (are these available in my sql?) on the parent table you can mimic the behavior of a cascading delete by specifying the tables to delete from before doing the actual delete (this how we used to do it in the old days before we had cascading deletes). You can also specify the tables to update if the primary key changes in an update (hopefully your design has a key that won't change, but not if you used any natural keys). An insert trigger on any child tables would see if the key field value existed in the parent table and then reject it if it did not.

I used to work with myIsam table.

So, this means you need to do manualy the job. You will need to do some SELECTs before delete some parent row for example.

It's possible to do, but without referencial integrity isn't the same. But works.

If might use stored procedures to make 'selects' easier. Another good apporach is to hide the database schema behind a model, and use it through it's interface.

One argument often heard from DBA's in this context is that "if RI is used, then unloading/loading to reorganise is harder for us to do".

This is of course true, per se, but the vilain is that the 'harder' is usually suggested to mean 'so much harder that it becomes nigh impossible for us DBAs to do our jobs'.

And THAT is bullocks.

There are persistence frameworks that will do it for you. In order to work on as many DBs as possible those frameworks don't rely on DB specific features like FKs and implement it them self. KODO is one example.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top