Django foreign key integrity with MyISAM - mysql

If MyISAM doesn't have FK integrity, how does a django app that uses MyISAM tables enforce the integrity of the FK constaints?

Poorly. It does its level best to issue updates and deletes when the referant changes, based on information it has already loaded from prior interactions, but there's just nothing protecting your data from becoming inconsistent.
The ForeignKey construct exists less to declare the integrity constraints as it does to tell django how the different tables link together, so you can traverse in python through the attributes to other model instances of other types. The orm-driven cascading is at best a band-aid over the shortcomings of databases like MyISAM. If this is important to you (and it should be), you should migrate away from the MyISAM engine to InnoDB or PostgreSQL.

Related

Why in Joomla 3.0.1 installation sql script ENGINE=InnoDB is used?

Can someone please explain why in Joomla! 3.0.1 installation sql script for MySQL is used ENGINE=InnoDB !?! Is there a particular reason !??!?
The 2 major types of table storage engines for MySQL databases are InnoDB and MyISAM. To summarize the differences of features and performance,
InnoDB is newer while MyISAM is older.
InnoDB is more complex while MyISAM is simpler.
InnoDB is more strict in data integrity while MyISAM is loose.
InnoDB implements row-level lock for inserting and updating while
MyISAM implements table-level lock.
InnoDB has transactions while MyISAM does not.
InnoDB has foreign keys and relationship contraints while MyISAM
does not.
InnoDB has better crash recovery while MyISAM is poor at recovering
data integrity at system crashes.
MyISAM has full-text search index while InnoDB has not.
In light of these differences, InnoDB and MyISAM have their unique
advantages and disadvantages against each other. They each are more
suitable in some scenarios than the other.
Advantages of InnoDB
InnoDB should be used where data integrity comes a priority because it inherently takes care of them by the help of relationship constraints and transactions.
Faster in write-intensive (inserts, updates) tables because it utilizes row-level locking and only hold up changes to the same row that’s being inserted or updated.
Disadvantages of InnoDB
Because InnoDB has to take care of the different relationships between tables, database administrator and scheme creators have to take more time in designing the data models which are more complex than those of MyISAM.
Consumes more system resources such as RAM. As a matter of fact, it is recommended by many that InnoDB engine be turned off if there’s no substantial need for it after installation of MySQL.
No full-text indexing.
Advantages of MyISAM
Simpler to design and create, thus better for beginners. No worries about the foreign relationships between tables.
Faster than InnoDB on the whole as a result of the simpler structure thus much less costs of server resources.
Full-text indexing.
Especially good for read-intensive (select) tables.
Disadvantages of MyISAM
No data integrity (e.g. relationship constraints) check, which then comes a responsibility and overhead of the database administrators and application developers.
Doesn’t support transactions which is essential in critical data applications such as that of banking.
Slower than InnoDB for tables that are frequently being inserted to or updated, because the entire table is locked for any insert or update.
The comparison is pretty straightforward.
InnoDB is more suitable for data critical situations that require frequent inserts and updates.
MyISAM, on the other hand, performs better with applications that don’t quite depend on the data integrity and mostly just select and display the data.
Read more
Considering the fact that they aren't using any foreign key constraints it's actually a really good question.
Since they are not using foreign constraints themselves there are a couple of reasons that come to my mind why they might use InnoDB over MyISAM which are:
They have some future plans to stricten data integrity at some point in time.
They want to allow people who write extensions for Joomla to refer to existing data and make hard constraints if that's what the creator desires. I.E.: Let's imagine a component that stores notes for users in Joomla system. An author could then create a table like so:
CREATE TABLE IF NOT EXISTS `#__notes` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`note` VARCHAR(255) NOT NULL,
`owner` INT(11) NOT NULL,
PRIMARY KEY (`id`),
INDEX (`owner`),
CONSTRAINT FOREIGN KEY (`owner`) REFERENCES `#__users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
then the author could be sure that an owner for the notes actually exists and he won't have any garbage leftover in case a user is removed from the system as all the notes that belongs to a certain user would be removed as well due to set CASCADE on delete action which is very convenient if you don't want to maintain clean database manually which would not be possible if databases you would want to refer to would use different engine, namely MyISAM.

MySQL & FK constraints

Is there any point in defining FK constraints in MyISAM? MyISAM doesn't enforce referential integrity, right? So maybe there is no point to FK constraints.
Although MySQL parses and ignores them on MyISAM tables, I think you should write them for three reasons.
Preparation: Your code will be ready when MyISAM gets there.
Documentation: Everybody will know what you intended. Much better than trying to figure out where foreign keys are supposed to go a year from now.
Insurance: If MyISAM fails you, you can move directly to InnoDB tables.
http://dev.mysql.com/doc/refman/5.0/en/ansi-diff-foreign-keys.html
At the end of second column:
At a later stage, foreign key constraints will be implemented for
MyISAM tables as well.
apparently in mysql 5.0 'latter stage' has not come yet
constraints are needed as an additional validation

Quick question about relational one-to many database

I'm doing a venue/events database and I've created my tables and would like some confirmation from someone if I did everything right :)
I have 2 tables:
Venues
Events
The primary key of Venues is VENUE_ID, which is set to auto_increment. I have the same column in Events, which will contain the number of the Venue ID. This should connect them, right?
Also, the table engine is MyISAM.
It does not automatically link the tables to each others, and the referenced columns don't necessarily have to have the same name (in fact, there are situations where this is impossible: e.g. when a table has two columns that both reference the same column in another table).
Read up on foreign keys; they're standard SQL and do exactly what you want. Note, however, that the MyISAM storage engine cannot enforce foreign key constraints, so as long as any of the tables involved uses MyISAM, the foreign key declaration doesn't add much (it does, however, document the relationship, at least in your SQL scripts).
I suggest you use InnoDB (or, if that's feasible, switch to PostgreSQL - not only does it provide foreign key constraints, it also has full support for transactions, unlike MySQL, which will silently commit a pending transaction whenever you do something that's not supported in a transaction, with potentially devastating results). If you have to / want to use MySQL, I suggest you use InnoDB for everything, unless you know you need the extra performance you can get out of MyISAM and you can afford the caveats. Also keep in mind that migrating large tables from MyISAM to InnoDB later in production can be painful or even outright impossible.
Your db structure is right.
You can use Innodb for adding foreign key contraints. Also don't forget to add index to the second table for faster joining two tables.
More info about FK http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
Note to comments:
Innodb allows you to make concurrent select/(insert/update) but MyIsam allows you to do the same things if you don't delete from MyIsam table. Otherwise MyIsam will lock your whole table.
Generally, yes. This is how you indicate a one-to-many relation between two tables. You may also specifically encode the relationship into the database by setting up a Foreign Key constraint. This will allow add'l logic such as cascading.

Best practice advise for deleting tables in PHP/MySQL framework?

What are some best practices tips for tinkering, deleting tables, making reversible changes in MySQL (not production) testing server? In my case I'm learning a PHP/MySQL framework.
The only general tool I have in my toolbox is to rename files before I delete them. If there is a problem I can always return a file to its original name. I would imagine it should be OK to apply the same practice to a database, since clients can lose their connection to a host. Yet, how does a web application framework proceed when referential integrity is broken only in one place?
I guess you are referring to transactions. InnoDB engine in MySQL supports transactions as well as Foreign Key constraints.
In transactional design, you can execute a bunch of queries that need to be executed as a single entity in order to be meaningful and to maintain data integrity. A transaction is started and if something goes wrong it does a Rollback, thus reverting every change done so far, or committing the entire set of modifications in the database.
Foreign keys are constraints for referential data. Thus in a master-detail relationship you cannot e.g. refer to a master record that does not exist. If there is a table comments with a user_id referring to the users.id field , you are not allowed to enter a comment for a non-existent user.
Read more here if you will
http://dev.mysql.com/doc/refman/5.0/en/innodb-transaction-model.html
and for foreign keys
http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html

Drupal MySql database design question

I was just looking at the MySql database created by drupal after I installed it.
All the tables are in MyISAM.
With a complex software like drupal, wouldn't it make more sense to
use foreign keys and hence InnoDB tables to enforce referential integrity?
Without foreign keys all the constraint checking will happen at the
PHP end.
MySQL offers a variety of database engines for a reason - different engines offer different advantages and disadvantages. InnoDB is a great engine that offers referential integrity as well as transaction safety, but it is poorly optimized for the use case of web site where you have order of magnitude more reads then writes.
MyISAM offers the best performance for a web site where most hits need only read access to the database. In such cases referential integrity can most often be maintained by writing your data inserts and deletes in a way that they cannot succeed if they compromise integrity.
For example, instead of writing
DELETE FROM mytable WHERE id = 5
you can write
DELETE mytable FROM mytable LEFT JOIN linkedtable ON mytable.id=linkedtable.ref WHERE id = 5 AND linkedtable.ref IS NULL
This will succeed in deleting the row only when the are no external references to it.