如何有效地去除mysql表中的列表冗余现象?

问题描述 投票:0回答:2

前段时间我做了一个快速 MVP 现在已经成为一个比较现实的项目。现在我正在对它进行重构和改进。我有一个这样的表格

CREATE TABLE `records` (
  `id` int(11) NOT NULL,
  `type` int(11) NOT NULL,
  .....
  `ref` int(11) DEFAULT NULL,
  `enabled` tinyint(1) NOT NULL DEFAULT '1',
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

ALTER TABLE `mrecord`
  ADD PRIMARY KEY (`id`),
  ADD KEY `type` (`type`);
  ADD KEY `ref` (`ref`);

ref 是指以前的 id 如果没有,则为null enabled 让我知道这个项目是否是该类型的最后一个版本。重点是当一个项目类型X被替换成新的类型时,旧的类型将被禁用 (enabled = 0),新的将设置 ref 旧的 id.

例如,我们有这个表,有3种类型的项目。

 --------------------------------------------
| ID | type | other columns | ref  | enabled |
|--------------------------------------------|
| 1  |   1  |               | null |    1    |
| 2  |   2  |               | null |    1    |
| 3  |   3  |               | null |    1    |
 --------------------------------------------

现在我们添加一个新的项目版本来代替项目类型2:

 --------------------------------------------
| ID | type | other columns | ref  | enabled |
|--------------------------------------------|
| 1  |   1  |               | null |    1    |
| 2  |   2  |               | null |    0    |
| 3  |   3  |               | null |    1    |
| 4  |   2  |               |  2   |    1    |
 --------------------------------------------

如果我们更新了全新的项目,我们有:

 --------------------------------------------
| ID | type | other columns | ref  | enabled |
|--------------------------------------------|
| 1  |   1  |               | null |    1    |
| 2  |   2  |               | null |    0    |
| 3  |   3  |               | null |    1    |
| 4  |   2  |               |  2   |    0    |
| 5  |   2  |               |  4   |    1    |
 --------------------------------------------

我们这里有的是项目类型的列表,只启用了最后的版本。

但是这里 enabled 列是多余的,因为一个启用的项目只是一个没有新版本的项目。

所以我的问题是如何做一个相当于SQL查询。

SELECT * FROM `records` WHERE type='2' AND enabled='1'

而不使用 enabled 并以高效的方式(这个查询是<1ms)。

mysql sql database-design myisam
2个回答
1
投票

你可以使用 not exists:

select  r.*
from records r
where not exists (select 1
                  from records r2
                  where r2.ref = r.id
                 ) and
       r.type = 2;

然而,使用 enabled 在我看来,让代码更清晰。 一个关于 records(ref) 是需要性能的。

如果你假设id总是递增,你也可以使用最大的 id.


0
投票

对于这个查询,你需要在where子句中出现的两列上建立索引。

create index myidx on records(type, enabled);

有了这个索引,数据库就能有效地执行这个查询。你可能还想尝试颠倒列的顺序,看看是否能提高性能。

© www.soinside.com 2019 - 2024. All rights reserved.