Autor Zpráva
qteck
Profil
Ahoj,

dělám hash tag systém. tabulky: articles ; tags ; ref.tags

Mám problém s duplicitama v ref.tags. Vím že byse to dalo jednoduše ošetřit použitím SELECT DISTINCT. Cona to ale rychlost až v tabulce bude třeba 10 000 referencí?

Dalo by se to taky ověřit před uložením poměrně jednoduše pokud bychnastavil unique key. To ale nemohu, protože v téhle tabulce nemám žádnou unikátní hodnotu.

Mohl bych taky před vložením hodit jenoduše select ověření a pod to insert, ale zase tu vyvstává otázka co na to rychlost zpracování?

Poslední nápad je trigger. Kterej bych to vždycky čekl při vložení a pokud existuje duplicitu vymazal. Což je podle mého názoru také nejlepší řešení, ale zase naúkor přehlednosti.

Co vy na to?

function hashTagInsert($tags, $id) 
    {        
        $lastInsertId = $id; //to get id of edited article instead of last id 
        
        foreach ($tags as $val)
        {
            $sql3 = 'SELECT id FROM tags WHERE tag = :tag';
               
            $existingTagId = $this->db->queryFetch($sql3, array(':tag' => $val));              
                
            if(!$existingTagId)
            {
                $sql = 'INSERT INTO tags (tag, added) VALUES (:tag, NOW())';
                $this->db->boolQuery($sql, array(':tag' => $val));
               
            }
            
            $tagId = (!empty($existingTagId)? array_shift($existingTagId) : $this->db->lastId());
            
            $sql2 = 'INSERT INTO tags_refs (article_id, tag_id) VALUES (:lastInsertId, :tagId)';
            $this->db->boolQuery($sql2, array(':lastInsertId' => $lastInsertId,
                                              ':tagId' => $tagId));
            
            unset($existingTagId);
        }
    } 
Kajman
Profil
A víte o tom, že můžete mít unikátní klíč na kombinaci více sloupců?
Keeehi
Profil
+ aplikace jde přece napsat tak, aby duplicity nevytvářela. Když je článek nový, nemá žádné tagy tak mu jde přiřadit cokoliv. No a při editaci stačí jen nezobrazit k přidání ty tagy, které už článek má.
qteck
Profil
No ono mi to funguje takto:

Představme si v závorkách článek
"
Tady máme nějaký symbolický text co se vleče přes několik řádků.
Pak pod to chci hodit nějaké klíčové tagy,
které třeba ještě ani neexistují.

#tagyKtereJesteNeexistuji #symbolickyText #BorecciZJakPsatWeb
"

Při ukládání si z toho tagy vytáhnu. Uživatelé je mohou vytvářet nezávisle už na existujících tagách. Pokud tag existuje nevytvoří se, protože to tag je unikátní záležitost a je na něm unique key.

Reference se ale vytvoří.

tabulka ref obsahuje tři slupce id ; tag-id ; article-id

Žádnej ze sloupců není samostatně vyloženě unikátní kromě id. tag-id a article-id jsou unikátní v závislosti na sobě ale né jako jednotlivé sloupce.

takže se mi může vyskytnout toto:

1 - 45 - 4
2 - 55 - 8
3 - 45 - 4

SELECT DISTINCT tohle vyřeší jednoduše, ale podle mého názoru je to chyba. Chci mít databázi čistou bez zbytečných nepotřebných záznamů. Efektivní a rychlou.

Nejlepší řešení je pravděpodobně trigger.

Co vy na to?
Alphard
Profil
qteck:
Mohl bych taky před vložením hodit jenoduše select ověření a pod to insert, ale zase tu vyvstává otázka co na to rychlost zpracování?
Jak často se budou přidávat nové články? Jestli se nechystáte konkurovat twitteru, tak to databáze určitě přežije, běžně snáší horší věci.
qteck
Profil
Jasně ale jde přecitakyo to aby to nebyla prasárna příliš.
Keeehi
Profil
qteck:
takže se mi může vyskytnout toto:
Nemůže. První záznam vznikne při vytváření článku 4, druhý záznam vznikne při vytváření článku 8. No a třetí by měl vzniknout až při editaci článku 4. Ale ty víš že pro článek 4 jsi už dříve tag 45 přidal. Protože pro editaci jsi všechny tagy ke článku musel vytáhnout a víš že se nezměnily. Tak je ani nemusíš ukládat.

Ale i kdyby, jak už psal Kajman v [#2], můžeš vytvořit unikátnost kombinace více sloupců
ALTER TABLE `tabulka` ADD UNIQUE `unique_index`(`tag-id`, `article-id`);
qteck
Profil
Ale může být přidaný článek tagem předchozího článku.Takovej tag už existuje v tabulce tag a tak se nevytvoří. ale referencito udělá a v případě že je tamunikátní klíč na něčem tak to skončí negativně.

Unique keys jsou špatné řešení.


Udělal jsem to takto. Funguje to vpohodě s rychlostí uvidím až tam bude nějaká zátěž. Chtěl jsem se vyhnout tolika příkazům protože je to v cyklu a autimatickymi to mi to vytváří hned někollik základních tagů.


    function hashTagInsert($tags, $editedArticleId) 
    {        
    
        
        foreach ($tags as $val)
        {
            $sql3 = 'SELECT id FROM tags WHERE tag = :tag';
               
            $existingTagId = $this->db->queryFetch($sql3, array(':tag' => $val));              
                
            if(!$existingTagId)
            {
                $sql = 'INSERT INTO tags (tag, added) VALUES (:tag, NOW())';
                $this->db->boolQuery($sql, array(':tag' => $val));
               
            }
            
            $tagId = (!empty($existingTagId)? array_shift($existingTagId) : $this->db->lastId());
            
            $sql4 = 'SELECT article_id, tag_id FROM tags_refs WHERE article_id = :articleId AND tag_id = :tagId';
               
            $existingTagRef = $this->db->queryFetch($sql4, array(':articleId' => $editedArticleId, 
                                                                 ':tagId' => $tagId)); 
            
            if(!$existingTagRef)
            {
                $sql2 = 'INSERT INTO tags_refs (article_id, tag_id) VALUES (:editedArticleId, :tagId)';
                $this->db->boolQuery($sql2, array(':editedArticleId' => $editedArticleId,
                                                  ':tagId' => $tagId));
            }
            
            unset($existingTagId);
        }
    } 

Díky
Keeehi
Profil
qteck:
Unique keys jsou špatné řešení.
Je to správné. To co jsem napsal v [#7] totiž nevytvoří 2 omezení pro dva sloupce ale jedno omezení z dat dvou sloupců. A to je to co jsi zatím nepochopil.

Příklad:
Postupně vkládám 5 záznamů:
záznam 1 - 12, 52 - OK, v tabulce nic není
záznam 2 - 12, 53 - OK, 12 sice je v prvním záznamu je ale druhý sloupec neodpovídá
záznam 3 - 13, 52 - OK, hodnota v druhém sloupci sice odpovídá hodnotě prvního záznamu avšak v prvním sloupci ne
záznam 4 - 13, 53 - OK, hodnoty z prvního i z druhého sloupce se sice nacházejí v některém z předchozích záznamů avšak nikdy ne zároveň
záznam 5 - 12, 53 - FAIL, kombinace 12, 53 se už nachází v záznamu 2
qteck
Profil
Okay no tak to potom joo :D.

Jsem netušil, že to funguje takto. Vlastně jsem si ani nedokázal představit, že byto takto fungovat mohlo.

Díky Keeshi, to je ještě nová znalost :-).

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: