Autor Zpráva
joe
Profil
Ahoj,

snažím se udělat možnost posílání zpráv mezi uživateli tak, aby měli složky zpráv: přijaté, odeslané a koš, ale nějak se mi to moc nedaří nebo nevím jestli na to jdu tím správným způsobem.

Udělal jsem si dvě tabulky

zpravy
id | predmet | zprava | cas

info
zpravaID | odesilatelID | prijemceID | novaZprava | casPrecteni | smazanaOdesilatelem | smazanaPrijemcem | slozkaOdesilatel | slozkaPrijemce

Viděl jsem i způsoby, které používaly jednu tabulku a zprávu tam vložily dvakrát, jen seprohodil přijemce s odesílatelem, takové řešení se mi nezdá moc šťastné.

Můj problém je ten, že když by někdo obdržel zprávu, tu smaže (-> nastaví se u dané zprávy smazanaPrijemcem=1). Pak ten samý zprávu odešle (zprávu má v odeslaných) a tu odeslanou zprávu smaže (-> nastaví se u dané zprávy smazanaOdesilatelem=1). V tomto okamžiku jsou obě v koši.

Jak ale později ty dvě zprávy rozlišit, třeba když bych v koši vybral všechny a kliknul na tlačítko obnovit, aby se vrátili do původních složek - přijatá / odeslaná.

---

Pro takový případ mám dotaz pro vypsání koše
select z.*, i.* from zpravy z, info i where i.zpravaID = z.id and ( (4 = i.odesilatelID and i.smazanaOdesilatelem = 1) OR (4 = i.prijemceID and i.smazanaPrijemcem = 1) )

Ale stejně se mi to nějak nezdá...
---

Pořád nevim jestli na to jdu tim správnym směrem nebo ne. Kdyby mi někdo poradil (Kajman_, Joker a jim podobní:-)) tak budu vděčný, díky!
Mastodont
Profil
Podle mne je zbytečné vytvářet dvojici odesilatelID x prijemceID a zároveň slozkaOdesilatel x slozkaPrijemce.

Zařazení zprávy do koše bych řešil pouze příznakem stavu, čili při obnově se opět jen změní stav a není třeba měnit žádné složky.
joe
Profil
Mastodont
Sloupce, které jsem tady pojmenoval slozka Odesilatel a slozkaPrijemce se nemění, měnil by se jen ten stav - smazanaPrijemcem/Odesilatelem.

Podle mne je zbytečné vytvářet dvojici odesilatelID x prijemceID a zároveň slozkaOdesilatel x slozkaPrijemce.
A jak jinak? :-) Bez těchto dvou mě napadá jediné řešení a to, které by na poslání zprávy použilo 3x insert

1 - do tabulky, která by mohla být id | predmet | zprava
2 - do tabulky zpravy_prirazeni uzivatelID | zpravaID | odesilatelID | novaZprava | casPrecteni | slozka
3 - do tabulky zpravy_prirazeni uzivatelID | zpravaID | odesilatelID | novaZprava | casPrecteni | slozka

(kde ve 2. a 3. insertu pak prohodim sloupce uzivatelID a odesilatelID). Takhle to bylo myšleno? To by taky snad nemuselo být tak špatné a pracovalo by se s tím daleko líp než s tím prvním co jsem napsal.
joe
Profil
Pravděpodobně už jsem na to přišel a jen pomocí jednoho vložení... Přemýšlel jsem nad tím poměrně dost dlouho, ale téma prosím nezamykejte, možná to ještě nebude to pravé, díky.

(Občas pomůže na to chvíli nemyslet a nápady přijdou sami/y?)
Str4wberry
Profil
Já to řešil takhle:

zprávy
id | autorid | příjemceid | datum | text | typ
Přičemž koš je pouze pro doručené. Ve sloupci „typ“ je rozlišená příchozí zpráva na: přečtené, nepřečtené a přesunuté do koše.

Kdybych chtěl přesouvat do koše i odeslané, vytvořil bych zřejmě sloupce „typautor“ a „typpříjemce“. Tím Ti odpadne starost s obnovováním. Snad jsem to popsal správně…
joe
Profil
Str4wberry
Popsal správně :), díky. Chápu, takhle nějak jsem to měl, když jsem to začínal dělat, pak jsem si rozmyslel, že by tam bylo dobré udělat pár věcí jinak...

Tím Ti odpadne starost s obnovováním.
Teď nevím, jestli jsme si rozuměli, obnovením zpráv jsem myslel, že když je odeslaná, přesune ji do koše a z koše ji může zase obnovit zpět do odeslaných... To by šlo asi jen v případě, že by tam byly sloupce všechny tři - typ, typautor a typprijemce.

Pokud ale to je takhle, tak odstraňovat zprávy by se muselo s podmínkou, kde by ve where bylo i OR, něco jako

... where autorid = 4 or prijemceid = 4 (kde 4 je id přihlášeného uživatele). Pokud by byly v koši jen doručené zprávy, tak by to šlo... Zkusím to co jsem vymyslel a třeba to půjde.
Str4wberry
Profil
Odeslané a přijaté zprávy poznáš podle „autorid“ a „příjemceid“. Tedy odeslané: „SELECT * FROM zprávy WHERE autorid = « id uživatele » AND type = 'normální'“; pro přijaté „SELECT * FROM zprávy WHERE příjemceid = « id uživatele » AND type = 'normální'“; pro koš „SELECT * FROM zprávy WHERE příjemceid = « id uživatele »“ AND type = 'koš'.

Při obnovení z koše se změní typ. Je to hodně zjednodušené, ale princip by měl být jasný.
Mastodont
Profil
Ve sloupci "typ zprávy" můžeš rozlišovat na: neodesláno (koncept), nepřečteno (ale odesláno), přečteno, smazáno odesilatelem, smazáno příjemcem, smazáno oběma.
joe
Profil
Str4wberry
Přijaté a odeslané jsou jasné... s košem je problém a ani tohle to neřeší, protože v koši může být zpráva jak přijatá, tak odeslaná a z toho plyne, že nemůžeš použít dotaz pro vybrání zpráv z koše:

SELECT * FROM zprávy WHERE příjemceid = « id uživatele »“ AND type = 'koš'.

ale musíš přidat další podmínku

SELECT * FROM zprávy WHERE (příjemceid = « id uživatele »“ AND type = 'koš') OR (autorid = « id uživatele »“ AND type = 'koš').

a to není moc dobrý pro index.


Tak ani moje vymyšlené řešení nejde, asi nezbývá nic jiného než tam tu zprávu prostě vložit 2x a prohodit příjemce a odesílatele... Tedy tak nějak jak jsem to napsal v prvním příspěvku, tam jsem jen dal samotnou celou zprávu zvlášť do tabulky, abych ji neopakoval, ale to je možná zbytečné...
joe
Profil
Mastodont
Rozlišovat můžu, ale myslim že to mi nepomůže... U zprávy totiž potřebuju znát pořád příjemce a odesílatele a to, v jakých to mají oni složkách.
Mastodont
Profil
joe
V prvním příspěvku píšeš, že budeš mít jen tyto složky: přijaté, odeslané a koš. V tom případě příslušnost do složek řeší jednoznačně ten stav, ID příjemce a odesílatele!
joe
Profil
Mastodont
Ano, to je pravda s těmi složkami, omlouvám se! Ale, pokud budou u obou uživatelů v koši, bude nastaven tedy stav "smazáno oběma", pak by dotaz pro výpis zpráv v koši vypadal asi takhle:

select * from zpravy where (prijemceId = « id uživatele » AND stav in ("smazano prijemcem", "smazano obema") OR (odesilatelId = « id uživatele » AND stav in ("smazano odesilatelem", "smazano obema"))

kde stringy v dotazu jsou jen pro názornost, buď by to byl tinyint nebo enum, případně set a tady je zase problém s indexem, protože zprávy se budou vkládat hodně.

Možná se pletu, potom jsem to moc nepochopil, ale už se s tím trápím dost dlouho. A pokud bych chtěl třeba někdy později rozšířit o možnost vytvoření složek, tak asi jiný způsob neexistuje než vložení zprávy 2x.

Díky za váš čas a rady ;-) Já se s tím zkusím ještě nějak poprat.
Str4wberry
Profil
Reakce na joa:
Přijaté a odeslané jsou jasné... s košem je problém a ani tohle to neřeší, protože v koši může být zpráva jak přijatá, tak odeslaná a z toho plyne, že nemůžeš použít dotaz pro vybrání zpráv z koše:
Ano, já to nezohlednil na Tvůj problém. Potom bych si asi vytvořil ty sloupce pro typ zprávy u autora i příjemce.
Mastodont
Profil
joe
Já bych uvažoval nejen o možnosti více složek, ale hlavně o možnosti definovat více příjemců zprávy, to je u mailů přijemná vlastnost ...
joe
Profil
Mastodont
U mailů to dobré je a taky se to používá, třeba ke spamování různými prezentacemi apod :) Tohle budou zprávy mezi uživateli na portálu.
Problém by to nebyl, teď nevím jak to "funguje", pokud bych chtěl vložit více řádků (třeba 5) s různými hodnoty, jestli to zařídí jeden insert nebo insertů 5, zvykl jsem si v MySQL používat "insert into set", ale s klasickou konstrukcí by to mohlo projít. Ale třeba při 5ti nastavených příjemcích by se muselo vložit 10 řádků.
peta
Profil
joe
v tom pripade bych udelal mozna 2 ruzne tabulky. Jedna pro jednoduche zpravy, druha pro kombinovane, kde by max pocet prijemcu byl 5-10, kazdy v jednom sloupci. V pripade vice, by se vlozili 2 zpravy.
To je z hlediska uspory.

Z hlediska rychlosti je mozna lepsi kazdou zpravu vlozit zvlast.



zpravy
id | predmet | zprava | cas

info
zpravaID | odesilatelID | prijemceID | novaZprava | casPrecteni | smazanaOdesilatelem | smazanaPrijemcem | slozkaOdesilatel | slozkaPrijemce

Toto bych resil podobne jako straw
id | autorid | příjemceid | datum | text | typ
mozna spise
id | autorid | příjemceid | typ | umisteni/slozka | autor nick | prijemce nick | datum odeslani | datum precteni | text
sloupce, ktere se pouzivaji nejcasteji bych se snazil dat prvni. Do sql dotazu bych daval prvni hodnoty, ktere jsou male, ciselne a vyskytuji se v co nejmensim poctu.
Nicky je dobre uvest, protoze pak je budes vyhledavat dalsim SQL dotazem? Ale uz bych to podle nicku neindexoval. Pri vyhledani podle autora bych si nasel jeho id. Nick je tudiz jen pomocny text.
Zbytecne vytvaret 2 tabulky. Pokud bys chtel ale nutne 2 tabulky, pak bych oddelil radky pevne delky od promenne, v tomto pripade doufam, ze pouze text ma ruznou delku. Tim se vyrazne zrychly prace s tabulkou1 a zkomplikuje s tabulkou 2.
joe
Profil
peta
Díky, zrovna jsem to dodělával a udělal jsem nakonec jen jednu tabulku, která vypadá nějak takhle:

id | odesilatelID | prijemceID | vlastnikID | zprava

a zprávy jsou vloženy 2x, kde se jen změní id vlastníka, protože pak se s tím mnohem lépe pracuje dál, například ve sloučených složkách, kde můžou být jak přijaté, tak odeslané zprávy.

Nicky je dobre uvest, protoze pak je budes vyhledavat dalsim SQL dotazem?
Dalším ne, ale JOINem, kdybych od uživatele potřeboval vědět jen nick, tak bych ho uložil, ale potřebuju od něj víc údajů, navíc nick se asi bude moci změnit, takže by se to využilo jen v případě, pokud by byl uživatel smazaný a chtěl bych vědět původní nick odesílatele...

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: