Задавайте вопросы, мы ответим
Вы не зашли.
Привет всем!
Ребята, объясните, пожалуйста, как связать две таблицы MyISAM в MySQL.
Интересуют взаимосвязи: один к одному, многие ко многим, а также таблица, имеющая взаимосвязь с др. таблицей один к одному и еще с одной таблицей многие ко многим.
Читал статью "Enforcing Foreign Keys Programmatically in MySQL" (http://dev.mysql.com/doc/refman/5.0/en/ … -keys.html) и книгу Р. Яргер, Дж. Риз, Т. Кинг "MySQL и MSQL. Базы данных для небольших предприятий и интернета", но все равно никак не могу разобраться.
Неактивен
vasya написал:
Что вы подразумеваете под связью таблиц? Если внешние ключи, то они работают только для innodb, подробнее см FAQ п 4.
vasya, спасибо за ответ.
Да, именно внешние ключи я и имел в виду. Я в курсе, что таблицы MyISAM не поддерживают внешних ключей. В статье "Enforcing Foreign Keys Programmatically in MySQL", ссылку на которую я указал в своем первом посте, описывается как программно воссоздать внешние ключи для движков, которые их не поддерживают нативно.
Мне же, после прочтения статьи, осталось непонятно следующее:
1.
wikipedia написал:
Внешним ключом называется поле таблицы, предназначенным для хранения значения первичного ключа другой таблицы с целью организации связи между этими таблицами.
Если MyISAM не поддерживает внешних ключей, то как организовать связь между таблицами? Очень был бы признателен за фрагменты MySQL запросов для создания таблиц.
2.
wikipedia написал:
Развитые СУБД поддерживают автоматический контроль ссылочной целостности на внешних ключах.
Так как СУБД MyISAM не поддерживают автоматический контроль ссылочной целостности на внешних ключах, то вся ответственность за это ложится на плечи программиста? Какие именно случаи необходимо контролировать?
dev.mysql.com написал:
Creating triggers for the MyISAM child tables which will ensure a corresponding parent_id value exists in the parent table when we insert a value into the child table.
dev.mysql.com написал:
A cascading delete specifies that if an attempt is made to delete a row with a key referenced by foreign keys in existing rows in other tables, all rows that contain those foreign keys are also deleted.
dev.mysql.com написал:
A cascading update specifies that if an attempt is made to update a key value in a row, where the key value is referenced by foreign keys in existing rows in other tables, all the values that make up the foreign key are also updated to the new value specified for the key.
PS: InnoDB не поддерживает мой хостер, переходить на другой хостинг сейчас нет времени, хочу разобраться.
Отредактированно FiMko (05.01.2010 13:18:44)
Неактивен
Ну, если Ваш хостер поддерживает триггеры, то можете описать нужную
функциональность триггерами. Т.е. отдельный триггер на вставку, который
будет проверять, есть ли значение в родительской таблице, отдельный
триггер на удаление из родительской таблицы, который будет каскадно
удалять и т.п.
Возможно, более логичным, однако, окажется написание клиентского кода
так, чтобы он ходил в соответствующие таблицы и делал всё сам.
Неактивен
paulus написал:
Ну, если Ваш хостер поддерживает триггеры, то можете описать нужную функциональность триггерами. Т.е. отдельный триггер на вставку, который будет проверять, есть ли значение в родительской таблице, отдельный триггер на удаление из родительской таблицы, который будет каскадно удалять и т.п.
Возможно, более логичным, однако, окажется написание клиентского кода так, чтобы он ходил в соответствующие таблицы и делал всё сам.
paulus, спасибо!
Однако, у меня-то еще и проблемы с обычным пониманием того как спроектировать связанные таблицы при условии, что СУБД - MyISAM. Проще говоря, вы, как специалист по mysql, какой бы запрос MySQL отправили если вы вам понадобилось спроектировать структуру базы, где:
1. существует взаимосвязь двух таблиц: один ко многим
2. существует взаимосвязь двух таблиц: многие ко многим
3. таблица, имеет взаимосвязь с др. таблицей "один ко многим" и еще с одной таблицей "многие ко многим".
Объясните, пожалуйста, на примере. Спасибо!
Отредактированно FiMko (05.01.2010 15:41:16)
Неактивен
Случай 2 эквивалентен двум связям типа 1 (таблица А с таблицей связей и таблица
связей с таблицей Б). Случай 3 эквивалентен случаю 2 + случаю 1 (проверять
нужно по всем связанным напрямую таблицам).
Т.о. нужно рассматривать только случай 1. В нем можно определить родительскую
и дочернюю таблицы.
Тогда для дочерней таблицы триггеры должны на вставку и обновление
проверять, что в родителе есть соответствующая запись.
Для родительской таблицы триггеры должны на обновление и удаление
или обновлять дочерние таблицы («CASCADE», «SET NULL») или проверять
наличие строк в дочерних таблицах и запрещать («RESTRICT»).
P.S. Текст триггеров все-таки прийдется написать самостоятельно
Неактивен
отдельный триггер на вставку, который
будет проверять, есть ли значение в родительской таблице, отдельный
триггер на удаление из родительской таблицы, который будет каскадно
удалять и т.п.
Да, деваться некуда, но ты представь, как это будет долго..
И еще. С помощью триггеров никак нельзя запретить вставку в дочернюю таблицу строк, соотв. значений ключа для которых нет в родительской.
Вообще я думаю, что не стоит изобретать велосипед, а просто нужно поменять хостера (потому как очень странно и подозрительно выглядит отсутствие поддержки InnoDB, который есть сразу в комплекте).
Неактивен
Да, без InnoDB фигово, буду думать в этом направлении...
http://www.peterhost.ru/ - На тарифах виртуального хостинга нет поддержки InnoDB в MySQL.
Спасибо за помощь!
Отредактированно FiMko (07.01.2010 19:22:23)
Неактивен
Странный какой-то хостинг..
Вот есть тоже питерский http://docker.ru/plans - там вроде бы InnoDB есть
Неактивен
LazY написал:
И еще. С помощью триггеров никак нельзя запретить вставку в дочернюю таблицу строк, соотв. значений
ключа для которых нет в родительской.
А почему нет? Повесить триггер на дочернюю таблицу?
Неактивен
И как он будет предотвращать вставку?
Неактивен
paulus написал:
Повесить триггер на дочернюю таблицу?
И как он будет предотвращать вставку?
Кстати. Мне тут пришло в голову, что ведь триггер каждый раз должен будет сканировать по ключу родительскую таблицу. Я так понимаю, внешний ключ делает примерно то же самое, т.е. значительных потерь производительности при этом не будет?
Неактивен
Предотвращать вставку, например, так:
IF NOT (условие проверки)
SET NEW.key = -1,
где -1 — существующее значение.
Неактивен