Php 为mysql表选择索引

Php 为mysql表选择索引,php,mysql,Php,Mysql,表格 我有一张表,里面有大约100万件商品的价格。这些商品有一个唯一的ID号,但表中包含多家商店的价格。因此,如果两个商店获得相同的商品,那么uniques ID对于表来说将不是唯一的 表格结构 桌上物品 id INT 价格 存储VARCHAR(40) 日常使用 除了用户使用ID号进行查询外,我需要运行每日更新,其中来自csv文件的数据插入/更新表中的每篇文章。choosen过程是尝试选择一篇文章,然后执行插入或更新 问题 考虑到这一点,我应该选择哪个键 以下是我一直在考虑的一些解决方案: 全

表格

我有一张表,里面有大约100万件商品的价格。这些商品有一个唯一的ID号,但表中包含多家商店的价格。因此,如果两个商店获得相同的商品,那么uniques ID对于表来说将不是唯一的

表格结构

桌上物品

id INT

价格

存储VARCHAR(40)

日常使用

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

问题

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

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

  • 全文
    字段索引
    isbn
    存储
  • 添加一个字段,该字段的值由
    isbn
    和存储生成,并设置为
  • 每个存储一个表,并使用isbn作为主键

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

理想情况下,你应该有3张桌子。。。比如:

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


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


pricelist
--------------------------------------------
article_id | store_id | price | ... etc ...
pricelist
主键是由
article\u id
store\u id
组成的复合键

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

即使在一百万行上,
更新
也应该是正常的(对于OK的某个定义,在超过一百万行的情况下可能还需要一段时间),因为
文章id
存储id
构成了
主键
——它们都将被索引

您只需编写查询,使其符合以下要求:

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

>您可能想考虑在<代码>存储> <代码>表(<代码>存储> ID >代码> -因此也<代码> > PICELLIST .StureSid ID >代码> > <强>无符号int >强>或类似<强> char(30)< /强>

虽然VARCHAR在磁盘空间方面效率更高,但它有几个缺点:

1:MySQL不太喜欢更新VARCHAR值,它会使索引膨胀,因此您可能需要偶尔在其上运行
optimizetable
(我以前在order\u头表上发现过)


2:具有非固定长度字段(例如VARCHAR)的任何(MyISAM)表必须有一个动态的行格式,这在查询它时效率稍低-这篇文章中有更多关于这方面的信息:

使用一个由商店ID和商品ID组成的复合主键-这将在每个商店的基础上为每个项目提供唯一的主键,而您不需要使用单独的字段(假设存储id和项目id已经在表中)

理想情况下,你应该有3张桌子。。。比如:

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


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


pricelist
--------------------------------------------
article_id | store_id | price | ... etc ...
pricelist
主键是由
article\u id
store\u id
组成的复合键

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

即使在一百万行上,
更新
也应该是正常的(对于OK的某个定义,在超过一百万行的情况下可能还需要一段时间),因为
文章id
存储id
构成了
主键
——它们都将被索引

您只需编写查询,使其符合以下要求:

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

>您可能想考虑在<代码>存储> <代码>表(<代码>存储> ID >代码> -因此也<代码> > PICELLIST .StureSid ID >代码> > <强>无符号int >强>或类似<强> char(30)< /强>

虽然VARCHAR在磁盘空间方面效率更高,但它有几个缺点:

1:MySQL不太喜欢更新VARCHAR值,它会使索引膨胀,因此您可能需要偶尔在其上运行
optimizetable
(我以前在order\u头表上发现过)


2:任何具有非固定长度字段(如VARCHAR)的(MyISAM)表都必须具有动态的行格式,这在查询时效率稍低-这篇文章中有更多关于这方面的信息:

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

i、 e.由于将此表称为“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
);
这还需要在使用name的存储上有一个主键


基于单列检查键和基于两列检查键之间的差异可以忽略不计,而正确规范化数据库将为您省去很多麻烦。

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