选择mysql表的索引

时间:2011-10-12 12:45:23

标签: php mysql

表格

我有一张包含大约1 000 000篇文章价格的表格。文章有一个唯一的ID号,但该表包含多个商店的价格。因此,如果两个商店得到同一篇文章,那么唯一ID就不会是唯一的。

表格结构

表格文章

id INT

价格IN

存储VARCHAR(40)

每日使用

除了用户使用ID号的查询之外,我需要运行每日更新,其中来自csv文件的数据插入/更新表中的每篇文章。选择的过程是尝试选择一篇文章,然后执行插入或更新。

问题

考虑到这一点,我应该选择哪个键?

以下是我一直在考虑的一些解决方案:

  • FULLTEXT字段isbnstore
  • 的索引
  • 添加一个值generated by isbnstore的字段,该字段设置为PRIMARY密钥
  • 每个商店一张桌子,并使用isbn作为PRIMARY密钥

2 个答案:

答案 0 :(得分:0)

使用由商店ID和商品ID组成的复合主键 - 它将为每个商店提供每个商品的唯一主键,并且您不需要单独的字段(假设商店ID和商品ID已经在表格中。

理想情况下,您应该有3个表......类似于:

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


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


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

PRIMARY KEY pricelist是由article_idstore_id组成的复合键。

编辑:(已更新以包含评论中的答案)

即使在一百万行上,UPDATE 应该也可以(对于某个OK的定义,它可能需要一段时间才有100万行),因为{{1} }和article_id组成store_id - 他们被编入索引。

您只需要编写查询,以便它符合以下几行:

PRIMARY KEY

虽然您可能需要考虑将UPDATE pricelist SET price = {$fNewPrice} WHERE article_id = {$iArticleId} AND store_id =` '{$sStoreId}' 表格中的PRIMARY KEYstore - 以及store.id表格中的pricelist.store_id转换为无符号INT 或类似 CHAR(30)

虽然 VARCHAR 在磁盘空间方面更有效但它有一些缺点:

1:MySQL不太热衷于更新VARCHAR值,它可能会使索引膨胀一点,因此您可能需要偶尔在其上运行pricelist(我在 order_header上找到了它之前的表格。)

2:具有非固定长度字段的任何(MyISAM)表(例如 VARCHAR )必须具有 DYNAMIC 行格式,当它格式化效率稍差时来询问它 - 关于这个SO帖子的更多信息:MySQL Row Format: Difference between fixed and dynamic?

答案 1 :(得分:0)

您的索引应与您的查询保持一致。当然,使用STORE和ID在articles表上应该有一个主键 - 但声明它们的顺序将影响性能 - 取决于相关表中的数据和应用的查询。实际上,最简单的解决方案可能是PRIMARY KEY(STORE,ID) UNIQUE KEY(ID,STORE)以及两个字段上的外键约束。

即。因为它使NO SENSE无法调用此表'articles',所以我将使用与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将为您节省很多痛苦。