2011-10-12 77 views
2

選擇了MySQL表

索引我有一個包含價格約1 000 000篇的表。這些文章獲得了唯一的ID號碼,但該表包含來自多個商店的價格。因此,如果兩個商店獲得同一篇文章,則唯一ID不會唯一表格。

表結構

表文章

ID INT

價格

店VARCHAR(40)

日常使用

除用戶使用ID號的查詢外,我需要運行每日更新,其中csv-files的數據插入/更新表中的每篇文章。選擇的過程是嘗試選擇一篇文章,然後執行插入或更新。

問題

考慮到這一點,我應該選擇哪個鍵?

這裏是我一直在考慮一些解決辦法:

  • FULLTEXT領域isbn指數和store
  • 添加一個字段的值generated byisbn和被設置爲PRIMARY關鍵
  • 一個store每個商店和使用isbn作爲PRIMARY密鑰
+0

你可以發表你的表的結構嗎? –

+2

聽起來像你需要重組你的表。您應該每個項目只有一行。如果它有多個價格,這些將反映在一個單獨的表格中,這可能是物品和商店之間的多對多。 – John

+0

@DaveRix我編輯了我的Q. – Joseph

回答

0

使用由商店ID和商品ID組成的複合主鍵 - 它將爲每個商店提供每個商品的唯一主鍵,並且您不需要單獨的字段(假設商店標識和商品標識已在表格中)。

理想情況下,你應該有3個表...類似:

article 
-------------------------------------------- 
id | isbn | ... etc ... 


store 
-------------------------------------------- 
id | description | ... etc ... 


pricelist 
-------------------------------------------- 
article_id | store_id | price | ... etc ... 

隨着PRIMARY KEYpricelist量由article_idstore_id複合鍵。

編輯:(更新,其中包含從註釋的答案)

即使在一百萬行的UPDATE應該是確定(OK的有一定的定義,它可能仍然需要一段時間與因爲article_idstore_id包括PRIMARY KEY-它們將兩者被索引。

你只需要編寫你的查詢,以便它沿着線是:

UPDATE pricelist SET price = {$fNewPrice} 
WHERE article_id = {$iArticleId} 
AND store_id =` '{$sStoreId}' 

雖然你可能要考慮在store表(store.id轉換PRIMARY KEY - 因此在還pricelist.store_idpricelist表)到無符號INT或類似CHAR(30)

雖然VARCHAR是更有效的,當談到磁盤空間,它有兩個缺點:

1:MySQL是不是太熱衷於更新VARCHAR值,它可以使索引臃腫了一點,所以您可能需要偶爾運行OPTIMIZE TABLE(我在order_header表之前發現此問題)。

2:與非固定長度字段(如VARCHAR)任何(MyISAM的)表將必須有一個DYNAMIC行格式這是稍微低效率的,當涉及到查詢它 - 有關於更多信息在此SO帖子上:MySQL Row Format: Difference between fixed and dynamic?

+0

因爲我需要在例如+ 1M的帖子上運行更新。價位表。那麼我應該檢查article_id和store_id的組合鍵嗎?這會造成任何性能問題嗎?我的測試是,使用PRIMARY鍵可以很好地搜索,但要求非鍵搜索非常困難。 – Joseph

+0

應該可以,因爲'article_id'和'store_id'都將被索引(因爲它們組成主鍵) - 您只需編寫查詢,以便它符合'UPDATE pricelist SET price = {$ fNewPrice} WHERE article_id = {$ iArticleId} AND store_id ='{$ sStoreId}' - 我會更新答案,因爲有幾個provisos :) – CD001

0

您的索引應與您的查詢一致。當然,使用STORE和ID在文章表上應該有一個主鍵 - 但是它們的聲明順序會影響性能 - 這取決於相關表中的數據和應用的查詢。事實上,最簡單的解決方案可能是PRIMARY KEY(STORE,ID) UNIQUE KEY(ID,STORE)以及兩個字段上的外鍵約束。

即因爲它沒有任何意義調用此表「文章」,我將使用相同的模式CD001:

CREATE TABLE pricelist (
    id INT NOT NULL , 
    price INT, 
    store VARCHAR(40) NOT NULL 
    PRIMARY KEY(store,id), 
    UNIQUE KEY rlookup (id, store) 
    CONSTRAINT id FOREIGN KEY articles.id, 
    CONSRAINT store FOREIGN KEY store.name 
); 
這還需要有使用的名稱在商店主鍵

檢查基於單列和基於2列的密鑰之間的差異可以忽略不計 - 並且規範化數據庫properyl將爲您節省大量的痛苦。