Задавайте вопросы, мы ответим
Вы не зашли.
Страниц: 1
Доброго дня, Коллеги!
Назрел насущный вопрос, к сожалению, на нашел на него в документации прямого ответа, кто может ткнуть носом в нужный параграф доки - ткните плиз.
Environment: Mysql 5.6, Debian.
Суть: Есть таблица t с много-много записей. Тип InnoDB. Одно из полей f - ссылка на поле f1 другой таблицы t1.
Суть вопроса - если добавить foreign key на t.f references t1.f1 (не создавай ключика на поле t.f) - это же не увеличит
размер таблицы (с точки зрения занимаемого таблицей дискогого пространства)? Эксперимент показал, что нет - но вдруг я не учел чего.
И еще - сам механизм проверки foreign key - это просто невидимый для нас триггер или что-то более глубокое?
Неактивен
на t.f должен быть ключ. В старых версиях его нужно было создавать явно, иначе ошибка. В новых он создается автоматически.
The columns in the child table must be an index, or the leftmost part of an index. Index prefixes are not supported (thus, TEXT and BLOB columns cannot be used as foreign keys). If MariaDB automatically creates an index for the foreign key (because it does not exist and is not explicitly created), its name will be index_name.
https://mariadb.com/kb/en/mariadb/foreign-keys/
Неактивен
Вася, спасибо!
Ты говоришь про MariaDB, в MySQL точно также? Какие версии, к слову, ты подразумеваешь под новыми и старыми?
Впрочем, проведу эксперимент, отпишусь.
Неактивен
В MySQL также.
К слову в доке 5.0 ( http://dev.mysql.com/doc/refman/5.0/en/ … aints.html ) было сказано:
Such an index is created on the referencing table automatically if it does not exist. (This is in contrast to some older versions, in which indexes had to be created explicitly or the creation of foreign key constraints would fail.)
Но теперь минимальная дока - 5.5, а там этого нет. Приходится полагаться на память
(хотя нет, можно скачать в архиве старую доку http://dev.mysql.com/doc/index-archive.html )
Соответственно, errno 150 возникало для четвертой версии.
Неактивен
В оперативную память своей головы diffы между документациями версий загружает только верховный шаман sqlinfo .
Понял, буду пробовать. А то табличка на диске весит чуть не 100 гб, "лишний" FK, а соответственно индекс может хорошо скушать место.
Неактивен
deadka написал:
И еще - сам механизм проверки foreign key - это просто невидимый для нас триггер или что-то более глубокое?
вот тут paulus говорил, что fk это третья табличка связей, которую видит только innodb.
Неактивен
Ага, спасибо. По существу вопроса я проверил на версии 5.6 - foreign key начинает содержать в себе одноименный индекс, который потом используется в запросах, судя по explain.
Неактивен
Ага, это то, о чем я говорил.
А из сказанного paulus-ом следует, что fk будет занимать больше места, чем обычный индекс, так как fk= index на дочерней таблице (который показывает explain) + доп таблица, которая вероятно тоже проиндексирована.
Неактивен
Кстати, всё есть на sqlinfo
http://sqlinfo.ru/forum/viewtopic.php?pid=19115#p19115
paulus написал:
Внешний ключ — это отдельная табличка many-to-many в пространстве
данных InnoDB, которая не видна из MySQL.
to paulus, а почему many-to-many? Ведь значения родительского ключа должны быть уникальны.
Неактивен
fk - да, вопрос насколько больше места будет занимать )).
paulus, присоединяюсь к вопрос про many to many.
Ну и вообще, будем рады любым каментам по сабжу.
Неактивен
Ох, ребята, вы хотите, чтобы я думал
Многие ко многим — потому что вот так:
Неактивен
paulus вышел из темноты, уря!
В контексте вопроса от vasya
( Ведь значения родительского ключа должны быть уникальны ) - мне тоже раньше так казалось, вроде даже в документации видел, что поле в "папе", куда ссылается другое поле в "дочке"-таблице - оно должно быть либо PK (который по определению NOT NULL UNIQUE) либо просто UNIQUE, твой же пример свидетельствует о том, что можно ссылаться просто на индексированное поле. А ведь так даже непонятно, на какую именно запись в a ссылается запись из b (а вот если бы поле a было бы уникально, то такого бы не было!).
Неактивен
ИМХО баг, потому что как бе противоречит логике.
mysql> CREATE TABLE a (a INT, INDEX(a)) ENGINE=InnoDB; Query OK, 0 rows affected (0.02 sec) mysql> INSERT INTO a VALUES (1), (1), (2); Query OK, 3 rows affected (0.01 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> CREATE TABLE b (b INT, INDEX(b), FOREIGN KEY(b) REFERENCES a(a)) ENGINE=InnoDB; Query OK, 0 rows affected (0.01 sec) mysql> INSERT INTO b VALUES (1), (1), (2); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> select version(); +-------------------------+ | version() | +-------------------------+ | 5.6.31-0ubuntu0.15.10.1 | +-------------------------+ 1 row in set (0.00 sec)
Неактивен
В то же время, если на поле a не создать индекса вовсе, то так все же нельзя.
mysql> CREATE TABLE a (a INT) ENGINE=InnoDB; Query OK, 0 rows affected (0.01 sec) mysql> CREATE TABLE b (b INT, INDEX(b), FOREIGN KEY(b) REFERENCES a(a)) ENGINE=InnoDB; ERROR 1215 (HY000): Cannot add foreign key constraint
Неактивен
Вот как. Специальное расширение, которое отходит от ANSI-стандарта. Остается вопрос - зачем..
vasya, а у тебя на тесте от paulus в MariaDB валится тест? Как догадываюсь, таблица b не должна создасться. Покажешь лог (и версию mariadb)?
Неактивен
5.5.23-MariaDB-log
удивительно, но создается
Неактивен
Ну тогда это либо бага в документации MariaDB либо бага в реализации.
Неактивен
Зато мы можем ещё добавить 1.
Всех пускаем, никого не выпускаем
Неактивен
Страниц: 1