如何以一种有效的方式消除mysql列表表中的冗余

如何以一种有效的方式消除mysql列表表中的冗余,mysql,sql,database-design,myisam,Mysql,Sql,Database Design,Myisam,不久前,我做了一个快速,现在已经成为一个更现实的项目。现在我正在重构和改进它。我有一张这样的桌子 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 COLL

不久前,我做了一个快速,现在已经成为一个更现实的项目。现在我正在重构和改进它。我有一张这样的桌子

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,并且
已启用
让我知道此项是否是该类型的最后版本。要点是,当项目类型X被替换为新项目时,旧项目将被禁用(
启用
=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'

如果不使用启用的
并以有效的方式(对于此查询,此查询是),则需要在where子句中显示的两列上建立索引:

create index myidx on records(type, enabled);

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

您可以使用
不存在

select  r.*
from records r
where not exists (select 1
                  from records r2
                  where r2.ref = r.id
                 ) and
       r.type = 2;
然而,在我看来,使用
enabled
可以使代码更清晰。性能需要
记录(ref)
上的索引


如果您假设id总是递增的,那么您也可以使用最大的
id

为什么要使用MyISAM?此查询大约需要两倍的时间,但足够了;)我的发现不存在
我不知道,谢谢!好的,这个想法是摆脱
启用的