sql >> Database >  >> RDS >> Mysql

De beste manier om tags voor snelheid op te slaan in een enorme tabel

FULLTEXT-indexen zijn echt niet zo snel als je misschien denkt.

Gebruik een aparte tabel om uw tags op te slaan:

Table tags
----------
id integer PK
tag varchar(20)

Table tag_link
--------------
tag_id integer foreign key references tag(id)
content_id integer foreign key references content(id)
/* this table has a PK consisting of tag_id + content_id */

Table content
--------------
id integer PK
......

U SELECTEERt alle inhoud met tag x met behulp van:

SELECT c.* FROM tags t
INNER JOIN tag_link tl ON (t.id = tl.tag_id)
INNER JOIN content c ON (c.id = tl.content_id)
WHERE tag = 'test'
ORDER BY tl.content_id DESC /*latest content first*/
LIMIT 10;

Vanwege de refererende sleutel worden alle velden in tag_links individueel geïndexeerd.
De `WHERE tags ='test' selecteert 1 (!) record.
Equi voegt hieraan 10.000 taglinks toe.
En Equi sluit zich aan bij dat met elk 1 inhoudsrecord (elke tag_link verwijst slechts naar 1 inhoud).
Vanwege de limiet van 10 stopt MySQL met zoeken zodra het 10 items heeft, dus het kijkt eigenlijk alleen naar 10 tag_links-records.
De content.id wordt automatisch verhoogd, dus hogere aantallen zijn een zeer snelle proxy voor nieuwere artikelen.

In dit geval zul je nooit moet zoeken naar iets anders dan gelijkheid en je begint met 1 tag die je equi-join gebruikt met behulp van integer-sleutels (de snelst mogelijke join).

Er zijn geen of-dan-of-maars, dit is de snelste manier.

Houd er rekening mee dat, omdat er maximaal een paar 1000 tags zijn, elke zoekopdracht veel sneller zal zijn dan het doorzoeken van de volledige inhoudstabel.

Eindelijk
CSV-velden zijn een heel slecht idee, gebruik ze nooit in een database.




  1. Een string opvragen uit de int-kolom?

  2. Definities overslaan of negeren in Mysqldump

  3. Kan parameter niet doorgeven via referentie in MySQLi

  4. GIN-index op smallint[]-kolom niet gebruikt of foutoperator is niet uniek