【问题标题】:How to get rid of redundancy in a mysql table with lists in an efficient way如何以有效的方式消除带有列表的mysql表中的冗余
【发布时间】:2020-09-17 23:08:28
【问题描述】:

前段时间我做了一个快速的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 并且以一种有效的方式(这个查询是

【问题讨论】:

  • 你为什么使用 MyISAM?

标签: mysql sql database-design myisam


【解决方案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

【讨论】:

  • 这个查询大约需要两倍的时间,但已经足够了;)我发现这里是not exists我不知道,谢谢!
【解决方案2】:

对于这个查询,你需要一个出现在 where 子句中的两列的索引:

create index myidx on records(type, enabled);

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

【讨论】:

  • 嗯,这个想法是摆脱enabled
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-29
  • 1970-01-01
相关资源
最近更新 更多