Задавайте вопросы, мы ответим
Вы не зашли.
Как при создании таблицы описать внешний ключ и первичный ключ,если он состоит из 2-х столбов?
Написала так:references имя_табл(имя_столбца) (это на счет Foreigh key). Не помогло
Неактивен
Неактивен
А если в одной таблице 2-а столбца, оба являются внешними ключами на разные таблицы,тогда...
и ещё для чего после таблицы такая запись:ENGINE=INNODB?Почему-то MySQL ругается на эту запись.
Неактивен
FOREIGN KEY (имя_столбца) REFERENCES имя_родительской_таблицы(имя_родительского_столбца)
Про foreign key также полезно почитать http://webew.ru/posts/219.webew
для чего после таблицы такая запись:ENGINE=INNODB?Почему-то MySQL ругается на эту запись.
Это механизм хранения данных. MySQL поддерживает несколько механизмов хранения (см. http://dev.mysql.com/doc/refman/5.1/en/ … gines.html), но внешние ключи пока может только InnoDB.
Если ругается - проверьте еще раз, что все правильно написали.
Неактивен
Пожалуйста, объясните в чем моя ошибка:
есть бд Poliklinika,таблицы:med_personal, в которой есть столбец id_mp-номер медперсонала; bolnye, где есть столбец id_bol-номер больного. Создаю такую табличку с 2-мя внешними ключами:
Create table bolnye_mp(
id_med_p int(4) not null,
id_boln int(4) not null,
primary key (id_med_p,id_boln),
CONSTRAINT FOREIGN KEY(id_med_p) REFERENCES med_personal (id_mp) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT FOREIGN KEY (id_boln) REFERENCES bolnye (id_bol) ON DELETE CASCADE ON UPDATE CASCADE
) TYPE=InnoDB;
но почему-то ошибка:error 1005:Can’t create table ‘.\poliklinika\bolnye_mp.frm’ (errno:150)
Что я делаю не так?и что это за ошибка?
Неактивен
Так бывает, когда в дочерней таблице есть записи, которых нет в родительской (в т.ч. NULL'ы).
Попробуйте создать ключи на пустых таблицах, потом заполнить родительские и затем заполнить дочернюю.
А. Ну и еще родительские таблицы тоже InnoDB должны быть.
Неактивен
Не стал открывать новую тему, у меня тоже вопрос по внешнему ключу.
Задача стоит такая. Есть 2 таблицы:
Works(God, Qwartal, TypeOfWork, Summa)
и
Sprav(Element, Grup, Describe).
Домен поля TypeOfWork в первой таблице - это
SELECT Element FROM Sprav WHERE Grup = 'Work'
Напрашивается внешний ключ в первой таблице. Но, насколько я понимаю, не бывает таких столбцов, в которых были бы не значения, а запросы.
Поэтому сделал промежуточное представление WorkTypes с единственным столбцом TypeOfWork, образуемым вышеприведенным запросом. Представление создалось, в нем перечень неповторяющихся значений видов работ.
Но образование внешнего ключа с помощью конструкции вида
ALTER TABLE Works ADD FOREIGN KEY (TypeOfWork) REFERENCES WorkTypes(TypeOfWork) ON DELETE RESTRICT ON UPDATE RESTRICT;
выдало ошибку
ERROR 1005 (HY000): Can't create table '.\diplom\#sql-4f8_1.frm' (errno: 150)
В чем я ошибаюсь? И как правильно реализовать необходимую связку между двумя таблицами?
Отредактированно E-Stranger (06.06.2008 16:18:55)
Неактивен
На VIEW к сожалению нельзя ссылаться внешним ключом. Такую функциональность, как Вы описываете напрямую реализовать нельзя, а разбивать основную таблицу на несколько будет не очень удобно. Создав триггер BEFORE UPDATE и BEFORE INSERT на ссылающейся таблице Вы не сможете запретить некорректную вставку (можно только имитировать поведение SET NULL)
Неактивен
rgbeast, а как же тогда быть? Неужели такой редко встречающийся случай? Имхо, это же довольно распространенная ситуация: есть справочник с перечнем, и при заполнении другой таблицы в определенном столбце можно выбирать только из вышереализованного перечня. Правда, в моем случае не один в один, перечень включает несколько групп, а нужен только из одной. Неужели этот нюанс так сильно затрудняет дело?
А может, создавать временные таблицы вместо представлений? Они автоматически создаются при входе в БД или их нужно заново создавать вручную при каждом входе в БД?
Неактивен
То, что Вы говорите решилось бы, если бы на VIEW можно было бы вешать внешний ключ, но в MySQL на данный момент такого функционала нет.
Создайте не временные, а постоянные таблицы. Временные - живут в течение одной сессии пользователя (для каждого подключения отдельный набор). Не забывайте регенерировать все вторичные таблицы при изменении основной.
Неактивен
Создал таблицу на основе запроса:
CREATE TABLE IF NOT EXISTS WorkTypes SELECT Element FROM Sprav WHERE Grup = 'Work';
Все нормально:
Query OK, 7 rows affected (0.00 sec)
Records: 7 Duplicates: 0 Warnings: 0
Имеем таблицу из одного столбца с неповторяющимися видами работ.
Далее попробовал создать внешний ключ:
ALTER TABLE Works ADD FOREIGN KEY (TypeOfWork) REFERENCES WorkTypes(Element) ON DELETE RESTRICT ON UPDATE RESTRICT;
Вот ответ:
ERROR 1005 (HY000): Can't create table '.\diplom\#sql-50c_12.frm' (errno: 150)
Что опять не так?
Уже дропнул таблицу Work (она не пустая, думал, может, из-за этого СУБД не дает создать внешний ключ). Но и попытка повторного создания таблицы с указанием внешнего ключа дает ошибку.
Я уже близок к тому, чтобы реализовать связи между таблицами не в БД, а в логике приложения, создавая вспомогательные таблицы в DataSet. Но там свои заморочки...
Неактивен
Есть замечательная утилита - perror, она возвращает текстом то, что написано в коде ошибки.
$ perror 150
MySQL error code 150: Foreign key constraint is incorrectly formed
Для того, чтобы работали связи InnoDB, нужно, чтобы на таблицах были соответствующие
индексы. В данном случае, очевидно, не хватает
ALTER TABLE WorkTypes ADD INDEX (Element);
Неактивен
Да, действительно, нужен ключ на соотв. столбце родительской таблицы.
(на дочерней, кстати, должна сама создавать, если не указан)
Неактивен
LazY
Спасибо! Дело действительно было в индексе. Я их никогда не изучал особо (тем паче, что в курсе БД окромя первичных ключей ничего подобного не дают), считая за дополнительные цифровые столбцы, дублирующие первичный ключ. А это. оказывается, не дополнительные столбцы
Таким образом, связка между дочерней и промежуточной (для дочерней - родительской) таблицей реализуется. А между промежуточной и родительской, видимо, аналогичную связку делать в виде триггера? Три штуки и после изменения родительской таблицы?
Кстати, как правильно написать текст триггера? Просто внести аналогичное изменение в промежуточную таблицу? Или полностью написать код, создающий таблицу, прописывающий в нее индексы и добавляющий внешние ключи в дочернюю?
З.Ы. Не хочу заводить доп. тему, потому что больше уже не успею до защиты диплома задавать вопросы по другой теме. Как (если вообще можно) перенести БД с одной машины на другую? Простым копированием не переносится.
З.Ы. 2. Перрор не впечатлил. Про ошибку 1452 вообще ничего не смог сказать. Имхо, ничего нового к сообщениям утилиты mysql не дает.
Неактивен
Ну, я тут, конечно, сбоку, но отвечу на ЗЫ
ЗЫРАЗ) MyISAM таблички проще всего копировать mysqlhotcopy, InnoDB - mysqldump + mysql.
ЗЫДВА) А Вы ничего и не писали про 1452
Неактивен
Триггер - не очень сложная вещь. Посмотрите документацию (там немного):
http://dev.mysql.com/doc/refman/5.0/en/ … igger.html
и у нас тут темы тоже были. Например, вот это сообщение:
http://sqlinfo.ru/forum/viewtopic.php?pid=4132#p4132
Неактивен
paulus, LazY, благодарю!
1452 вылезла позже, там ситуация была несколько другая. Пришлось по-другому разрулить, изменив структуру БД.
Неактивен