Diskuze: Návrh tabulky/ek - odesílání zpráv
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
Zobrazeno 20 zpráv z 20.
K personalizaci obsahu a reklam, poskytování funkcí sociálních médií a analýze naší návštěvnosti využíváme soubory cookie. Informace o tom, jak náš web používáte, sdílíme se svými partnery pro sociální média, inzerci a analýzy. Partneři tyto údaje mohou zkombinovat s dalšími informacemi, které jste jim poskytli nebo které získali v důsledku toho, že používáte jejich služby.
Používáme nezbytné cookies pro fungování webu a s tvým souhlasem také analytické a marketingové cookies.
Zajišťují základní funkce, bezpečnost a služby, které sis vyžádal. Nelze je vypnout.
| Služba | Poskytovatel | Účel | Cookies a úložiště | Doba uložení |
|---|---|---|---|---|
| ITnetwork | ITnetwork | Provoz webu, relace, přihlášení a uložení nastavení cookies. | PHPSESSID, auth_token, sid, itn_consent_impression, __Host-itn_consent | Relace až 1 rok |
| Google Tag Manager | Správa značek a načítání měřicích nástrojů webu. | Žádné | Neukládá se | |
| Google Fonts | Načítání typografie webu. | Úložiště řízené poskytovatelem | Dle podmínek poskytovatele | |
| Google Hosted Libraries | Načítání potřebných knihoven a stylů webu. | Úložiště řízené poskytovatelem | Dle podmínek poskytovatele | |
| Google reCAPTCHA | Ochrana formulářů a webu před zneužitím. | _GRECAPTCHA, rc::a, rc::b, rc::c, rc::f | Relace až 180 dní | |
| YouTube | Přehrávání vloženého video obsahu. | localStorage, IndexedDB; cookies after playback interaction | Relace až trvalé úložiště | |
| Vimeo | Vimeo | Přehrávání vloženého video obsahu. | __cf_bm, _cfuvid, vuid, localStorage, IndexedDB | Relace až 2 roky |
| Facebook Login | Meta | Přihlášení pomocí účtu třetí strany. | Úložiště řízené poskytovatelem | Relace až 1 rok |
| GoPay | GoPay | Zpracování uživatelem vyžádané platby. | Úložiště řízené poskytovatelem | Dle podmínek poskytovatele |
Pomáhají nám porozumět používání webu a zlepšovat ho.
| Služba | Poskytovatel | Účel | Cookies a úložiště | Doba uložení |
|---|---|---|---|---|
| Google Analytics 4 | Měření návštěvnosti a používání webu. | _ga, _ga_* | Až 2 roky | |
| Microsoft Clarity | Microsoft | Měření návštěvnosti a používání webu. | _clck, _clsk, _cltk | Relace až 1 rok |
Slouží k měření kampaní, personalizaci reklamy a marketingové komunikaci.
| Služba | Poskytovatel | Účel | Cookies a úložiště | Doba uložení |
|---|---|---|---|---|
| Google Ads | Měření kampaní, reklama a remarketing. | _gcl_au, _gcl_ls | Relace až 90 dní | |
| Meta Pixel | Meta | Měření kampaní, reklama a remarketing. | _fbp, _fbc, localStorage | Až 90 dní |
| Sklik | Seznam.cz | Měření kampaní, reklama a remarketing. | retargeting, sid, szn:* | Relace až trvalé úložiště |
| LinkedIn Insight | Měření kampaní, reklama a remarketing. | bcookie, li_gc, lidc, __cf_bm | Relace až 1 rok | |
| Ecomail | Ecomail.cz | Měření kampaní, reklama a remarketing. | ecmid, Úložiště řízené poskytovatelem | Dle podmínek poskytovatele |
| Atribuce kampaní ITnetwork | ITnetwork | Přiřazení návštěvy a objednávky ke kampani. | campaign_clid[*], user_session_context | Až 1 rok |
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
Zkus to rozdělit na dvě tabulky:
CREATE TABLE message (
id int,
subject text,
content text,
time datetime,
type int);
CREATE TABLE cover (
id int,
mesage_id int,
uzivatel_id int,
type int);
Zpráva bude pouze 1× v tabulce message, vytvoří se k ní záznamy odesílateli i příjemci (resp. příjemcům) do tabulky cover.
S tím reportem bych byl opatrnější, ten se dá uložit
přímo do tabulky příjemce ve formě počitadla.
Děkuji za návrh. Mohl bys mi, prosím tě, upřesnit, co přesně bude
message.type a
cover.type?
message.type nebude
cover.type INT -- 1 příchozí, 2 odeslané, 3 skupinové
Odesílatel bude mít type 2, příjemce 1 nebo 3. Ke každému záznamu v
message budou 2 záznamy v cover. Když příjemce
"smaže zprávu", smaže se jeho záznam v cover. Když odesílatel
"smaže odeslanou zprávu", opět se smaže jen jeho záznam v
cover. Občas se smažou položky v message, na které
není žádný odkaz v cover.
Jasně, děkuji za vysvětlení!
Ještě malá ukázka, jak se budou vypisovat přijaté, odeslané a skupinové zprávy:
SELECT subject, content FROM message WHERE id IN (
SELECT message_id FROM cover WHERE uzivatel_id = $myid AND type = 1
)
Jenom se to bude lišit podmínkou type. Samozřejmě se to dá
vylepšit o některé údaje (např. kdo a komu v message), ale to snad
zvládneš. Tyto údaje tam vlastně budou 2×. Jednou pro doručování (v
cover) a podruhé pro evidenci (v message). V cover se to dá
udělat i triggerem, který zároveň u příjemce zvýší počitadlo
nepřečtených mailů. Jedinou tvou starostí při odesílání zprávy pak
bude zapsat záznam do tabulky message.
Co se týká toho počítadla nepřečtených zpráv, pochopil jsem správně, že daný počet bude v nové tabulce?
Nemusí být nová. To počitadlo může být sloupeček v tabulce uživatelů/hráčů.
Děkuji za nápad s triggery. Sice jsem s nimi dělal prakticky poprvé, ale nakonec to funguje a funguje to skvěle.
Není zač. Triggery by se měly používat všude tam, kde se dělala denormalizace databáze.
Ještě taková drobnost. Občas se řeší, že před uložením záznamu je nutné některý údaj vyhledat v jiné tabulce a záznam přidat pouze v případě, že je v té tabulce nalezen. Řešení v SQL je celkem jednoduché:
INSERT INTO message (author_id, recipient_id, subject)
SELECT :myid, recipient_id, :subject FROM users
WHERE name LIKE :recipient LIMIT 1;
-- :myid => id odesílatele
-- :subject => předmět zprávy
-- :recipient => jméno příjemce, které se má nahradit jeho id
A teď otázka: Dá se tato trivialita řešit v Dibi a podobných frameworcích nebo se to musí dělat více SQL dotazy? Jak by to asi vypadalo?
Dobrý nápad, nicméně mám stále v těchto dvou tabulkách problém, jak
vložit ta data závisle na tom, zda existuje daný uživatel.
Prvně musím vložit do tabulky message a poté do tabulky
cover (jejíž sloupec message_id se bude rovnat
message.id). Jenže to první vložení musí
proběhnout jen tehdy, že ten uživatel existuje, což je trochu zamotané.
To první vložení do message bude viz výše. Ověřuje se tam
proti tabulce users. Pokud adresát neexistuje, zpráva se
nevloží, protože výsledek selectu bude prázdný. V případě úspěchu
nastoupí trigger navázaný na message a vloží dva patřičné
záznamy do cover.
A aby toho nebylo málo, na cover bude navázán další
trigger, který v případě přidání záznamu typu přijatá nebo skupinová
pošta inkrementuje příjemci čítač došlé pošty v users.
Hmm, stále mě nenapadá způsob, jak to aplikovat, když v tabulce
messsage jsou sloupce id, subject,
content a time. Pokud použiji ten SELECT, hlásí mi
databáze chybu, že se snažím vybrat více hodnot, než kolik mohu
vložit.
Možná je to triviální řešení, ale za boha nemohu přijít, jak to
udělat.
Ten trigger na čítač mám již hotový a funguje (když jsem to zkoušel vložit manuálně v Admineru). Jen mám teď problém s vložením té zprávy od uživatele.
Za INSERT INTO máš v závorce 3 parametry. Za tím SELECTem musí být výběr 3 sloupců z druhé databáze. Některé můžeš nahradit konstantou nebo subselectem, ale počet musí souhlasit.
Místo čísla 3 si dosaď jakékoli jiné číslo.
Asi tam přece jen budeš muset přidat i sloupce author_id a
recipient_id, aby se ten trigger měl čeho chytit.
Tak jo, děkuji za pomoc. Jestli by nebylo nakonec nejlepší vše udělat prostě do jedné tabulky s tím, že se ten předmět a obsah bude opakovat.
Uvědom si, že jsme tady řešili víc problémů, než jen duplicitu jednoho záznamu. Jeden INSERT je vždy rychlejší než dva a máš garantovánu konzistenci. Kromě toho se normalizace hodí vždy.
Zobrazeno 20 zpráv z 20.