SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 23.08.2014 12:39:05

animegirl
Активист
Зарегистрирован: 28.07.2011
Сообщений: 288

Внешний ключ из составного индекса

Почитала мануалы, разобралась со смыслом внешних ключей, пошла улучшать свою базу. И в какой-то момент задумалась над несколькими моментами.
Аксиома - чтобы привязать колонку к внешнему ключу, она должна быть сама индексом
1. Если индекс, состоит из нескольких колонок, а я использую его для связи с внешним ключом, то привязывается первая колонка указанная в индексе?
2. Насколько плохо создавать индексы к колонкам где их раньше не было, чтобы связать их внешними ключами? Может имеет смысл как-то сам индекс ограничить, скажем до одного символа, это играет хоть какую-нибудь роль? Ранее там не было индекса, так как колонка при выборке не была критично важной.


Скажи миру - НЯ!

Неактивен

 

#2 23.08.2014 12:48:06

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3878

Re: Внешний ключ из составного индекса

1. Первая часть индекса может быть использована во внешнем ключе

2. Не ничего плохого в создании индекса, необходимого для FOREIGN KEY

Неактивен

 

#3 23.08.2014 13:00:22

animegirl
Активист
Зарегистрирован: 28.07.2011
Сообщений: 288

Re: Внешний ключ из составного индекса

rgbeast написал:

2. Не ничего плохого в создании индекса, необходимого для FOREIGN KEY

А кстати, эти индексы хранятся всё равно отдельно или их как-то склеивает движок?


Скажи миру - НЯ!

Неактивен

 

#4 23.08.2014 13:06:15

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3878

Re: Внешний ключ из составного индекса

В ссылающейся таблице индекс создастся автоматически (в неявном виде), если его нет, а если есть - будет использован. В таблице, на которую ссылается внешний ключ, индекс должен быть создан заранее.

Неактивен

 

#5 23.08.2014 13:35:33

animegirl
Активист
Зарегистрирован: 28.07.2011
Сообщений: 288

Re: Внешний ключ из составного индекса

rgbeast написал:

(в неявном виде)

Это как? Его не будет видно в основном списке индексов? И им не будет пользоваться оптимизатор?

Должна покаяться, я всё ещё не распрощалась с pma, а у него нету такой фишки, как "создать внешний ключ, не имея индекса", по этому создаю самый обыкновенный индекс, после чего соединяю. Не считая моего нежелания уходить от pma, есть ли какой-нибудь минус, такого подхода?


Скажи миру - НЯ!

Неактивен

 

#6 23.08.2014 14:37:54

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3878

Re: Внешний ключ из составного индекса

Прошу прощения, индекс создается явно, если нет подходящего.

Неактивен

 

#7 23.08.2014 15:06:34

animegirl
Активист
Зарегистрирован: 28.07.2011
Сообщений: 288

Re: Внешний ключ из составного индекса

Я за это время успела наспотыкаться о другие непонятные сущности.
1. Пытаюсь соединить с родителем колонку, которая идёт на 2+ месте в первичном индексе, но так же имеется как отдельный индекс, при удаление выбираю "SET NULL", на меня орут, что нельзя, так как поле не может быть NULL, вздыхаю, иду править настройки поля, исправила, сохранила, меняю внешний ключ - тоже самое, с 5ого раза до меня дошло, что хоть база и глотает запрос на изменения без ошибки, но атрибут колонки не меняется. Позлилась - выпилила первичный индекс, сделала такой же, но просто уникальный. Всё заработало. Я верно понимаю, что в отличии от уникального индекса, первичный не терпит NULL?

2. Совершенно непонятная логика. В одной таблице есть составной индекс, когда лезу прописывать внешний ключ, мне дают это сделать только с первой колонкой, в другой таблице, так же составной индекс, но в форме внешних ключей, можно вписывать всё, что находится в составном индексе. Я запуталась в логике мышлении движка. На картинке пример этого феномена:
http://storage6.static.itmages.ru/i/14/0823/h_1408791943_4646632_8b5a8aad99.png
http://storage5.static.itmages.ru/i/14/0823/h_1408791943_5893584_46c69da8da.png
http://storage6.static.itmages.ru/i/14/0823/h_1408791943_5725708_8a6721584b.png
http://storage7.static.itmages.ru/i/14/0823/h_1408791944_5209280_d0135a4fbd.png


Скажи миру - НЯ!

Неактивен

 

#8 23.08.2014 15:12:31

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3878

Re: Внешний ключ из составного индекса

1. PRIMARY KEY тихо делает колонку NOT NULL

2. Сформулируйте в терминах SQL.
SHOW CREATE TABLE для таблиц, а затем
ALTER TABLE .. ADD FOREIGN KEY ...
и какая ошибка получается.

Неактивен

 

#9 23.08.2014 15:32:11

animegirl
Активист
Зарегистрирован: 28.07.2011
Сообщений: 288

Re: Внешний ключ из составного индекса

rgbeast написал:

2. Сформулируйте в терминах SQL.
SHOW CREATE TABLE для таблиц, а затем
ALTER TABLE .. ADD FOREIGN KEY ...
и какая ошибка получается.

CREATE TABLE `info_lokal_kitchen` (
 `lid` bigint(20) unsigned NOT NULL,
 `kid` tinyint(3) unsigned NOT NULL,
 `showing_order` tinyint(2) unsigned NOT NULL,
 `mod_time` int(10) unsigned NOT NULL,
 `SSID` char(32) COLLATE utf8mb4_unicode_ci NOT NULL,
 `ip_front` varchar(45) COLLATE utf8mb4_unicode_ci NOT NULL,
 `ip_end` varchar(45) COLLATE utf8mb4_unicode_ci NOT NULL,
 UNIQUE KEY `lid` (`lid`,`kid`),
 CONSTRAINT `info_lokal_kitchen_ibfk_1` FOREIGN KEY (`lid`) REFERENCES `info_lokal` (`lid`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci


CREATE TABLE `info_lokal_menu` (
 `mid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
 `lid` bigint(20) unsigned NOT NULL,
 `nid` bigint(20) unsigned NOT NULL,
 `price` decimal(13,4) unsigned NOT NULL,
 `price_currency` tinyint(3) unsigned NOT NULL,
 `price_in_euro` decimal(13,4) unsigned NOT NULL,
 `mod_time` int(11) unsigned NOT NULL,
 `SSID` char(32) COLLATE utf8mb4_unicode_ci NOT NULL,
 `ip_front` varchar(45) COLLATE utf8mb4_unicode_ci NOT NULL,
 `ip_end` varchar(45) COLLATE utf8mb4_unicode_ci NOT NULL,
 PRIMARY KEY (`mid`),
 UNIQUE KEY `lid` (`lid`,`nid`),
 CONSTRAINT `info_lokal_menu_ibfk_1` FOREIGN KEY (`lid`) REFERENCES `info_lokal` (`lid`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci


ALTER TABLE `info_lokal_kitchen` ADD FOREIGN KEY ( `kid` ) REFERENCES `db`.`test` (
`test`
) ON DELETE CASCADE ON UPDATE CASCADE ;



Эта команда прошла успешно, таблица теперь выглядит так:

CREATE TABLE `info_lokal_kitchen` (
 `lid` bigint(20) unsigned NOT NULL,
 `kid` tinyint(3) unsigned NOT NULL,
 `showing_order` tinyint(2) unsigned NOT NULL,
 `mod_time` int(10) unsigned NOT NULL,
 `SSID` char(32) COLLATE utf8mb4_unicode_ci NOT NULL,
 `ip_front` varchar(45) COLLATE utf8mb4_unicode_ci NOT NULL,
 `ip_end` varchar(45) COLLATE utf8mb4_unicode_ci NOT NULL,
 UNIQUE KEY `lid` (`lid`,`kid`),
 KEY `kid` (`kid`),
 CONSTRAINT `info_lokal_kitchen_ibfk_3` FOREIGN KEY (`kid`) REFERENCES `test` (`test`) ON DELETE CASCADE ON UPDATE CASCADE,
 CONSTRAINT `info_lokal_kitchen_ibfk_1` FOREIGN KEY (`lid`) REFERENCES `info_lokal` (`lid`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci



А вот команда

ALTER TABLE `info_lokal_menu` ADD FOREIGN KEY ( `nid` ) REFERENCES `db`.`test` (
`test2`
) ON DELETE CASCADE ON UPDATE CASCADE ;


Выдала ошибку:

#1005 - Can't create table 'db.#sql-fd7_1d4' (errno: 150)




Комментарий модератора:
Все возможные причины ошибки (errno: 150) рассмотрены в статье:
Ошибки внешних ключей: errno 150, MySQL error 1005 и другие


Скажи миру - НЯ!

Неактивен

 

#10 23.08.2014 15:34:35

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3878

Re: Внешний ключ из составного индекса

Покажите
SHOW CREATE TABLE `db`.`test`;

Совпадают ли типы info_lokal_menu.nid и test.test2?

Неактивен

 

#11 23.08.2014 15:46:48

animegirl
Активист
Зарегистрирован: 28.07.2011
Сообщений: 288

Re: Внешний ключ из составного индекса

rgbeast написал:

Покажите
SHOW CREATE TABLE `db`.`test`;

Совпадают ли типы info_lokal_menu.nid и test.test2?

CREATE TABLE `test` (
`test` tinyint(3) unsigned NOT NULL,
`test2` bigint(20) unsigned NOT NULL,
PRIMARY KEY (`test`),
KEY `test2` (`test2`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci


Скажи миру - НЯ!

Неактивен

 

#12 23.08.2014 15:58:15

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3878

Re: Внешний ключ из составного индекса

Странно, у меня получилось без ошибки. Попробуйте воспроизвести на новой чистой базе.

Неактивен

 

#13 23.08.2014 18:22:22

animegirl
Активист
Зарегистрирован: 28.07.2011
Сообщений: 288

Re: Внешний ключ из составного индекса

rgbeast написал:

Странно, у меня получилось без ошибки. Попробуйте воспроизвести на новой чистой базе.

Вот и я о том же, чистейший воды рандом какой-то.

Ладно, это просто зацепился мозг за не понимание, но проблемы в этом нету.

А вот в чём проблема может возникнуть. Есть три таблицы и их связи по внешним ключам.

CREATE TABLE `t1` (
 `c1` int(11) NOT NULL,
 `c2` int(11) NOT NULL,
 `c3` int(11) NOT NULL,
 KEY `c1` (`c1`),
 KEY `c2` (`c2`),
 KEY `c3` (`c3`),
 CONSTRAINT `t1_ibfk_3` FOREIGN KEY (`c3`) REFERENCES `t3` (`c7`) ON DELETE CASCADE ON UPDATE CASCADE,
 CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`c1`) REFERENCES `t3` (`c7`) ON DELETE CASCADE ON UPDATE CASCADE,
 CONSTRAINT `t1_ibfk_2` FOREIGN KEY (`c2`) REFERENCES `t2` (`c5`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

INSERT INTO `t1` (`c1`, `c2`, `c3`) VALUES
(1, 4, 6);

CREATE TABLE `t2` (
 `c4` int(11) NOT NULL,
 `c5` int(11) NOT NULL,
 `c6` int(11) NOT NULL,
 KEY `c4` (`c4`),
 KEY `c5` (`c5`),
 CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`c4`) REFERENCES `t3` (`c7`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

INSERT INTO `t2` (`c4`, `c5`, `c6`) VALUES
(1, 4, 5);

CREATE TABLE `t3` (
 `c7` int(11) NOT NULL,
 `c8` int(11) NOT NULL,
 `c9` int(11) NOT NULL,
 KEY `c7` (`c7`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

INSERT INTO `t3` (`c7`, `c8`, `c9`) VALUES
(1, 2, 3),
(6, 7, 8);



Вопрос: Если удалить из t3 строку c7=1. То везде всё спокойно удалится, или же может быть сбой?
И да, я пока писала вопрос протестировала, проблем не было, но это была тестовая таблица, а что будет если это будет заполненная таблица с ещё большим количество зависимостей и отслеживанием транзакций?


Скажи миру - НЯ!

Неактивен

 

#14 23.08.2014 18:58:50

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3878

Re: Внешний ключ из составного индекса

Непонятно в чем может быть проблема - удалится последовательно все, что нужно.

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson