鍍金池/ 問(wèn)答/數(shù)據(jù)庫(kù)/ sql 消息表狀態(tài)關(guān)聯(lián) 如何優(yōu)化?

sql 消息表狀態(tài)關(guān)聯(lián) 如何優(yōu)化?

表結(jié)構(gòu)如下圖:
clipboard.png

我現(xiàn)在實(shí)現(xiàn)的未讀消息為:

SELECT
    `n`.`id`
FROM
    `message` AS `m`
WHERE
    `m`.`id` NOT IN (
        SELECT
            `m_s`.`message_id`
        FROM
            `message_status` AS `m_s`
        WHERE
            `m`.`id` = `n_s`.`message_id`
    );

這種實(shí)現(xiàn)語(yǔ)句,子查詢(xún)可以使用到所有,但是主查詢(xún)無(wú)法使用索引,請(qǐng)問(wèn)在 MySQL 下有什么好的優(yōu)化方法嗎?

注意消息跟用戶(hù)是一對(duì)多關(guān)聯(lián),及一條消息,多個(gè)用戶(hù)對(duì)應(yīng)關(guān)系。

回答
編輯回答
淚染裳

你這樣關(guān)聯(lián)字段來(lái)判斷是否已讀消息不科學(xué)啊,后期數(shù)據(jù)量大起來(lái)的話很難受的

一般都是消息表有個(gè)狀態(tài)字段來(lái)區(qū)分它們,比如:

—————————————————————————————————————————
| Id | 編號(hào) |
—————————————————————————————————————————
| State | 消息狀態(tài):1 未讀 2 已讀 |
—————————————————————————————————————————

關(guān)聯(lián)還是 messageId 與 消息表 Id 關(guān)聯(lián)

但查詢(xún)未讀消息的話就這樣

SELECT * FROM [message] WHERE State=1

豈不美哉?。?!

2017年11月13日 01:08
編輯回答
晚風(fēng)眠
select m.id
from message m left join (select distinct message_id from message_status) s on m.id = s.message_id 
where s.message_id is null

這個(gè)問(wèn)題最好還是從設(shè)計(jì)角度解決,消息閱讀后在message表上面打標(biāo)記。

另外,如果用子查詢(xún),用not exists效率可能會(huì)更好一些。

2017年7月24日 10:46