2016-02-22 19 views
5

Tôi có hai bảng giống hệt nhau được đặt trong hai cơ sở dữ liệu giống hệt nhau (có tên khác). Tôi muốn kết hợp hai bảng này, nhưng khóa chính của họ được sử dụng trong các bảng khác,Cập nhật MYSQL tất cả các giá trị khóa ngoài

các bảng giống như thế này:

Bảng A

id  column1  column2 column3 
___ ________ _______ ________ 
1  text  text  text 
2  text  text  text 
3  text  text  text 

Bảng B

id  column1  column2 column3 
___ ________ _______ ________ 
2  text  text  text 
3  text  text  text 
4  text  text  text 

các bảng được liên kết với Bảng A

liên kết Một

id  column1  tableA_ID 
___ ________ _______ 
1  text  2  
2  text  3  
3  text  4 

liên kết B

id  column1  tableA_ID 
___ ________ _______ 
1  text  3  
2  text  3  
3  text  2  

Xin lưu ý, các bảng có giống hệt id 's, điều này có nghĩa là khi tôi làm việc hợp nhất, tôi phải thay đổi id của bảng thứ hai. Hãy nhớ rằng các khóa chính của bảng thứ hai là được sử dụng trong các bảng khác.

tôi đã viết truy vấn này để hợp nhất hai bảng:

INSERT INTO db_A.`Table_A`(`column2`,`column3`) 
    SELECT `column2`,`column3` FROM db_B.`Table_B`; 

truy vấn này sẽ sao chép một cách chính xác các hồ sơ của bảng thứ hai để bảng đầu tiên.

Bây giờ tôi cũng muốn di chuyển dữ liệu của các bảng được liên kết với Table B, tôi có thể sử dụng cùng một truy vấn, nhưng bây giờ khóa ngoại sẽ không khớp, vì ID chúng đã được liên kết với đã bị thay đổi.

Làm cách nào để cập nhật chúng để ID sẽ khớp lại?

NB: Tôi không có ON UPDATE CASCADE hạn chế trên những bảng

Tôi hy vọng điều này làm cho ý nghĩa, tôi sẽ cố gắng để cải thiện vấn đề này để mọi người hiểu được nó.

Cơ sở dữ liệu Thông tin

Type : MySQL 
Engine: MyISAM 
+2

Cập nhật ID thành phạm vi duy nhất, hợp nhất. –

+0

Bạn muốn cập nhật tất cả ID của 'Table_B' và tham chiếu của nó trước khi hợp nhất? mmm .... làm thế nào đến tôi đã không bao giờ nghĩ về điều đó, ý tưởng tốt đẹp –

+1

Bạn nên chuyển sang InnoDB. Cho đến lúc đó, không có câu trả lời 'FOREIGN KEY' nào được áp dụng. –

Trả lời

1

Một cách đơn giản sẽ được cập nhật 's TableBID s phạm vi độc đáo và sau đó làm việc hợp nhất. Nếu các khóa ngoại của bạn được đặt đúng để thay đổi, cơ sở dữ liệu của bạn sẽ duy trì tính nhất quán thông qua thao tác này.

Bạn không cần thực hiện bất kỳ thay đổi nào đối với giản đồ cơ sở dữ liệu theo cách này, vì vậy không có điểm nào trong thời gian khi dữ liệu không phải là dữ liệu. Bạn cũng có thể chắc chắn rằng các ID sẽ không xung đột. Cách dễ nhất để tìm các giá trị duy nhất là lấy tối đa ID trong TableA và thêm giá trị đó vào ID s trong TableB.

+0

_ "Tôi không có ràng buộc ON UPDATE CASCADE trên các bảng" _ –

+0

@LuthandoLoot Xin lỗi, bỏ lỡ điều đó. Tôi khuyên bạn nên thay đổi điều đó để đảm bảo cập nhật mọi thứ đúng cách. –

3

đề nghị của tôi là:

  1. bạn thả các ràng buộc khoá ngoại của Linka trong database1
  2. tăng chìa khóa đối ngoại của TableA : idLinka: tableA_ID (cách tốt nhất là với một tham gia) bởi phép nói 1000 (hoặc bao nhiêu hàng bạn có trong database2)
  3. thêm khó khăn một lần nữa (không bắt buộc)
  4. nhập khẩu TableAsau đóLinkA to cơ sở dữ liệu2 từ cơ sở dữ liệu1.

Nếu bạn cần trợ giúp thêm, chỉ cần hỏi.

Trân trọng

====================================

Cập nhật. Ví dụ cho các cập nhật của id:

UPDATE 
    Table_A, Link_A 
SET 
    Table_A.id = Table_A.id + 1000, 
    Link_A.id = Link_A.tableA_ID + 1000, 
FROM 
    Table_A JOIN Link_A 
ON 
    Table_A.id = Link_A.tableA_ID 
+2

Truy vấn của bạn có hợp lệ không? Tôi có nghĩa là tôi thấy 'Update' và' From' trong một truy vấn –

+0

Xin chào Luthando, tôi không có MySQL để kiểm tra một cách rõ ràng truy vấn. Nhưng một truy vấn tương đương đã làm việc cho tôi với MS SQLServer. Và xem [ở đây, ví dụ ở dưới cùng] [1] [1]: http://www.techonthenet.com/sql_server/update.php –

+0

Tốt hơn là không nên sử dụng các kết nối vì chúng tôi có thể bỏ lỡ một số các bản ghi (các bản ghi rỗng ở phía bên phải hoặc bên trái) đặc biệt khi có hai hoặc nhiều quan hệ với cùng một bảng ngoại. –

2

Nếu cả hai db là giống hệt nhau, tôi tin rằng bạn nên đặt tên cho nó db_B.Table_A không db_B.Table_B để tránh confusion..but cho bây giờ tôi đi cùng với nó

--get delta id, use biggest id from db_A and db_B 
--to avoid failure because of updating to existing primary key 

SELECT @dbBMax := MAX(id) FROM db_B.`Table_B`; 
SELECT @dbAMin := MIN(id), @dbAMax := MAX(id) FROM db_A.`Table_A`; 
SET @DeltaID := IF(@dbBMax > @dbAMax, @dbBMax, @dbAMax) - @dbAMin + 1; 

--drop constraint 
ALTER TABLE db_A.`Link_A` DROP FOREIGN KEY `constraint_name_A`; 
ALTER TABLE db_A.`Link_B` DROP FOREIGN KEY `constraint_name_B`; 

--update ids 
UPDATE db_A.`Table_A` SET id = id + @DeltaID; 
UPDATE db_A.`Link_A` SET tableA_ID = tableA_ID + @DeltaID; 
UPDATE db_A.`Link_B` SET tableA_ID = Link_A.tableA_ID + @DeltaID; 

--merge tables 
--assume id is auto-increment, don't use auto-increment value, 
--so id manually inserted 
INSERT INTO db_A.`Table_A`(`id`, `column1`, `column2`,`column3`) 
SELECT `id`, `column1`, `column2`,`column3` FROM db_B.`Table_B`; 

--assume id is auto-increment, use it, don't insert manually  
INSERT INTO db_A.`Link_A`(`column1`, `tableA_ID`) 
SELECT `column1`, `tableA_ID` FROM db_B.`Link_A`; 

--assume id is auto-increment, use it, don't insert manually  
INSERT INTO db_A.`Link_B`(`column1`, `tableA_ID`) 
SELECT `column1`, `tableA_ID` FROM db_B.`Link_B`; 

Mã này có thể thêm lớn bước nhảy vọt trên id tại db_B.Table_B nếu db_A.Table_A có nhiều dữ liệu hơn mà db_B.Table_B .. có thể được sửa dễ dàng trước/sau khi hợp nhất bảng .. nhưng tôi nghĩ tùy chọn của nó ..

1

Bạn có thể áp dụng ON UPDATE CASCADE để mỗi bảng với các phím nước ngoài liên quan đến TableB.id trong cơ sở dữ liệu thứ hai tạm thời:

ALTER TABLE db2.other_tables_with_fk DROP FOREIGN KEY fk_to_TableB; 

ALTER TABLE db2.other_tables_with_fk 
    ADD CONSTRAINT fk_to_TableB FOREIGN KEY (TableB_id) 
    REFERENCES TableB(id) ON UPDATE CASCADE; 

và sau đó sử dụng các trick trong Sami's Answer và sau đó loại bỏ những thay đổi tạm thời như thế này:

ALTER TABLE db2.other_tables_with_fk DROP FOREIGN KEY fk_to_TableB; 

ALTER TABLE db2.other_tables_with_fk 
    ADD CONSTRAINT fk_to_TableB FOREIGN KEY (TableB_id) 
    REFERENCES TableB(id); 

Sau đó, cơ sở dữ liệu thứ hai của bạn sẽ sẵn sàng hợp nhất với cơ sở dữ liệu đầu tiên.


Đối MyISM hoặc tình huống mà CASCADE không được hỗ trợ bởi động cơ bạn có thể mô phỏng nó bằng tay bằng cách định nghĩa Triggers:

CREATE TRIGGER trigger1 
    AFTER UPDATE 
    ON TableB 
    FOR EACH ROW 
BEGIN 
    UPDATE other_tables_with_fk1 SET TableB_id = NEW.id WHERE TableB_id = OLD.id 
    UPDATE other_tables_with_fk2 SET TableB_id = NEW.id WHERE TableB_id = OLD.id 
    ... 
END 

Thậm chí nếu trigger không có sẵn bạn chỉ có thể tăng id số hàng trong cơ sở dữ liệu thứ hai bằng một số lượng tùy chỉnh (bất kỳ số tiền nào lớn hơn id hàng tối đa được sử dụng trong cơ sở dữ liệu đầu tiên) trong tất cả các bảng bao gồm cả bảng chính của khóa ngoài cùng một lúc:

UPDATE TableB t SET t.id = (t.id + 10000); 
UPDATE related_table_1 t SET t.TableB_id = (t.TableB_id + 10000); 
UPDATE related_table_2 t SET t.TableB_id = (t.TableB_id + 10000); 
... 

Và sau đó bạn có thể hợp nhất các cơ sở dữ liệu đó.

Các vấn đề liên quan