簡體   English   中英

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

[英]How to get rid of redundancy in a mysql table with lists in an efficient way

前段時間我做了一個快速的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)。

您可以使用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

對於此查詢,您需要在 where 子句中出現的兩列上都有一個索引:

create index myidx on records(type, enabled);

有了索引,數據庫應該能夠有效地執行查詢。 您可能還想嘗試反轉列順序,看看它是否會提高性能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM