2015-04-23 24 views
1

意外的雙刀片我有一個like表同類產品在我的網站的客戶。於MyISAM

的問題是,我用這個表:誰喜歡

CREATE TABLE IF NOT EXISTS `likes` (
    `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, 
    `user` varchar(40) NOT NULL, 
    `post` int(11) UNSIGNED NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ; 

用戶,職位是產品ID。

像按鈕發送Ajax請求的PHP:

session_start(); 
$user = $_SESSION["user"]; 
$pinsid=$_POST['id']; 

$stmt = $mysqli_link->prepare("SELECT * FROM likes WHERE post=? AND user=?"); 
$stmt->bind_param('is', $pinsid, $user); 
$stmt->execute(); 
$result = $stmt->get_result(); 
$stmt->close(); 
$chknum = $result->num_rows; 

if($chknum==0){ 
    $stmt = $mysqli_link->prepare("INSERT INTO likes (user, post) VALUES (?,?)"); 
    $stmt->bind_param('si', $user, $pinsid); 
    $stmt->execute(); 
    $stmt->close(); 
    $response = 'success'; 
} 

echo json_encode($response); 

我的問題是,我有相同的人如雙刀片。例如:

1 josh 5 
2 josh 5 

但如果MySQL引擎被設置爲InnoDB的,如果我將其更改爲MyISAM的我只有1插入時纔會發生。

發生了什麼事?我該怎麼做才能使它正常工作?這樣做的

+0

我覺得很難相信需要在post索引 - 你確定你的用戶和帖子的ID值是一致的,沒有多餘的空格等? –

+0

在'(user,post)'上設置唯一索引! – yergo

+0

我認爲主要問題是ajax,即發送多個請求!但在php/sql中解決它會很好。我怎樣才能爲用戶和帖子設置唯一的索引? –

回答

1

但如果MySQL引擎被設置爲InnoDB的,如果我將其更改爲MyISAM數據時纔會發生,我只有1插入是有問題的。 發生了什麼?我該怎麼做才能使它正常工作?

MyISAM引擎使用表級鎖定,這意味着如果某個操作正在某個表上執行,則所有其他操作將等待執行,直到該操作完成。

的InnoDB是事務性的,並使用行級鎖,因爲你不使用的交易沒有被鎖定。

正如在評論中提到和答案最簡單的解決方案是創建用戶和後一個唯一約束,在您選擇的情況下,你可以同時使用作爲主鍵,因爲自動增量列沒有附加值。

要創建一個唯一約束:

ALTER TABLE likes ADD UNIQUE KEY uk_user_post (user,post); 

至於你的問題:

但它可以插入我慢下來?

如果我們只是談論表中的插入操作,是的,它確實減慢了,因爲在插入,更新或刪除操作之後,每個索引都必須重建。它減慢的速度取決於索引的大小和表中的行數。

但是,在您當前的表結構中,userpost上沒有任何索引,並且在您的應用程序中,您在兩個柱面上執行select查找,這將導致全表掃描。

使用唯一索引(user,post),您可以跳過選擇,因爲當唯一約束違反時,您將收到SQL錯誤。

另外userpost是外鍵,所以應該無論如何索引。

唯一索引(user,post)覆蓋user FK,那麼你也將separatly

+0

謝謝你的回答!但它會減慢我的插入? –

+0

我已經擴展了我的答案:-) – Gervs

1

的一種方法是建立用戶和崗位的喜歡錶的唯一鍵(見https://dev.mysql.com/doc/refman/5.0/en/constraint-primary-key.html)。

如果已經到位,該數據庫將確保沒有用戶和後重復。然而,對於已經在表中的數據,它可能如果已經有複製

+1

在Colomn或多列上設置唯一約束時,MyIsam重複項會自動移除。 – Gervs

+0

@Gervs感謝您的信息。我不知道,我主要與InnoDB工作 – gabe3886

+0

Yw,我也主要與InnoDb合作,如果你必須設置一個獨特的約束om InnoDb表包含重複項,只需將de引擎更改爲MyISAM,設置唯一的常量並更改引擎回到InnoDb – Gervs