簡體   English   中英

用新外鍵替換列值的方法?

[英]Way to replace column values with new foreign key?

我有一個大表(數百萬行),我想用INT替換VARCHAR列中的所有值,這將是指向包含所有VARCHAR值的新表的外鍵。 VARCHAR值是唯一的,如果這很重要的話。

目前,我可以通過以下方式有效地創建外部表:

INSERT INTO `messages` (`message`) SELECT `message` FROM `history`;

但是我第一次替換 VARCHAR 列的基本嘗試非常低效,每行需要幾秒鍾,這顯然不切實際( LIMIT用於測試)。

$messages = $mysqli->query('SELECT `message` FROM `history` LIMIT 0,100;');
while($row = $messages->fetch_array(MYSQLI_ASSOC)) {
    $msg = $row['message'];
    $result2 = $mysqli->query(
        'SELECT `id` FROM `messages` WHERE `message` = "'.$msg.'" LIMIT 0,1'
    );
    $row2 = $result2->fetch_array(MYSQLI_ASSOC);
    $id = $row2['id'];
    $mysqli->query(
        'UPDATE `history` SET `message`="'.$id.'" WHERE `message` = "'.$msg.'"'
    );
    $result2->free_result();
}

感覺我應該能夠完全在 SQL 中完成這個過程,而不是依賴 PHP,這也有望成為一種有效的方式。

您可以使用UPDATE ... JOIN查詢來讓您的 RDBMS 立即完成繁重的工作,而不是使用 PHP 循環:

UPDATE history h
INNER JOIN messages m ON m.message = h.message
SET h.message = m.id

這假設表messages已經被饋送。 為了獲得更好的性能,由於您聲明值在message列中是唯一的,您可能希望在messages(messsage)上創建一個UNIQUE約束。

你必須使用php嗎? 因為你在做:1)一個請求帶來 100 行 2)對於每一行,一個請求帶來另一個表的 id,然后另一個請求更新原始表。 我假設原始表大於 100 行。

你不能直接在數據庫里面做嗎? 如果 varchar 值是唯一的,並且您想要的只是將它們放在一個單獨的表中,您可以像之前一樣填充新表,但還要指定 id,這將很方便地與原始表的 id 完全相同:

INSERT INTO `messages` (`id`, `message`) SELECT `id`, `message` FROM `history`;

然后,創建一個新的 INT 列來保存外鍵:

ALTER TABLE history ADD message_id INT;

然后,填充列:

UPDATE history SET message_id = id;

然后刪除 varchar 列:

ALTER TABLE history DROP message;

您現在可以添加約束以指示 message_id 是外鍵:

ALTER TABLE history ADD CONSTRAINT fk_message_id FOREIGN KEY message_id REFERENCES messages(id);

通過這種方式,您只需進行 2 次迭代:一次用於填充新表,另一次用於設置新列。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM