2013-05-14 12 views
9

Tôi có một bảng với cấu trúc dưới đây:Mysql xóa chế

CREATE TABLE `Lm_help` (
`id` int(10) NOT NULL AUTO_INCREMENT, 
`section` int(10) NOT NULL, 
`language` int(10) NOT NULL, 
`title` varchar(255) NOT NULL, 
`text` text NOT NULL, 
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
PRIMARY KEY (`id`), 
UNIQUE KEY `unique_help` (`section`,`language`), 
KEY `language_constraint` (`language`), 
CONSTRAINT `language_constraint` FOREIGN KEY (`language`) REFERENCES `Lm_languages` (`id`), 
CONSTRAINT `section_constraint` FOREIGN KEY (`section`) REFERENCES `Lm_help_sections` (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 

tôi cần phải loại bỏ "unique_help" chìa khóa, nhưng tôi nhận được lỗi ràng buộc khoá ngoại.

Do lỗi này, tôi không thể xóa bất kỳ thứ gì trong số này, section_constraint, language_constraint, unique_help.

Dưới đây là bảng khác đề cập đến điều này:

CREATE TABLE `Lm_languages` (
`id` int(11) NOT NULL AUTO_INCREMENT, 
`name` varchar(255) NOT NULL, 
`code` varchar(255) NOT NULL, 
`status` int(11) DEFAULT NULL, 
`created_at` datetime NOT NULL, 
`updated_at` datetime NOT NULL, 
PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1 




CREATE TABLE `Lm_help_sections` (
`id` int(11) NOT NULL AUTO_INCREMENT, 
`name` varchar(255) NOT NULL, 
PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 
+0

lỗi gì là bạn nhận được chính xác? –

+0

unique_help không phải là khóa chính, là một chỉ mục duy nhất. lỗi gì bạn nhận được? –

+0

Không thể thả chỉ mục 'language_constraint': cần thiết trong ràng buộc khóa ngoài – viv

Trả lời

19

Vấn đề là chỉ số unique_help (section, language) được sử dụng bởi section_constraint ràng buộc khoá ngoại. Vì vậy, bạn không thể thả chỉ mục mà không làm giảm ràng buộc đầu tiên.


Một cách để giải quyết vấn đề này, trước tiên hãy rút ràng buộc khóa ngoài ra, sau đó thả chỉ mục.

Sau đó, bạn có thể thêm chỉ mục (đơn giản) trên (section) và tạo lại khóa ngoại.

Tất cả những có thể được thực hiện trong một tuyên bố:

ALTER TABLE Lm_help 
    DROP FOREIGN KEY section_constraint, -- drop the FK so 
    DROP INDEX unique_help,    -- the index can be dropped 
              -- and then 
    ADD INDEX section_IX (section),  -- add a new index 
    ADD CONSTRAINT section_FK    -- so the FK can be recreated 
     FOREIGN KEY (section) 
     REFERENCES Lm_help_sections (id) 
    ; 

Tested tại SQL-Fiddle


Cải thiện

tôi đã sai, không cần phải thả và tái tạo hạn chế. Chỉ số có thể được giảm, miễn một chỉ số mới được tạo ra:

ALTER TABLE Lm_help 
    DROP INDEX unique_help, 
    ADD INDEX section_IX (section) 
    ; 

Tested tại SQL-Fiddle-2

+0

Cảm ơn , mà làm việc, tôi đã sử dụng chỉ số thả section_constraint, điều này đã không làm việc nhưng thả phím nước ngoài section_constraint làm việc ....... Bạn có thể giải thích cho tôi tại sao ??? – viv

+0

Đó là cú pháp (trong MySQL) để thả các ràng buộc khóa ngoài. –

2

As your error message suggests:

(...) trong [bảng tham chiếu bởi một chìa khóa nước ngoài], có phải là chỉ mục trong đó các cột được tham chiếu được liệt kê là các cột đầu tiên trong số cùng một thứ tự.

Bạn phải tìm (các) bảng tham chiếu và thả (các) ràng buộc khoá ngoại từ (các) bảng khác này.

Tệ, tôi đọc qua định nghĩa bảng của bạn quá nhanh. Vấn đề thực tế là the other way around:

MySQL đòi hỏi chỉ số trên phím nước ngoài và các phím tham chiếu để kiểm tra chính nước ngoài có thể được nhanh chóng và không đòi hỏi một bảng quét.

Trước tiên, hãy rút section_constraint ràng buộc khóa ngoài hoặc tạo chỉ mục mới trên language trước khi giảm hạn chế UNIQUE.

+0

Bạn có thể xem cấu trúc của các bảng khác, mà tôi đã sử dụng – viv

+0

Tệ của tôi, xin vui lòng xem anwer mới của tôi. – RandomSeed

+0

KHÔNG có vấn đề gì ok, giải quyết vấn đề, cảm ơn tất cả ... – viv

6
ALTER TABLE Orders 
DROP FOREIGN KEY 'language_constraint'; 

ALTER TABLE Orders 
DROP FOREIGN KEY 'section_constraint'; 

PERFORM DELETE QUERY ĐÂY

ALTER TABLE Orders 
ADD CONSTRAINT `language_constraint` 
FOREIGN KEY (`language`) 
REFERENCES `Lm_languages` (`id`); 

ALTER TABLE Orders 
ADD CONSTRAINT `section_constraint` 
FOREIGN KEY (`section`) 
REFERENCES `Lm_help_sections` (`id`); 
+1

Cảm ơn tushar đã làm việc, nhưng tôi không thể chấp nhận hai câu trả lời ... :) – viv

+0

Không sao cả, tôi vui vì mã của tôi đã giúp bạn :) –

1

Đây là một thủ tục lưu trữ mà bạn có thể gọi điện để thả một chìa khóa nước ngoài trước khi gọi các tạo sql . Tôi đã sửa đổi câu trả lời cho một câu hỏi tương tự về thả THỦ TỤC Nếu tồn tại được trả lời bởi: https://stackoverflow.com/users/166161/thomas-paine

gọi mẫu:

CALL DropForeignKey (DATABASE(), 'tablename', 'keyname'); 

Thủ tục:

DELIMITER ; 

/* DROP_FOREIGN_KEY */ 
DROP PROCEDURE IF EXISTS DropForeignKey; 

DELIMITER // 

CREATE PROCEDURE DropForeignKey(
IN param_schema VARCHAR(100), 
IN param_table_name VARCHAR(100), 
IN param_constraint_name VARCHAR(100) 
) 

BEGIN 
    IF EXISTS(
    SELECT NULL FROM information_schema.TABLE_CONSTRAINTS 
    WHERE CONSTRAINT_NAME=param_constraint_name AND TABLE_NAME=param_table_name AND TABLE_SCHEMA = param_schema 
    ) 
    THEN 
     set @paramTable = param_table_name ; 

    set @ParamConstraintName = param_constraint_name ; 
    set @ParamSchema = param_schema; 
    /* Create the full statement to execute */ 
    set @StatementToExecute = concat('ALTER TABLE `',@ParamSchema,'`.`',@paramTable,'` DROP FOREIGN KEY `',@ParamConstraintName,'` '); 
    /* Prepare and execute the statement that was built */ 
    prepare DynamicStatement from @StatementToExecute ; 
    execute DynamicStatement ; 
    /* Cleanup the prepared statement */ 
    deallocate prepare DynamicStatement ; 

END IF; 
END // 

DELIMITER ;