2012-07-16 12 views
7

Actualmente estoy codificando mi propio CMS y estoy en el punto del search.php. Necesito buscar en 4 tablas que tienen un nombre de columna diferente en una sola consulta porque mi servidor no es el más rápido.MySQL - Buscar script PHP

Ahí está mi disposición DB:

cmw_admin (tabla de usuarios)

+-----------------+------------+------+-----+---------+----------------+ 
| Field   | Type  | Null | Key | Default | Extra   | 
+-----------------+------------+------+-----+---------+----------------+ 
| id    | int(11) | NO | PRI | NULL | auto_increment | 
| role   | int(11) | NO |  | 1  |    | 
| username  | text  | NO |  | NULL |    | 
| password  | text  | NO |  | NULL |    | 
| email   | text  | NO |  | NULL |    | 
| phone   | text  | NO |  | NULL |    | 
| location  | text  | NO |  | NULL |    | 
| full_name  | text  | NO |  | NULL |    | 
| bio    | text  | NO |  | NULL |    | 
| website   | text  | NO |  | NULL |    | 
| last_login  | datetime | NO |  | NULL |    | 
| registered_date | datetime | NO |  | NULL |    | 
| registered_ip | text  | NO |  | NULL |    | 
| credits   | tinyint(1) | NO |  | NULL |    | 
| online   | int(11) | NO |  | 0  |    | 
+-----------------+------------+------+-----+---------+----------------+ 

cmw_blog (tabla articles)

+------------+----------+------+-----+---------+----------------+ 
| Field  | Type  | Null | Key | Default | Extra   | 
+------------+----------+------+-----+---------+----------------+ 
| id   | int(11) | NO | PRI | NULL | auto_increment | 
| title  | text  | NO |  | NULL |    | 
| content | text  | NO |  | NULL |    | 
| date  | datetime | NO |  | NULL |    | 
| author  | int(11) | NO |  | NULL |    | 
| categories | text  | NO |  | NULL |    | 
| media  | text  | NO |  | NULL |    | 
| thumb  | text  | NO |  | NULL |    | 
+------------+----------+------+-----+---------+----------------+ 

cmw_projects (cartera)

+-------------+------------+------+-----+---------+----------------+ 
| Field  | Type  | Null | Key | Default | Extra   | 
+-------------+------------+------+-----+---------+----------------+ 
| id   | int(11) | NO | PRI | NULL | auto_increment | 
| owner_id | int(11) | NO |  | NULL |    | 
| title  | text  | NO |  | NULL |    | 
| content  | text  | NO |  | NULL |    | 
| date  | date  | NO |  | NULL |    | 
| link  | text  | NO |  | NULL |    | 
| img   | text  | NO |  | NULL |    | 
| type  | int(11) | NO |  | NULL |    | 
| start_date | date  | NO |  | NULL |    | 
| end_date | date  | NO |  | NULL |    | 
| done  | tinyint(1) | NO |  | 0  |    | 
| screenshots | text  | NO |  | NULL |    | 
+-------------+------------+------+-----+---------+----------------+ 

cmw_services (mesa de servicios)

+-------------+---------------+------+-----+---------+----------------+ 
| Field  | Type   | Null | Key | Default | Extra   | 
+-------------+---------------+------+-----+---------+----------------+ 
| id   | int(11)  | NO | PRI | NULL | auto_increment | 
| cat_id  | int(11)  | NO |  | NULL |    | 
| name  | text   | NO |  | NULL |    | 
| description | text   | NO |  | NULL |    | 
| img   | text   | NO |  | NULL |    | 
| price  | decimal(11,2) | NO |  | NULL |    | 
+-------------+---------------+------+-----+---------+----------------+ 

En mi búsqueda, tengo que buscar cada cadena en name/title columnas y en todos los description/content columnas también. En claro, quiero buscar todas esas tablas para una cadena, en una sola consulta. ¿Es eso posible? Sé que usar JOIN, LEFT JOIN, RIGHT JOIN y INNER JOIN puede ser fácil pero no sé cómo usarlos. ¡Google no es muy explícito en esas cosas!

+3

+1 para un buen formato. – Lion

+0

Es bastante fácil de hacer con una unión, pero cualquier coincidencia devolvería cada columna de las 4 tablas. No creo que ese sea el comportamiento previsto. No importa qué tan lento sea su servidor, debería hacer 4 consultas O reestructurar su base de datos –

Respuesta

4

El costo total de cuatro consultas directas es con toda probabilidad mucho menor que el costo de un JOIN más una búsqueda de esos mismos registros/campos.

En todo caso, compruebe las posibilidades de un índice FULLTEXT.

En cualquier caso, se puede hacer esto con algo como

SELECT "cmw_admin" as source, id FROM cmw_admin, NULL as date [...] WHERE bio LIKE '%search%' 
UNION 
SELECT "cmw_blog" as source, id FROM cmw_admin, date as date [...] WHERE 
    (title LIKE '%search%' OR content LIKE '%search%') 
UNION 
... 

que le dará una lista de los registros encontrados, junto con una pizca de que el disco salió a partir de (cmw_blog "cmw_admin"," ", ...); eso le permitirá elegir cómo presentar los registros de las diversas fuentes.

La consulta siempre devolverá el mismo conjunto de campos, algunos con valores válidos, otros no, según la "fuente". Luego, en su script PHP que puede hacer algo así,

$source = $record['source']; 
if (!isset($template[$source])) 
    $template[$source] = file_get_contents("templates/search/$source.html"); 

$html_view = preg_replace('#{{\s*([^}\s]*)\s*}}#e', 'isset(\$record["\1"])?\$vars["\1"]:""', $template[$source]); 

Esto tomará una plantilla HTML que contiene un fragmento de HTML como

<h2>{{ date }}</h2> 

y "rellenar" el campo con la entrada [fecha] de la registro actual $. Encuentro que esta es una buena manera de mantener HTML y código separados (YMMV). Si ya tiene un sistema de plantillas, puede (y debería) adaptarlo en su lugar.

+0

¿Cómo hago esto? Soy muy novato en MySQL, conozco la base y cómo usar PRIMARY KEY, pero el índice 'FULLTEXT' es otra cosa que no sé ... –

1

Si solo desea buscar en mysql, el índice FULLTEXT es el camino a seguir.

Durante la búsqueda se debe utilizar una sola tabla de consulta PR Desde lo más probable es necesario construir enlaces html/resultado que es diferente en función de lo que la tabla del partido se encontró en.

embargo, usted debe considerar el mirar en una verdadera motor de búsqueda como Apache Lucene.Zend tiene una muy buena implementación que no depende de ningún servicio externo. http://framework.zend.com/manual/en/zend.search.lucene.html/ le ayudará a clasificar los resultados mejor de lo que puede hacer con mysql y debería escalar mejor.

+0

Parece que el enlace no está roto, pero es extraño. No puedo acceder a la información, siempre muestra la introducción a Zend Framework. –