Как я могу обойти это ограничение внешнего ключа, которое должно иметь уникальное имя?

Я не уверен, почему они должны быть уникальными, но, читая форумы MySQL, кажется, что это так. Однако я думаю, что это больше связано с названием INDEX. У меня есть две таблицы с ограничениями внешнего ключа, ссылающимися на один и тот же первичный ключ в третьей таблице. Если это поможет, я использую MySQL workbench для разработки схемы.

Обычно я называю свой внешний ключ в каждой таблице тем же именем, что и первичный ключ, на который он ссылается. Я думаю, это невозможно. Он создаст первую таблицу с ограничением внешнего ключа, но когда он попытается создать вторую таблицу, он выдаст ошибку. Вот вторая таблица, на которой он выдает ошибку:

CREATE  TABLE IF NOT EXISTS `joe`.`products_to_categories` (
  `product_to_category_id` INT NOT NULL AUTO_INCREMENT ,
  `category_id` INT NOT NULL ,
  `product_id` INT NOT NULL ,
  PRIMARY KEY (`product_to_category_id`) ,
  INDEX `category_id` (`category_id` ASC) ,
  INDEX `product_id` (`product_id` ASC) ,
  CONSTRAINT `category_id`
    FOREIGN KEY (`category_id` )
    REFERENCES `joe`.`categories` (`category_id` )
    ON DELETE CASCADE
    ON UPDATE NO ACTION,
  CONSTRAINT `product_id`
    FOREIGN KEY (`product_id` )
    REFERENCES `joe`.`products` (`product_id` )
    ON DELETE CASCADE
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

Я хочу, чтобы имена внешних ключей были такими же, как первичный ключ в обеих других таблицах. Что я должен удалить здесь, чтобы я мог использовать эти имена. Что является лучшей практикой здесь.


person Community    schedule 11.07.2009    source источник


Ответы (3)


Это невозможно, потому что у вас будет конфликт в имени файла для файла, который используется для индекса IIRC. Я, вероятно, назвал бы ключ ‹ имя_таблицы >_‹ имя_столбца > или что-то в этом роде.

person txwikinger    schedule 11.07.2009
comment
точно не помню!! Я столкнулся с этой проблемой, для нее требуется уникальное имя ограничения, даже если ограничение принадлежит другой схеме/БД на той же машине/установке. - person Ratnesh Maurya; 12.07.2009
comment
Конечно, вы можете придумывать уникальные имена; однако это более подвержено ошибкам, чем просто позволить MySQL найти уникальное имя. См. этот URL-адрес: dev.mysql.com/ doc/refman/5.1/en/ Если задано предложение символа CONSTRAINT, значение символа должно быть уникальным в базе данных. Если предложение не задано, InnoDB автоматически создает имя. - person Wil Moore III; 07.10.2010

Вы создаете индекс (ограничение) по имени product_id через: INDEX product_id

Затем вы создаете другое ограничение (для внешнего ключа) с тем же именем: CONSTRAINT product_id

Что вам нужно сделать, так это разрешить серверу предоставлять уникальное имя ограничения по умолчанию, удалив CONSTRAINT product_id

См. этот URL-адрес: http://dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html

«Если указано предложение символа CONSTRAINT, значение символа должно быть уникальным в базе данных. Если предложение не задано, InnoDB создает имя автоматически».

person Wil Moore III    schedule 07.10.2010

В PostgreSQL по умолчанию для именования индексов добавляются «_pkey» и «_fkey» к имени первичного и внешнего ключа соответственно. Таким образом, ваш случай будет выглядеть так:

INDEX `product_id_fkey` (`product_id` ASC) ,

ОБНОВЛЕНИЕ: я только что попробовал это, и это сработало. Посмотри, не это ли ты имел в виду.

    use test;

create table if not exists test.product
(
    product_id int not null auto_increment,
    name varchar(80) not null,
    primary key(product_id)
);

create table if not exists test.category
(
    category_id int not null auto_increment,
    name varchar(80) not null,
    primary key(category_id)
);

create table if not exists test.product_category
(
    product_id int,
    category_id int,
    primary key(product_id, category_id),
    constraint product_id_fkey
        foreign key(product_id) references product(product_id)
        on delete cascade
        on update no action,
    constraint category_id_fkey
        foreign key(category_id) references category(category_id)
        on delete cascade
        on update no action
);

insert into test.product(name) values('teddy bear');
insert into test.category(name) values('toy');
insert into test.product_category 
    select p.product_id, c.category_id from product as p, category as c
    where p.name = 'teddy bear' and c.name = 'toy';
person duffymo    schedule 11.07.2009
comment
Так действительно ли индекс для product_id вызывает конфликт, а фактическое имя внешнего ключа в порядке? - person ; 12.07.2009
comment
Попробуйте и посмотрите, был бы мой совет. - person duffymo; 12.07.2009
comment
AFAIK это не имеет значения в mysql - person Ratnesh Maurya; 12.07.2009
comment
Он создаст первую таблицу с ограничением внешнего ключа, но когда он попытается создать вторую таблицу, он выдаст ошибку - тогда о чем это? - person duffymo; 12.07.2009