2013-12-08 81 views
1

我與列的表:(ID, UserID, Slot, ItemID, Quant)

可以說我有值的行:('1', '10', '2', '35', '200');

此行有一個槽值2.我在庫存標籤中有20個插槽。我想以數字升序插入數據。有沒有一種方法可以在查詢最後一個槽的時候編寫一個查詢,以便將它分配給下一個槽?因此,如果時隙2,已經使用的下一個項目,然後將消耗插槽3

或者有一種方法來比較多個變量的數值,而不必具有等於該數字兩個變量所以像

if($var1 or $var2 or $var3 == 1) { 
excute this code 
} 

而不是做以下幾點:

if($var1 ==1) { 
    execute code 
} 
if($var2 == 1) { 
    execute code 
} 
if($var3 == 1) { 
    execute code 
} 
+0

['in_array()'](http://nl3.php.net/in_array)可能帶有嚴格的標誌或簡單的'||'。 – PeeHaa

+0

沒有更多的信息可能是錯誤的,但這聽起來像一個解決方案的不好的方法。你對插槽/庫存做什麼?你可能會更好,只是使用一個新的行或許有一個額外的列,或改變方法,並以某種方式使用自動增量,但需要更多的信息來建議 – James

+0

基本上我有x數量的產品將被顯示在一個阻止格式每個​​被分配給一個插槽。所以即時嘗試確定哪個插槽使用下一個基於下一個數字可用 – user3078244

回答

1

我討厭成爲壞消息的承載者,但是恕我直言,你的數據模型是根本上被打破的。有兩種可能的情況:

  • 如果且僅當永遠需要,如果插槽是一個封閉的實體訪問單槽,即你應該存儲序列化槽結構。

  • 如果您需要任何訪問單個插槽,我希望通過表slots和另一個表通過連接表使用它解決這樣的問題。使用插槽就可以簡單地通過反覆INSERT ING被acomplished,直到不再有鍵衝突發生(ofcourse有更有效的方法)

編輯

在迴應@斯多葛派的要求,這裏是在第二子彈更闡述:假定以下:

  • 在OQ的表稱爲useritems
  • 有所謂users另一個表,其中UserID來自(PK)
  • 承擔,另外還有一個表叫items,其中ItemID來自(PK)

現在我們創建一個表userslots

CREATE TABLE userslots (
    UserID int, -- possibly some FK, 
    SlotNum int, 
    ItemId int, -- possibly some FK, 
    ItemCount int, 
    -- possibly more, as the game logic needs (Styling, etc.) 
    PRIMARY KEY(UserID, SlotNUm), 
) 

並且我們爲每個用戶的每個插槽創建一個行,SlotNum = 0..N和ItemID = ItemCount = 0 - 這使我們有可能讓不同的用戶擁有不同數量的插槽。

現在,如果我們要插入一個項目,我們走了兩步:

  • 也許用戶已經有這樣的項目,我們只是需要增加計數? UPDATE userslots SET ItemCount=ItemCount+1 WHERE UserID=$UserID and ItemID=$ItemID LIMIT 1。如果這返回1受影響的行,我們就完成了。
  • 如果不是,我們需要使用一個新插槽:UPDATE userslots SET ItemID=$ItemID, ItemCount=1 WHERE UserID=$UserID and ItemCount=0 LIMIT 1

  • 如果我們需要刪除一個項目,我們只需UPDATE userslots SET ItemCount=ItemCount-1 WHERE UserID=$UserID and ItemID=$ItemID and ItemCount>0 LIMIT 1,受影響的行數(0或1)原子顯示給我們,如果用戶有這樣的項目:沒有與另一個會話競爭,可能導致以雙倍消費。

+0

好主意我會構建一個新表和他們之間的過程謝謝。 – user3078244

-1

至少有一個辦法做到這一點在SQL是:

SELECT max(slot) FROM table_name; 

然後,您可以從結果集中提取出來,然後插入到下一個插槽中。

和If問題:

if($var1 == 1 || $var2 == 1 || $var3 == 1) { 
    do_something(); 
} 
+0

這會中斷,如果兩個會話遇到競爭條件,所以你至少需要事務和一個重試邏輯 –

-1

您可以使用SQL的max功能檢查最後最大值爲一列,像這樣:

SELECT max(slot) FROM table_name; 

然後,對於條件,你可以使用以下任一項:

$matrix = array($var1, $var2, $var3); 
if (in_array(1, $matrix) { 
    execute_code(); 
} 

或者,

if ($var1 == 1 || $var2 == 1 || $var3 == 1) { 
    execute_code(); 
} 

我個人更喜歡in_array方法,因爲它更通用且易於實現。

+0

如果兩個會話進入競爭狀態,這將中斷,所以你至少需要事務和一個重試邏輯 –

+0

@ EugenRieck:你確定?我想,我們可以使用'mysqli :: store_result'方法,它總是會返回我們所做的最後一個查詢的結果。沒有線程安全?我只向他提供了所需的SQL查詢,而不是PHP代碼,這樣OP就可以使用他進一步需要的任何邏輯。 – Stoic

+0

競爭是在SQL中:SELECT max(slot)FROM table_name;'的結果可能不再有效,在它處理的時間點(如果另一個會話插入一個新項目) –