InnoDB unique keys and indexes - mysql

I used the following create statement:
CREATE TABLE `subscr` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`media_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY (`media_id`, `user_id`),
CONSTRAINT FOREIGN KEY (`media_id`) REFERENCES `media` (`id`) ON DELETE CASCADE,
CONSTRAINT FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB
Why does InnoDB only put an index on user_id? I thought it needed indexes on all foreign key references.
CREATE TABLE `subscr` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`media_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `media_id` (`media_id`,`user_id`),
KEY `user_id` (`user_id`),
CONSTRAINT `subscriptions_media_ibfk_1` FOREIGN KEY (`media_id`) REFERENCES `media` (`id`) ON DELETE CASCADE,
CONSTRAINT `subscriptions_media_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB

media_id has an index, too, and it's unique. It's sufficient the way it is for MySQL. There's just a separate index created for user_id, since user_id in the unique index is second, and therefore it's useless for the foreign key.

Related

How to create composite foreign key in Mysql

I need to add composite foreign key to table which structure looks like
CREATE TABLE IF NOT EXISTS `discount_month_devices` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`discount_month_id` int(11) UNSIGNED NOT NULL,
`global_device_id` int(11) DEFAULT NULL,
`location_id` int(11) UNSIGNED DEFAULT NULL,
`server_id` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `discount_month_id` (`discount_month_id`),
KEY `global_device_id` (`global_device_id`),
KEY `location_id` (`location_id`,`server_id`),
KEY `server_id` (`server_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Devices table DDL looks like
CREATE TABLE IF NOT EXISTS `devices` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`server_id` varchar(20) CHARACTER SET utf8mb4 NOT NULL,
`device_id` int(11) DEFAULT NULL,
`location_id` int(11) UNSIGNED DEFAULT NULL,
`device_lat` float DEFAULT NULL,
`device_long` float DEFAULT NULL,
....
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `devices_idx1` (`server_id`,`device_id`) USING BTREE,
KEY `devices_idx5` (`server_id`) USING BTREE,
KEY `devices_idx6` (`device_id`) USING BTREE,
KEY `devices_idx8` (`server_id`,`owner_id`) USING BTREE,
KEY `server_id` (`server_id`,`location_id`),
KEY `devices_idx14` (`location_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1583586 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC;
ALTER TABLE `devices`
ADD CONSTRAINT `devices_fk1` FOREIGN KEY (`server_id`,`location_id`) REFERENCES `locations` (`server_id`, `location_id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `devices_fk2` FOREIGN KEY (`discount_month_id`) REFERENCES `discount_month` (`id`);
There are location_id composite index. I can create FK for location_id and server_id separately so columns types and ranges should be right.
I would like to run alter table which should add the foreign which looks like
ALTER TABLE `discount_month_devices` ADD CONSTRAINT `discount_month_devices_fk3`
FOREIGN KEY (`location_id`, `server_id`) REFERENCES `devices`(`location_id`, `server_id`)
ON DELETE CASCADE ON UPDATE CASCADE;
This throws me an error: General error: 1215 Cannot add foreign key constraint
Does anybody know what could be the problem.
You must list the columns in the foreign key constraint in the same order that they appear in a key in the referenced table. Your key in devices is on (server_id, location_id) but you tried to reference them in your foreign key constraint as (location_id, server_id).
Try this:
ALTER TABLE `discount_month_devices`
ADD CONSTRAINT `discount_month_devices_fk3`
FOREIGN KEY (`server_id`, `location_id`)
REFERENCES `devices`(`server_id`, `location_id`)
ON DELETE CASCADE ON UPDATE CASCADE;
The order of columns in keys and constraints is not required to match the order of columns in the table definition.

mysql sometimes removes and old index when adding a new index?

TL;DR
We've seen on a virtual machine, that adding a UNIQUE index causes an older non-UNIQUE index to be removed automatically.
I cannot reproduce this on any other machines (yet?), and if I do:
mysql -e 'create db2'
mysqldump db1 | mysql db2
before adding the new index to db1, and then try adding the index on db2 instead, the old index is not removed from db2. Funky!
We have a snapshot of the machine with db1, and can reproduce it there in the existing db1 database...
Anybody have any idea what is going on? We have scripts to automate adding/removing indexes, and that started failing because on that one machine, the old index didn't exist any longer.
When a dump/restore cycle causes the problem to go away, that makes it hard understand, reproduce and reduce the problem to a simple example.
Details
The table in question looked like this before adding the new index (from SHOW CREATE TABLE). Note the monitoredTableRowID KEY:
CREATE TABLE `cfgAttributeInstances` (
`ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`attributeID` int(10) unsigned DEFAULT NULL,
`nodeID` int(10) unsigned DEFAULT NULL,
`groupID` int(10) unsigned DEFAULT NULL,
`statisticID` int(10) unsigned DEFAULT NULL,
`nodeStatisticID` int(10) unsigned DEFAULT NULL,
`serviceID` int(10) unsigned DEFAULT NULL,
`nodeServiceID` int(10) unsigned DEFAULT NULL,
`nodeComponentID` int(10) unsigned DEFAULT NULL,
`syslogFilterID` int(10) unsigned DEFAULT NULL,
`value` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`ID`),
UNIQUE KEY `nodeID` (`nodeID`,`attributeID`),
UNIQUE KEY `groupID` (`groupID`,`attributeID`),
UNIQUE KEY `statisticID` (`statisticID`,`attributeID`),
UNIQUE KEY `nodeStatisticID` (`nodeStatisticID`,`attributeID`),
UNIQUE KEY `serviceID` (`serviceID`,`attributeID`),
UNIQUE KEY `nodeServiceID` (`nodeServiceID`,`attributeID`),
KEY `attributeID` (`attributeID`),
KEY `monitoredTableRowID` (`nodeComponentID`),
KEY `syslogFilterID` (`syslogFilterID`),
CONSTRAINT `cfgAttributeInstances_ibfk_1` FOREIGN KEY (`attributeID`) REFERENCES `cfgAttributes` (`ID`) ON DELETE CASCADE,
CONSTRAINT `cfgAttributeInstances_ibfk_2` FOREIGN KEY (`nodeID`) REFERENCES `cfgNodes` (`ID`) ON DELETE CASCADE,
CONSTRAINT `cfgAttributeInstances_ibfk_3` FOREIGN KEY (`groupID`) REFERENCES `cfgGroups` (`ID`) ON DELETE CASCADE,
CONSTRAINT `cfgAttributeInstances_ibfk_4` FOREIGN KEY (`statisticID`) REFERENCES `cfgStatistics` (`ID`) ON DELETE CASCADE,
CONSTRAINT `cfgAttributeInstances_ibfk_5` FOREIGN KEY (`nodeStatisticID`) REFERENCES `cfgNodeStatistics` (`ID`) ON DELETE CASCADE,
CONSTRAINT `cfgAttributeInstances_ibfk_6` FOREIGN KEY (`serviceID`) REFERENCES `cfgServices` (`ID`) ON DELETE CASCADE,
CONSTRAINT `cfgAttributeInstances_ibfk_7` FOREIGN KEY (`nodeServiceID`) REFERENCES `cfgNodeServices` (`ID`) ON DELETE CASCADE,
CONSTRAINT `cfgAttributeInstances_ibfk_8` FOREIGN KEY (`nodeComponentID`) REFERENCES `cfgNodeComponents` (`ID`) ON DELETE CASCADE,
CONSTRAINT `cfgAttributeInstances_ibfk_9` FOREIGN KEY (`syslogFilterID`) REFERENCES `cfgSyslogFilters` (`ID`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='CapMon Attribute instances';
I added this index:
ALTER TABLE cfgAttributeInstances ADD
UNIQUE new_nodeComponentID (nodeComponentID, attributeID)
It looked like this after adding that index:
CREATE TABLE `cfgAttributeInstances` (
`ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`attributeID` int(10) unsigned DEFAULT NULL,
`nodeID` int(10) unsigned DEFAULT NULL,
`groupID` int(10) unsigned DEFAULT NULL,
`statisticID` int(10) unsigned DEFAULT NULL,
`nodeStatisticID` int(10) unsigned DEFAULT NULL,
`serviceID` int(10) unsigned DEFAULT NULL,
`nodeServiceID` int(10) unsigned DEFAULT NULL,
`nodeComponentID` int(10) unsigned DEFAULT NULL,
`syslogFilterID` int(10) unsigned DEFAULT NULL,
`value` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`ID`),
UNIQUE KEY `nodeID` (`nodeID`,`attributeID`),
UNIQUE KEY `groupID` (`groupID`,`attributeID`),
UNIQUE KEY `statisticID` (`statisticID`,`attributeID`),
UNIQUE KEY `nodeStatisticID` (`nodeStatisticID`,`attributeID`),
UNIQUE KEY `serviceID` (`serviceID`,`attributeID`),
UNIQUE KEY `nodeServiceID` (`nodeServiceID`,`attributeID`),
UNIQUE KEY `new_nodeComponentID` (`nodeComponentID`,`attributeID`),
KEY `attributeID` (`attributeID`),
KEY `syslogFilterID` (`syslogFilterID`),
CONSTRAINT `cfgAttributeInstances_ibfk_1` FOREIGN KEY (`attributeID`) REFERENCES `cfgAttributes` (`ID`) ON DELETE CASCADE,
CONSTRAINT `cfgAttributeInstances_ibfk_2` FOREIGN KEY (`nodeID`) REFERENCES `cfgNodes` (`ID`) ON DELETE CASCADE,
CONSTRAINT `cfgAttributeInstances_ibfk_3` FOREIGN KEY (`groupID`) REFERENCES `cfgGroups` (`ID`) ON DELETE CASCADE,
CONSTRAINT `cfgAttributeInstances_ibfk_4` FOREIGN KEY (`statisticID`) REFERENCES `cfgStatistics` (`ID`) ON DELETE CASCADE,
CONSTRAINT `cfgAttributeInstances_ibfk_5` FOREIGN KEY (`nodeStatisticID`) REFERENCES `cfgNodeStatistics` (`ID`) ON DELETE CASCADE,
CONSTRAINT `cfgAttributeInstances_ibfk_6` FOREIGN KEY (`serviceID`) REFERENCES `cfgServices` (`ID`) ON DELETE CASCADE,
CONSTRAINT `cfgAttributeInstances_ibfk_7` FOREIGN KEY (`nodeServiceID`) REFERENCES `cfgNodeServices` (`ID`) ON DELETE CASCADE,
CONSTRAINT `cfgAttributeInstances_ibfk_8` FOREIGN KEY (`nodeComponentID`) REFERENCES `cfgNodeComponents` (`ID`) ON DELETE CASCADE,
CONSTRAINT `cfgAttributeInstances_ibfk_9` FOREIGN KEY (`syslogFilterID`) REFERENCES `cfgSyslogFilters` (`ID`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='CapMon Attribute instances';
But hey! Where did the monitoredTableRowID index go?
Again, I cannot reproduce this. If I do a mysqldump > dump.db/mysql < dump.db cycle, the monitoredTableRowID doesn't disappear...
Any ideas on what is going on?
The composite key with nodeComponentID causes the non-composite key with nodeComponentID to be redundant within the context of the foreign key reference it is used. MySQL automatically drops the redundant implicit index. The behavior is dependant on column index ordering, as the dropped index will always be the first column within the defined composite key. [sic]
The issue(s) are specifically caused by the automatic implicit index created when adding a foreign key CONSTRAINT, and the index(es) being explicitly defined in SHOW CREATE TABLE which is also used by mysqldump.
The index_name value is ignored if there is already an explicitly
defined index on the child table that can support the foreign key.
Otherwise, MySQL implicitly creates a foreign key index... [sic]
MySQL requires indexes on foreign keys and referenced keys so that
foreign key checks can be fast and not require a table scan. In the
referencing table, there must be an index where the foreign key
columns are listed as the first columns in the same order. Such an
index is created on the referencing table automatically if it does not
exist. This index might be silently dropped later, if you create
another index that can be used to enforce the foreign key constraint.
index_name, if given, is used as described previously. [sic]
To reproduce the issue
Implicit Key Example db-fiddle
Note - INDEX FK_BAR_FOO (foo_id) is not explicitly defined.
DROP TABLE IF EXISTS `BAR`;
DROP TABLE IF EXISTS `FOO`;
CREATE TABLE `FOO` (
`id` INT(11) NOT NULL,
PRIMARY KEY (`id`)
)
ENGINE=InnoDB
;
CREATE TABLE `BAR` (
`id` INT(11) NOT NULL,
`foo_id` INT(11) NOT NULL,
`b` INT(11) NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `FK_BAR_FOO` FOREIGN KEY (`foo_id`) REFERENCES `FOO` (`id`) ON DELETE CASCADE
)
ENGINE=InnoDB
;
SHOW CREATE TABLE `BAR`;
Result
INDEX FK_BAR_FOO (foo_id) is explicitly defined in SHOW CREATE TABLE, but is implicitly created by MySQL.
CREATE TABLE `BAR` (
`id` INT(11) NOT NULL,
`foo_id` INT(11) NOT NULL,
`b` INT(11) NOT NULL,
PRIMARY KEY (`id`),
INDEX `FK_BAR_FOO` (`foo_id`),
CONSTRAINT `FK_BAR_FOO` FOREIGN KEY (`foo_id`) REFERENCES `FOO` (`id`) ON DELETE CASCADE
)
ENGINE=InnoDB
;
Composite Key Example: db-fiddle
ALTER TABLE `BAR`
ADD UNIQUE INDEX `foo_id_b` (`foo_id`, `b`);
SHOW CREATE TABLE `BAR`;
Result
foo_id index is removed due to being redundant.
Since foo_id is the first column within the composite key, the implicit foo_id index FK_BAR_FOO is removed.
CREATE TABLE `BAR` (
`id` INT(11) NOT NULL,
`foo_id` INT(11) NOT NULL,
`b` INT(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `foo_id_b` (`foo_id`, `b`),
CONSTRAINT `FK_BAR_FOO` FOREIGN KEY (`foo_id`) REFERENCES `FOO` (`id`) ON DELETE CASCADE
)
ENGINE=InnoDB
;
Explicit Key Example: db-fiddle
MySQL ignores the redundant indexes, if the table was created with an explicit index that satisfies the foreign key CONSTRAINT.
DROP TABLE IF EXISTS `BAR`;
DROP TABLE IF EXISTS `FOO`;
CREATE TABLE `FOO` (
`id` INT(11) NOT NULL,
PRIMARY KEY (`id`)
)
ENGINE=InnoDB
;
CREATE TABLE `BAR` (
`id` INT(11) NOT NULL,
`foo_id` INT(11) NOT NULL,
`b` INT(11) NOT NULL,
PRIMARY KEY (`id`),
INDEX `FK_BAR_FOO` (`foo_id`),
CONSTRAINT `FK_BAR_FOO` FOREIGN KEY (`foo_id`) REFERENCES `FOO` (`id`) ON DELETE CASCADE
)
ENGINE=InnoDB
;
ALTER TABLE `BAR`
ADD UNIQUE INDEX `foo_id_b` (`foo_id`, `b`);
SHOW CREATE TABLE `BAR`;
Result
Composite-key index for foo_id, b and index on foo_id are created.
CREATE TABLE `BAR` (
`id` INT(11) NOT NULL,
`foo_id` INT(11) NOT NULL,
`b` INT(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `foo_id_b` (`foo_id`, `b`),
INDEX `FK_BAR_FOO` (`foo_id`),
CONSTRAINT `FK_BAR_FOO` FOREIGN KEY (`foo_id`) REFERENCES `FOO` (`id`) ON DELETE CASCADE
)
ENGINE=InnoDB
;
Solution
In your scripts, verify the index (does not) exist before attempting to drop/add the index.
IF NOT EXISTS(
SELECT 1 FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_NAME = 'cfgAttributeInstances'
AND INDEX_NAME = 'new_nodeComponentID'
AND INDEX_SCHEMA = 'DbName')
THEN
ALTER TABLE `cfgAttributeInstances`
ADD UNIQUE INDEX `new_nodeComponentID` (`nodeComponentID`,`attributeID`);
END IF;
IF EXISTS (
SELECT 1 FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_NAME = 'cfgAttributeInstances'
AND INDEX_NAME = 'nodeComponentID'
AND INDEX_SCHEMA = 'DbName')
THEN
ALTER TABLE `cfgAttributeInstances`
DROP INDEX `nodeComponentID`;
END IF;

Foreign key constraint fails when I want delete table

When I am trying
drop tables users;
It shows error: Cannot delete or update a parent row: a foreign key constraint fails
Here are my tables:
CREATE TABLE `events` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(128) NOT NULL,
`users_id` int(11) NOT NULL,
`capacity` int(64) NOT NULL,
`event_date` datetime NOT NULL,
`text` text CHARACTER SET utf8 COLLATE utf8_czech_ci,
`last_edit` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `users_id` (`users_id`),
CONSTRAINT `events_ibfk_5` FOREIGN KEY (`users_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`email` varchar(100) NOT NULL,
`password` varchar(100) NOT NULL,
`role` enum('admin','member','guest','registered') NOT NULL DEFAULT 'registered',
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `users_data` (
`id` int(120) NOT NULL AUTO_INCREMENT,
`users_id` int(11) DEFAULT NULL,
`name` varchar(50) NOT NULL,
`username` varchar(50) NOT NULL,
`phone_number` varchar(25) NOT NULL,
PRIMARY KEY (`id`),
KEY `users_id` (`users_id`),
CONSTRAINT `users_data_ibfk_5` FOREIGN KEY (`users_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `user_matches` (
`user_id` int(120) NOT NULL,
`match_id` int(11) NOT NULL,
KEY `user_id` (`user_id`),
KEY `match_id` (`match_id`),
CONSTRAINT `user_matches_ibfk_4` FOREIGN KEY (`user_id`) REFERENCES `users_data` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `user_matches_ibfk_5` FOREIGN KEY (`match_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
I think I did wrong foreign key but I am not sure how to change it correctly. Thank you for your any advice.
When you submit drop table users MySQL checks for referential integrity constraints violation when the deletion is about to be committed. This check fails because you have defined the following constraint of events:
CONSTRAINTevents_ibfk_5FOREIGN KEY (users_id) REFERENCESusers(id) ON DELETE CASCADE ON UPDATE CASCADE
and at the same time on the events table the users_id field cannot be NULL. Therefore, upon dropping the table, the users_id is set to NULL which fails during commit. One possible way to work around this problem is to remove the NOT NULL constraint on the users_id field on the events table.

Foreign key constraint fails even when data types are the same

I'm building a table with a two part foreign key that references a two part key in another table. It isn't working, and I can't see why because the data types line up.
Can't create table 'tsugi.video_comments' (errno: 150)
Here's the code I'm trying to run:
CREATE TABLE `video_comments` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`video_id` varchar(11) NOT NULL DEFAULT '',
`link_id` int(11) NOT NULL,
`videoTime` int(11) NOT NULL,
`comment` text NOT NULL,
`parent` int(11) unsigned DEFAULT NULL,
`private` tinyint(1) DEFAULT NULL,
`replies` int(11) unsigned DEFAULT '0',
`reports` int(11) DEFAULT '0',
`user_id` int(11) NOT NULL,
`displayname` varchar(2048) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `video_ibfk_1` (`link_id`),
KEY `video_ibfk_2` (`user_id`),
CONSTRAINT `video_comments_ibfk_1` FOREIGN KEY (`parent`) REFERENCES `video_comments` (`id`) ON DELETE CASCADE,
CONSTRAINT `video_ibfk_1` FOREIGN KEY (`link_id`) REFERENCES `lti_link` (`link_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `video_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `lti_user` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `video_key` FOREIGN KEY (`link_id`, `video_id`) REFERENCES `video_ids` (`link_id`, `video_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=285 DEFAULT CHARSET=utf8;
The command runs successfully if I delete the last constraint, so that's where the problem is, not in the other constraints.
Here's the table it's referencing:
CREATE TABLE `video_ids` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`video_id` varchar(11) NOT NULL DEFAULT '',
`link_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `video_key` (`video_id`,`id`),
KEY `link_id` (`link_id`),
KEY `id` (`id`,`video_id`),
CONSTRAINT `video_ids_ibfk_1` FOREIGN KEY (`link_id`) REFERENCES `t_lti_link` (`link_id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
To make sure that the video_id and link_id fields are exactly the same, I copied them directly from the existing table's code to the code for creating the new table. I expected that to solve it, but it did not. Here's the error log:
------------------------
LATEST FOREIGN KEY ERROR
------------------------
141114 22:04:09 Error in foreign key constraint of table tsugi/video_comments:
FOREIGN KEY (`link_id`, `video_id`) REFERENCES `video_ids` (`link_id`, `video_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=285 DEFAULT CHARSET=utf8:
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
See http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
for correct foreign key definition.
Foreign key references need to be to unique or primary keys. So, you can fix this just by having a unique declaration in video_ids:
CREATE TABLE `video_ids` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`video_id` varchar(11) NOT NULL DEFAULT '',
`link_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `video_key` (`video_id`,`id`),
KEY `link_id` (`link_id`),
KEY `id` (`id`,`video_id`),
UNIQUE (link_id, video_id),
CONSTRAINT `video_ids_ibfk_1` FOREIGN KEY (`link_id`) REFERENCES `t_lti_link` (`link_id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
Here is a SQL Fiddle with an example.

An InnoDB column marked with "using btree" why?

from an unknown reason:
CREATE TABLE `orders_products` (
`ORDER_ID` int(10) unsigned NOT NULL,
`PRODUCT_ID` int(10) unsigned NOT NULL,
`QUANTITY` tinyint(3) unsigned NOT NULL,
`USER_ID` int(10) unsigned NOT NULL,
PRIMARY KEY (`ORDER_ID`,`PRODUCT_ID`,`USER_ID`) USING BTREE,
KEY `FK_orders_products_3` (`USER_ID`),
KEY `FK_orders_products_2` (`PRODUCT_ID`) USING BTREE,
CONSTRAINT `FK_orders_products_1` FOREIGN KEY (`ORDER_ID`) REFERENCES `orders` (`ID`) ON DELETE CASCADE,
CONSTRAINT `FK_orders_products_2` FOREIGN KEY (`PRODUCT_ID`) REFERENCES `products` (`ID`) ON DELETE CASCADE,
CONSTRAINT `FK_orders_products_3` FOREIGN KEY (`USER_ID`) REFERENCES `users` (`ID`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
primary key and FK_orders_products_2 got BTREE. How to know it? Neither SHOW INDEX, nor DESCRIBE TABLE describes who using BTREE and who doesnt
You can get information about the keys using
SHOW KEYS FROM orders_products
There's an INDEX_TYPE column in that resultset.