SQLinfo.ru - Все о MySQL

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

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

Вы не зашли.

#1 20.05.2008 17:32:16

Nata
Участник
Зарегистрирован: 10.05.2008
Сообщений: 7

Внешний ключ

Как при создании таблицы описать внешний ключ и первичный ключ,если он состоит из 2-х столбов?
Написала так:references имя_табл(имя_столбца) (это на счет Foreigh key). Не помогло

Неактивен

 

#2 20.05.2008 17:46:20

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5246

Re: Внешний ключ


CREATE TABLE product (category INT NOT NULL, id INT NOT NULL,
                      price DECIMAL,
                      PRIMARY KEY(category, id)) ENGINE=INNODB;

CREATE TABLE product_order (no INT NOT NULL AUTO_INCREMENT,
                            product_category INT NOT NULL,
                            product_id INT NOT NULL,
                            customer_id INT NOT NULL,
                            PRIMARY KEY(no),
                            INDEX (product_category, product_id),
                            FOREIGN KEY (product_category, product_id)
                              REFERENCES product(category, id)
                              ON UPDATE CASCADE ON DELETE RESTRICT) ENGINE=INNODB;

 

Неактивен

 

#3 20.05.2008 18:24:09

Nata
Участник
Зарегистрирован: 10.05.2008
Сообщений: 7

Re: Внешний ключ

А если в одной таблице 2-а столбца, оба являются внешними ключами на разные таблицы,тогда...
и ещё  для чего после таблицы такая запись:ENGINE=INNODB?Почему-то MySQL ругается на эту запись.
smile

Неактивен

 

#4 21.05.2008 00:34:46

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 819

Re: Внешний ключ

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.
Если ругается - проверьте еще раз, что все правильно написали.

Неактивен

 

#5 22.05.2008 07:22:47

Nata
Участник
Зарегистрирован: 10.05.2008
Сообщений: 7

Re: Внешний ключ

Пожалуйста, объясните в чем моя ошибка:
есть бд 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)
Что я делаю не так?и что это за ошибка?

Неактивен

 

#6 22.05.2008 07:25:46

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 819

Re: Внешний ключ

Так бывает, когда в дочерней таблице есть записи, которых нет в родительской (в т.ч. NULL'ы).

Попробуйте создать ключи на пустых таблицах, потом заполнить родительские и затем заполнить дочернюю.

А. Ну и еще родительские таблицы тоже InnoDB должны быть.

Неактивен

 

#7 06.06.2008 16:16:19

E-Stranger
Участник
Зарегистрирован: 06.06.2008
Сообщений: 5

Re: Внешний ключ

Не стал открывать новую тему, у меня тоже вопрос по внешнему ключу.
Задача стоит такая. Есть 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)

Неактивен

 

#8 06.06.2008 16:45:34

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

Re: Внешний ключ

На VIEW к сожалению нельзя ссылаться внешним ключом. Такую функциональность, как Вы описываете напрямую реализовать нельзя, а разбивать основную таблицу на несколько будет не очень удобно. Создав триггер BEFORE UPDATE и BEFORE INSERT на ссылающейся таблице Вы не сможете запретить некорректную вставку (можно только имитировать поведение SET NULL)

Неактивен

 

#9 16.06.2008 10:08:44

E-Stranger
Участник
Зарегистрирован: 06.06.2008
Сообщений: 5

Re: Внешний ключ

rgbeast, а как же тогда быть? Неужели такой редко встречающийся случай? Имхо, это же довольно распространенная ситуация: есть справочник с перечнем, и при заполнении другой таблицы в определенном столбце можно выбирать только из вышереализованного перечня. Правда, в моем случае не один в один, перечень включает несколько групп, а нужен только из одной. Неужели этот нюанс так сильно затрудняет дело?
А может, создавать временные таблицы вместо представлений? Они автоматически создаются при входе в БД или их нужно заново создавать вручную при каждом входе в БД?

Неактивен

 

#10 16.06.2008 10:29:51

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

Re: Внешний ключ

То, что Вы говорите решилось бы, если бы на VIEW можно было бы вешать внешний ключ, но в MySQL на данный момент такого функционала нет.

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

Неактивен

 

#11 17.06.2008 19:37:08

E-Stranger
Участник
Зарегистрирован: 06.06.2008
Сообщений: 5

Re: Внешний ключ

Создал таблицу на основе запроса:

Код:

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. Но там свои заморочки...

Неактивен

 

#12 17.06.2008 19:46:30

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6624

Re: Внешний ключ

Есть замечательная утилита - perror, она возвращает текстом то, что написано в коде ошибки.
$ perror 150
MySQL error code 150: Foreign key constraint is incorrectly formed

Для того, чтобы работали связи InnoDB, нужно, чтобы на таблицах были соответствующие
индексы. В данном случае, очевидно, не хватает
ALTER TABLE WorkTypes ADD INDEX (Element);

Неактивен

 

#13 18.06.2008 01:02:39

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 819

Re: Внешний ключ

Да, действительно, нужен ключ на соотв. столбце родительской таблицы.
(на дочерней, кстати, должна сама создавать, если не указан)

Неактивен

 

#14 18.06.2008 22:55:17

E-Stranger
Участник
Зарегистрирован: 06.06.2008
Сообщений: 5

Re: Внешний ключ

LazY
Спасибо! Дело действительно было в индексе. Я их никогда не изучал особо (тем паче, что в курсе БД окромя первичных ключей ничего подобного не дают), считая за дополнительные цифровые столбцы, дублирующие первичный ключ. А это. оказывается, не дополнительные столбцы smile
Таким образом, связка между дочерней и промежуточной (для дочерней - родительской) таблицей реализуется. А между промежуточной и родительской, видимо, аналогичную связку делать в виде триггера? Три штуки и после изменения родительской таблицы?
Кстати, как правильно написать текст триггера? Просто внести аналогичное изменение в промежуточную таблицу? Или полностью написать код, создающий таблицу, прописывающий в нее индексы и добавляющий внешние ключи в дочернюю?

З.Ы. Не хочу заводить доп. тему, потому что больше уже не успею до защиты диплома задавать вопросы по другой теме. Как (если вообще можно) перенести БД с одной машины на другую? Простым копированием не переносится.

З.Ы. 2. Перрор не впечатлил. Про ошибку 1452 вообще ничего не смог сказать. Имхо, ничего нового к сообщениям утилиты mysql не дает.

Неактивен

 

#15 19.06.2008 15:02:18

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6624

Re: Внешний ключ

Ну, я тут, конечно, сбоку, но отвечу на ЗЫ wink

ЗЫРАЗ) MyISAM таблички проще всего копировать mysqlhotcopy, InnoDB - mysqldump + mysql.
ЗЫДВА) А Вы ничего и не писали про 1452 wink

Неактивен

 

#16 19.06.2008 16:19:31

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 819

Re: Внешний ключ

Триггер - не очень сложная вещь. Посмотрите документацию (там немного):
http://dev.mysql.com/doc/refman/5.0/en/ … igger.html
и у нас тут темы тоже были. Например, вот это сообщение:
http://sqlinfo.ru/forum/viewtopic.php?pid=4132#p4132

Неактивен

 

#17 20.06.2008 17:03:26

E-Stranger
Участник
Зарегистрирован: 06.06.2008
Сообщений: 5

Re: Внешний ключ

paulus, LazY, благодарю!
1452 вылезла позже, там ситуация была несколько другая. Пришлось по-другому разрулить, изменив структуру БД.

Неактивен

 

Board footer

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