Как эффективно избавиться от избыточности в таблице mysql со списками - PullRequest
0 голосов
/ 30 мая 2020

Некоторое время go я сделал быстрый MVP , который теперь стал более реалистичным c проектом. Сейчас занимаюсь рефакторингом и улучшаю. У меня есть такая таблица

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 и в эффективном путь (этот запрос <1 мс). </p>

Ответы [ 2 ]

1 голос
/ 30 мая 2020

Вы можете использовать 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.

0 голосов
/ 30 мая 2020

Для этого запроса вам нужен индекс для обоих столбцов, которые появляются в предложении where:

create index myidx on records(type, enabled);

С помощью индекса база данных должна иметь возможность эффективно выполнять запрос. Вы также можете попробовать инвертировать порядок столбцов и посмотреть, повысит ли это производительность.

...