Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Sistema de marcação:perguntas sobre a solução Toxi


Em primeiro lugar, "toxi" não é um termo padrão. Sempre defina seus termos! Ou pelo menos fornecer links relevantes.

E agora a pergunta em si...

Não, você terá 3 mesas.

Você está praticamente no caminho certo, com a exceção de que pode usar a natureza baseada em conjunto do SQL para "mesclar" muitas dessas etapas. Por exemplo, marcar um item 1 com as tags:'tag1', 'tag2' e 'tag3' pode ser feito assim...
INSERT IGNORE INTO tagmap (item_id, tag_id)
SELECT 1, tag_id FROM tags WHERE tag_text IN ('tag1', 'tag2', 'tag3');

O IGNORE permite que isso seja bem-sucedido mesmo se o item já estiver conectado a algumas dessas tags.

Isso pressupõe que todas as tags necessárias já estejam em tags . Supondo tag.tag_id é auto-incremento, você pode fazer algo assim para garantir que eles sejam:
INSERT IGNORE INTO tags (tag_text) VALUES ('tag1'), ('tag2'), ('tag3');

Não há mágica. Se "item está conectado a uma tag específica" for um conhecimento que você deseja registrar, ele terá ter algum tipo de representação física no banco de dados.

Você quer dizer remarcar itens (não modificar as próprias tags)?

Para remover todas as tags que não estão na lista, faça algo assim:
DELETE FROM tagmap
WHERE
    item_id = 1
    AND tag_id NOT IN (
        SELECT tag_id FROM tags
        WHERE tag_text IN ('tag1', 'tag3')
    );

Isso desconectará o item de todas as tags, exceto 'tag1' e 'tag3'. Execute o INSERT acima e este DELETE um após o outro para "cobrir" tanto a adição quanto a remoção de tags.

Você pode brincar com tudo isso no SQL Fiddle .

Correto. Um endpoint filho de um FK não acionará uma ação referencial (como ON DELETE CASCADE), apenas o pai o fará.

BTW, você está usando este esquema porque deseja campos adicionais em tags (ao lado de tag_text ), direita? Se você fizer isso, não perder esses dados adicionais apenas porque todas as conexões se foram é o comportamento desejado.

Mas se você quiser apenas o tag_text , você usaria um esquema mais simples em que excluir todas as conexões seria o mesmo que excluir a própria tag:



Isso não apenas simplificaria o SQL, mas também forneceria um melhor clustering .

À primeira vista, "toxi" pode parecer que está economizando espaço, mas isso pode não ser o caso na prática, pois requer tabelas e índices adicionais (e as tags tendem a ser curtas).

Meça antes de decidir fazer algo assim. Meu SQL Fiddle mencionado acima usa uma ordem muito deliberada de campos no tagmap PK, então os dados são agrupados de uma maneira muito amigável para esse tipo de contagem (lembre-se:As tabelas InnoDB são agrupadas ). Você teria que ter uma quantidade realmente enorme de itens (ou exigir um desempenho excepcionalmente alto) antes que isso se tornasse um problema.

De qualquer forma, medir em quantidades realistas de dados!