2011-10-12 52 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将为您节省大量的痛苦。