Ostatnio postanowiłem napisać sobie system powiadomień w serwsie. Proste powiadomienie to przypisanie rekordu użytkownikowi. Zaawansowane natomiast to takie, które jes
rozsyłane do wszystkich przyjaciół uzytkownika. No wiadomo, nie będę rozsyłał d
wszystkich userów po rekordzie, tylko rozpiszę tabelę trochę inaczej. Oto jej s
ruktura:
(klucz notice_owner napisany testowo)
CREATE TABLE `notice` ( `notice_id` int(11) NOT NULL AUTO_INCREMENT, `notice_type` smallint(2) NOT NULL DEFAULT '0', `notice_owner` int(11) NOT NULL DEFAULT '0', `notice_user` int(11) NOT NULL DEFAULT '0', `notice_item` int(11) NOT NULL DEFAULT '0', `notice_self` smallint(1) NOT NULL DEFAULT '0', PRIMARY KEY (`notice_id`), KEY `notice_normal` (`notice_owner`), KEY `notice_relation` (`notice_user`,`notice_self`), KEY `notice_owner` (`notice_owner`,`notice_user`,`notice_self`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;
Opis pól (ważniejszych):
notice_owner - "posiadacz" powiadomienia
notice_user - id user na temat którego jest powiadomienie
Wykorzystanie.
- Gdy chcemy zaznaczyć powiadomienia usera w trybie prostym, szukamy rekordów po notice_owner
- Gdy chcemy szukać powiadomień na temat przyjaciół, musimy wybrać najpierw listę przyjaciół (subzapytanie) i szukać po notice_user i notice_self zaznaczonym na 1.
PIERWSZE (unia):
EXPLAIN SELECT notice_type, user_name, user_id FROM notice LEFT JOIN users ON ( user_id = notice_user ) WHERE notice_owner =31385 UNION SELECT notice_type, user_name, user_id FROM notice LEFT JOIN users ON ( user_id = notice_user ) WHERE notice_self =1 AND notice_user IN ( SELECT friend_id FROM friends WHERE friend_owner =31385 )
(wykorzystane wszystkie klucze, oprócz notice_owner bo tego zapytania się on nie tyczy. Wyskakuje EXTRA w unii: Impossible WHERE noticed after reading const table...)
DRUGIE (z wykorzystaniem OR):
SELECT notice_type, user_name, user_id FROM notice LEFT JOIN users ON (user_id = notice_user) WHERE notice_owner = 31385 OR (notice_self = 1 AND notice_user IN(SELECT friend_id FROM friends WHERE friend_owner = 31385))
(tutaj nie korzysta się z klucza notice_owner)
Pytania:
a ) które zapytanie jest bardziej optymalne (proszę wziąć pod uwagę brak wykorzystania klcza w OR, jeżeli da się go jakoś zbudować, to jak)
b ) niepokoi mnie komunikat w EXTRA przy pierwszym zapytaniu dla unii: Impossible WHERE noticed after reading const table...
Dziekuję za wypowiedzi.