Kamelot Blog

Aller au contenu | Aller au menu | Aller à la recherche

samedi 25 septembre 2010

sam
25
sep '10

2 fonctions Mysql : EXPORT_SET et MAKE_SET

EXPORT_SET

SELECT EXPORT_SET(5,'oui','non','|',7);

Créer une chaîne exprimant la représentation littérale de la valeur binaire de 5,

les 1 seront représentés par des oui et les 0 seront représentés par des non

le tout séparé par des |

Attention la chaîne est "inversée"

 1 -> 1   -> oui         
 2 -> 10  -> non|oui     
 3 -> 11  -> oui|oui     
 4 -> 100 -> non|non|oui     
 5 -> 101 -> oui|non|oui

Le dernier paramètre permet de complèter

EXPORT_SET(5,'oui','non','|',7)
---
oui|non|oui|non|non|non|non

MAKE_SET

MAKE_SET(valeur numérique,chaine1,chaine2,chaine3,chaine4)

Avec export_Set on avait une "oui" pour 1 "non" pour 0 Ici on a "chaine1" si le bit le plus a droite est à 1

Si plusieurs bit sont à 1 on aura donc plusieurs chaines. Celles-ci seront séparées par des virgules ,

Donc avec

12 -> 1100

on inverse

0011
abcd
SELECT MAKE_SET(4,'a','b','c','d');
-
c,d

On peut s'amuser

SELECT CONCAT('Je suis ',MAKE_SET(RAND()*5,'beau','grand','méchant','passionné'),' et fort')
---
Je suis beau,grand et fort

Notez qu'on peut utilisé le "ou" ou le "et"

SELECT MAKE_SET(1|4,'a','b','c','d');
-
a,c
MAKE_SET(4&5,'a','b','c','d')
-
c

Tout ceci , sans php.

lundi 13 septembre 2010

lun
13
sep '10

Peur du jour où vous perdez votre mot de passe google ?

configurez vous options de récupération

vendredi 10 septembre 2010

ven
10
sep '10

StrToNum ou comment convertir une chaine en nombre ?

Dans Sphinx, les filtres doivent être scalaires. J'avais donc un problème pour obtenir une version numérique d'un code pays.

ASCII(str) transforme le premier caractère de votre chaine en nombre.

Mais comment faire pour avoir un nombre différent pour 2 chaines ayant le même premier caractère ?

J'étais parti dans un délire :

  ASCII(code)-65 + (ASCII(substr(code,1,0)-65+26)  ...

Puis j'ai un peu regratté la doc et j'ai trouvé HEX()

HEX(N_or_S)




Si N_OR_S est une chaîne de caractères, cette fonction retournera une chaîne de caractères hexadécimale de N_OR_S où chaque caractère de N_OR_S est converti en 2 chiffres hexadécimaux.

edit: Je n'ai par contre pas encore trouvé d'équivalent PHP. En PHP on a bin2hex. pour obtenir la même chose.

SELECT HEX('hello'),HEX('ZZ'),HEX('0A'),HEX(0xA);
HEX('hello')  HEX('ZZ')  HEX('0A')  HEX(0xA)
------------  ---------  ---------  --------
68656C6C6F    5A5A       3041       0A      

HEX('php')  HEX('PHP')  HEX('Php')
----------  ----------  ----------
706870      504850      506870    

HEX('aa')  HEX('ab')  HEX('AA')  HEX('AB')  HEX('ZZ')
---------  ---------  ---------  ---------  ---------
6161       6162       4141       4142       5A5A     

Edit (2010-09-30)

Visiblement mon blog est très lu : je dit une grosse connerie et personne le remarque.

Mon objectif présenté ici est de transformer une chaîne en nombre et la solution que je présente ne donne pas le résultat escompté.

En effet HEX('ZZ') -> 5A5A reste une chaine (0x5A5A est un nombre)

Donc pour finaliser le travail il faut reconvertir le hex en dec

avec CONV(leresultat, 16, 10) en mysql et avec hexdec() en php (et pas hex2dec )

mercredi 8 septembre 2010

mer
08
sep '10

Forum PHP Paris 2010 : 15 ans de PHP et des 10 ans de l'Afup.

Forum PHP Paris 2010 organisé par l'AFUP avec les meilleurs experts PHP français et internationaux

Le Forum PHP 2010 est officiellement annoncé pour les 09 et 10 novembre 2010 à la Cité des Sciences de Paris la Villette (France).

C'est le seul évènement professionnel en France consacré à la plate-forme PHP et aux technologies Web. Il rassemble les différents acteurs de la profession et valorise le dynamisme français en terme de technologies de pointe sur Internet.

Il sera placé sous le signe des 15 ans de PHP et des 10 ans de l'Afup.

mardi 7 septembre 2010

mar
07
sep '10

Colonnes Virtuelles pour MariaDb

Un petit post pour dire que dans la 5.2 de MariaDB on aura droit a des colonnes virtuelles

Fonctionnalité disponible dans oracle depuis sa version 11 et inexistante chez Mysql.

[sql]
 create table table1 (
    a int not null,
    b varchar(32),
    c int as (a mod 10) virtual,
    d varchar(5) as (left(b,5)) persistent);

Les colonnes C et D sont virtuelles, et ne représentent que des calculs (à la volée pour C à l'insertion pour D).

Les PERSISTENT peuvent même être utilisées pour des index (pas primary)

samedi 4 septembre 2010

sam
04
sep '10

Sphinx : j'en dit un peu plus sur ce moteur de recherche

Je parlais il y a 2 jours de sphinx en expédiant une explication en 2 secondes.

Le lendemain, je vois sur Planet Mysql que Shlomi Noach publiait un article pour remettre les pendules à l'heure sur ce qu'est sphinx

Je vais donc en dire un peu plus.

Sphinx est un moteur d'indexation/recherche open-source sous GPLv2.

On utilise indexer pour scanner ce qu'il faut indexer, cela génère des fichiers que searchd rend consultables.

Pour attaquer searchd, on a search en ligne de commande.

Mais on a aussi

  • SphinxSE: un engine mysql, il sera inclus directement dans les prochaines versions de mariaDb
  • SphinxAPI: que l'on peut utiliser en php avec un package pecl dedié mais aussi avec les apis officielles Php, Python, Java, Ruby, pur C, fournies avec sphinx, ou bien encore Riddle pour Ruby, Sphinx::Search pour perl, C++ Sphinx client, Haskell Sphinx client, C# .NET client, ...
  • SphinxQL: une syntaxe sql adaptée

Recherche

Pour la recherche elle même on a les syntaxes avancées sur le texte ...

  • et, ou , mais pas,
"hello world" @title "example program"~5 @body python -(php|perl) @* code
  • les quorum (je donne 7 mots et je veux qu'il y en aie au moins 4 dans chaque résultats)
  • la pertinence (ce mot là a plus de poids dans le titre, celui ci partout, ... )
  • la distance dans le texte : ces 2 mots là doivent être séparés par moins de n mots
  • Des remplacements
    • de caractères pour les problèmes de charset
    • les remplacements magiques (si je cherche email, je trouve aussi les contenus avec le mot courriel) sur base de vos listes (voir exemple en bas)
    • Morphologie linguistique, stemming (gestion des pluriels),
    • listes de mots interdits
    • listes de dictionnaires personnels pour la correction magique
  • ...

.. Les critères de filtre et tri annexe

  • groupes (avec decompte par groupe)
  • temporels
  • géographiques
  • ...

J'en passe bien sur.

Le service searchd est consultable via réseau (donc si vous utilisez SphinxSE il n'est pas embarqué dans la DB il peut/ils peuvent être ailleurs) avec ssl et tout le brol.

Indexation

La première chose à distinguer c'est qu'il n'est pas limité à mysql ni même à des bases de données. On peut indexer tout ce qui peut être parsé, moyennant une conversion vers un fichier xml.

On peut indexer des sources hétérogènes les mélanger comme on peut indexer partiellement une source monolithique.

On peut indexer "sur le coté" pendant que l'index précédent reste actif et swapper à la fin (très difficile à faire : il faut ajouter un --rotate)

On peut indexer par petit morceaux et exploiter les partitions ou les merger

On peut répartir les indexs sur plusieurs serveurs

Brefs il y a moyen de distribuer la recherche et l'indexation.

Il y a des techniques de RealTime indexing mais c'est dans la 1.10-beta

Lire la suite...

vendredi 3 septembre 2010

ven
03
sep '10

Chuck Norris et l'éléphpant

Après E_Chuck_Norris, le package Chuck Norris pour Drupal.

On a de l'humour dans la communauté PHP.

mercredi 1 septembre 2010

mer
01
sep '10

Nombre de résultats d'une recherche SphinxSe

Logo Sphinx Sphinx est un moteur de recherche full-text

On peut l'interroger au travers de son api, SphinxQL, en ligne de commande ou avec l'engine MySql SphinxSE

J'utilise MySqlSE;

SELECT * from INFORMATION_SCHEMA.ENGINES;

ENGINE SUPPORT COMMENT                     TRANSACTIONS  XA      SAVEPOINTS
------ ------- --------------------------- ------------  ------  ----------
...
SPHINX YES     Sphinx storage engine 0.9.9 NO            NO      NO        

La question du jour était : Y a-t-il un moyen de connaître le nombre total de résultats quand on utilise un limit ?

En Mysql simple, il y a SQL_CALC_FOUND_ROWS

mysql> SELECT SQL_CALC_FOUND_ROWS * 
    -> FROM tbl_name
    -> WHERE id > 100 LIMIT 10;
mysql> SELECT FOUND_ROWS();

Le second SELECT retourne un nombre indiquant combien de lignes le premier SELECT aurait retourné s'il n'avait pas été écrit avec une clause LIMIT.

Mais avec avec SPHINX

En testant sur ma table tbl_name_sphinx qui contient 2410 rows.

select SQL_CALC_FOUND_ROWS * from tbl_name_sphinx WHERE query='' LIMIT 10;
SELECT FOUND_ROWS();
Résultat
FOUND_ROWS()
------------
          20

20 parce que c'est la valeur par défaut du limit de sphinx

# limit - amount of matches to retrieve from result set, default is 20; (ref)

En effet si je force ce limit à 10

select SQL_CALC_FOUND_ROWS *
 from tbl_name_sphinx 
 WHERE query=';limit=10';

SELECT FOUND_ROWS();
Résultat

FOUND_ROWS() -> 10

Pourquoi ? parce que c'est sphinx qui fait la vraie recherche et remonte son résultat à MySql

Donc quand je fait

select SQL_CALC_FOUND_ROWS * 
 from tbl_name_sphinx 
 WHERE query=';limit=1000' 
 LIMIT 10;

Je reçois 10 résultats sur 2410 réels et sur les 1000 que sphinx a remonté

Donc

SELECT FOUND_ROWS(); -> affiche 1000 et pas 2410.

Donc je vais monter mon limit à 1000000.

Gloups, je viens de demander à Sphinx de me préparer en résultat de 100K rows, tout renvoyer à mysql dans une table temporaire qui me retournera uniquement les 10 premiers.... Fameux gaspillage

Quand on sait que sphinx ne me retourne que les id et que donc il faut faire un join avec la table de données, ca fait mal.

la solution

SHOW ENGINE SPHINX STATUS;

On oublie le 'SQL_CALC_FOUND_ROWS'

Et on remplace FOUND_ROWS() par SHOW ENGINE SPHINX STATUS;

On remet le limit 10 au niveau de sphinx;

select  * 
 from tbl_name_sphinx 
 WHERE query=';limit=10';

SHOW ENGINE SPHINX STATUS;

Type    Name    Status                                           
------  ------  -------------------------------------------------
SPHINX  stats   total: 1000, total found: 2410, time: 0, words: 0

Bingo j'ai mon info, planquée dans une "chaine" mais je l'ai.

re bingo

 SHOW STATUS LIKE 'sphinx_%';

Mais je préfère INFORMATION_SCHEMA.

SELECT *
 from information_schema.GLOBAL_STATUS
 WHERE VARIABLE_NAME like 'SPHINX%';
VARIABLE_NAME       VARIABLE_VALUE
------------------  --------------
SPHINX_ERROR        208409        
SPHINX_TIME         0             
SPHINX_TOTAL        1000          
SPHINX_TOTAL_FOUND  2410          
SPHINX_WORD_COUNT   0             
SPHINX_WORDS                      

Et je suis un heureux.

Si vous êtes intéressés par Sphinx, voici un bon article pour l'installer.

Si vous vous êtes déjà intéressé à Zend_Search_Lucene, (bien décrit ici) il me semble avoir que celui-ci peut utiliser Sphinx comme backend. je corrigerai si je retrouve la source.

Tags