2011-04-17 131 views
0

當我在用戶表中插入新記錄時,首先檢查電子郵件和暱稱尚未添加。另一個同時註冊相同數據的用戶有可能是我的錯誤結果嗎?澄清:策略查詢執行

連接1:

> SELECT * FROM account WHERE username = 'test'; 

空集(0.00秒)

連接2:

> SELECT * FROM account WHERE username = 'test'; 

空集(0.00秒)

> INSERT INTO account(username) VALUES ('test'); 

查詢行,1行受影響(0.01秒)

連接1:

> INSERT INTO account(username) VALUES ('test'); 

錯誤。重複密鑰

我想知道的是,如果MySQL以這種方式工作,通過在查詢時運行查詢以及使用最佳實踐。 我注意到在轉換過程中,其他連接所做的更改不可見。爲什麼?您可以在轉換之外使用SELECT ... FOR UPDATE?大量使用外鍵來確保數據完整性是一種推薦的做法?

編輯: 換句話說。忽略這個愚蠢的例子。我想誰登記下一個用戶有一個年齡比所有那些已經

> SELECT MAX (age) FROM account; 

[...檢查,如果用戶的年齡較高...]

> INSERT INTO accounts (age) VALUES ('$ var'); 

更大怎樣確保有兩個用戶在同一個野外陣營有風險嗎?

回答

1

這種情況下的最佳做法是創建UNIQUE約束(UNIQUE INDEX)。

當你同時得到2個查詢時,你會得到1個查詢失敗,並能夠處理它與適當的消息給用戶。

+0

他已經有一個唯一索引:「*錯誤重複鍵*」 – 2011-04-17 13:53:47

+0

@ypercube:是的,這是一個最好的做法反正)) – zerkms 2011-04-17 13:58:52

0

列出所有MySQL最佳實踐的Gheez需要一本書。

讓我先回答:

我想誰註冊了一個用戶有一個年齡比那些更大的已經

使用觸發器:

DELIMITER $$ 

CREATE TRIGGER bi_account_each BEFORE INSERT ON account FOR EACH ROW 
BEGIN 
    declare MaxAge integer; 

    SELECT Max(account.age) INTO MaxAge FROM account; 
    IF (new.age <= MaxAge) THEN BEGIN 
    /* force an error by selecting from a table_that_does_not_exist.*/ 
    SELECT * FROM 
     ErrFromTrigger_bi_account_each_New_Member_Must_Be_Older_then_The_Last 
    END; END IF; 

END$$ 

DELIMITER ; 

或存儲的功能

DELIMITER $$ 

CREATE FUNCTION CanInsertInAccount(pAge integer) RETURNS boolean 
BEGIN 
    declare MaxAge integer; 
    declare InsertAllowed boolean; 

    SELECT Max(account.age) INTO MaxAge FROM account; 
    SET InsertAllowed = (pAge > MaxAge); 

    RETURN InsertAllowed; 
END$$ 

DELIMITER ; 

參見:http://dev.mysql.com/doc/refman/5.1/en/triggers.html
有關觸發器的更多信息。
和:http://dev.mysql.com/doc/refman/5.0/en/create-procedure.html
有關存儲過程和函數的更多信息。

至於的最佳實踐,我的名單是:

  1. 不要相信客戶輸入:當插入從PHP值到MySQL總是使用mysql_real_escape_string()值(或使用PDO {prepared statements});這將保護你免受SQL注入攻擊。
  2. 在顯示客戶輸入的數據之前剝離HTML標籤禁止所有HTML。使用htmlspecialchars()將HTML字符轉換爲HTML實體。因此,標記<和>標記標記的開始/結束的字符將變成<和>。僅僅使用strip_tags()僅僅允許一些標籤是不夠的,因爲函數不會去除onclick或onload等有害屬性。
  3. 規範化數據庫
  4. 使用外鍵檢查
  5. 使用事務,但提交(或回滾)經常可以。只在一次交易中放入屬於一起的東西。
  6. 使用觸發器
  7. 使用存儲過程來操作和測試的東西,取決於你的數據庫的佈局。

這就是我現在可以想到的,名單並不完整,這些事情都是有些私人的。它適合我,YMMV。