sql—如何以有效的方式消除mysql表中的冗余

o7jaxewo  于 2021-08-13  发布在  Java
关注(0)|答案(2)|浏览(422)

前一段时间我做了一个快速mvp,现在已经成为一个更现实的项目。现在我正在重构和改进它。我有一张这样的table

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` 如果没有,则为空 `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)。
lstz6jyr

lstz6jyr1#

你可以用 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 .

uplii1fm

uplii1fm2#

对于此查询,您需要在where子句中出现的两列上都有一个索引:

create index myidx on records(type, enabled);

有了索引,数据库应该能够高效地执行查询。您还可以尝试反转列顺序,看看它是否提高了性能。

相关问题