miércoles, 31 de octubre de 2012

Optimización de consultas

Cuando hablamos de optimización de consultas nos referimos a mejorar los tiempos de respuesta en un sistema de gestión de bases de datos relacional, pues la optimización es el proceso de modificar un sistema para mejorar su eficiencia o también el uso de los recursos disponibles.
En bases de datos relacionales el lenguaje de consultas SQL es el más utilizado por el común de los programadores y desarrolladores para obtener información desde la base de datos. La complejidad que pueden alcanzar algunas consultas puede ser tal, que el diseño de una consulta puede tomar un tiempo considerable, obteniendo no siempre una respuesta óptima.

Tuplas
Una tupla de una relación o de una tabla corresponde a una fila de aquella tabla. Las tuplas están comúnmente desordenadas puesto que matemáticamente una relación se define como un conjunto y no como una lista. No existen tuplas duplicadas en una relación o tabla dado el hecho de que una relación es un conjunto y los conjuntos por definición no permiten elementos duplicados.
Un corolario importante en este punto es que la llave primaria siempre existe dada la condición de unicidad de las tuplas, por lo tanto, como mínimo la combinación de todos los atributos de una tabla puede servir para la conformación de la llave primaria, sin embargo usualmente no es necesario incluir todos los atributos, comúnmente algunas combinaciones mínimas son suficientes.

Relación
Formalmente, una relación R es un conjunto de n-tuplas.
Las propiedades fundamentales de una relación son:
  • No hay tuplas repetidas.
  • Las tuplas no están ordenadas.
  • Los atributos no están ordenados.
Cuando vamos a realizar este proceso debemos tener en cuenta aspectos tales como:
  • Evaluación de que la consulta es algebraicamente más correcta
  • Evaluación de la carga sobre los recursos del sistema

Ejemplo

A continuación podemos observar un ejemplo de la problemática de optimización. En este simple problema tenemos tablas de “Suppliers” (S) y “Orders” (SP)con 100 administradores y 10.000 pedidos. Consulta: “Obtener los nombres de los suministradores que nos sirven la pieza P2”. Consideraremos que sólo 50 tuplas de SP corresponden a la pieza P2.
SELECT DISTINCT S.NOMBRE FROM S, SP WHERE S.S#=SP.S# AND SP.P#=”P2”;
En el anterior ejercicio tenemos un producto cartesiano S x SP 100 x 10.000 = 1.000.000 de tuplas leídas. Probablemente 1.000.000 de tuplas escritas en memoria virtual. Cuando utilizamos la sentencia WHERE pasamos de 1.000.000 de tuplas leídas a 50 tuplas, luego realizamos una proyección sobre S.NOMBRE, dando como resultado un máximo de 50 tuplas.

Procedimientos

Seleccionar en SP las tuplas de la pieza P2. Se realizará lectura de 10.000 tuplas dando como resultado: 50 tuplas. Hacer JOIN de la tabla anterior. Con la tabla S se realizara lectura de 100 tuplas, dando como resultado: 50 tuplas con proyección sobre S.NOMBRE, dando como resultado un máximo de 50 tuplas.

Conclusión

El segundo procedimiento es unas 300 veces mejor, ya que el primero realiza 3.000000.000 operaciones de E/S, frente a 10..100 del segundo.

¿Dónde incide la optimización?

  • El coste de comunicación de acceso a almacenamiento secundario.
  • El coste de almacenamiento.
  • El coste de computación.
  • El optimizador interviene también en las actualizaciones y borrados.
El proceso de optimización
1.1. Representación interna de consultas. 1.2. Conversión a forma canónica. 1.3. Elección de procedimientos de bajo nivel. 1.4. Generación y elección de planes de consulta.

Representación interna de consultas

  • Características:
    • Ser relacionalmente completo.
    • Suministrar un punto de partida sólido para las siguientes fases.
    • Proporcionar un grado de libertad suficiente para realizar las posibles optimizaciones.
  • Sistemas de representación:

Conversión a forma canónica

En la conversión canónica encontramos que hay optimizaciones previas que tienen un resultado positivo seguro. En este paso debemos encontrar la expresión equivalente de una consulta dada en la que se mejore de alguna manera el rendimiento. Esta expresión equivalente será la FORMA CANONICA de dicha consulta.

Elección de procedimientos de bajo nivel

En la elección de procedimientos de bajo nivel se debe evaluar la consulta previamente transformada, también encontraremos existencia de índices u otras rutas de acceso y la distribución de los valores de los datos almacenados. Luego se realizará un agrupamiento físico de los registros.
  • Un optimizador debe tener algunos procedimientos disponibles para una operación de join tales como:
  • Un procedimiento para el caso en que la condición sea a través de una clave candidata.
  • Un procedimiento para el caso en que el campo de restricción (en alfa unión) esté indexado.
  • Un procedimiento para el caso en que el campo de restricción no esté indexado pero sí agrupados los datos físicamente.

Generación y elección de planes de consulta

Cuando elegimos un plan una de las primeras cosas que debemos tener en cuenta para escogerlo es la estimación de costes. Estos costes dependen de muchos aspectos tales como: el nº de operaciones de entrada/salida del disco requeridas, la utilización de la CPU. Una consulta suele implicar la generación de resultados intermedios, estos resultados estarán directamente relacionados con el número de E/S.


lunes, 22 de octubre de 2012

Diseño de Bases De Datos Distribuidas.

Estrategias de procesamiento de consultas

El procesamiento de consultas tiene varias etapas a seguir para resolver una consulta SQL, las características del modelo relacional permiten que cada motor de base de datos elija su propia representación que, comúnmente, resulta ser el álgebra relacional. La optimización de consultas es, entonces, una de estas etapas.

Existen distintos métodos para optimizar consultas relacionales, sin embargo el enfoque de optimización basada en costos combinado con heurísticas que permitan reducir el espacio de búsqueda de la solución es el método mayormente utilizado por los motores de base de datos relaciones de la actualidad, en todo caso, independiente del método elegido para optimizar la consulta, la salida de este proceso debe ser un plan de ejecución, el cual comúnmente es representado en su forma de árbol relacional.

Arboles de consultas 


Transformaciones equivalentes 

1.-el servidor recive una peticion de un nodo
2.-el servidor es atacado por el acceso concurrente a la base de datos cargada localmente
3.-el servidor muestra un resultado y le da un hilo a cada una de las maquinas nodo de la red local.

Una base de datos es accesada de esta manera la técnica que se utiliza es la de fragmentación de datos que puede ser hibrida, horizontal y vertical.
En esta fragmentación lo que no se quiere es perder la consistencia de los datos, por lo tanto se respetan las formas normales de la base de datos ok.
Bueno para realizar una transformación en la consulta primero desfragmentamos siguiendo los estandares marcados por las reglas formales y posteriormente realizamos el envio y la maquina que recibe es la que muestra el resultado pertinente para el usuario, de esta se puede producir una copia que sera la equivalente a la original.
 

Join

La sentencia join en SQL permite combinar registros de dos o más tablas en una base de datos relacional. En el Lenguaje de Consultas Estructurado (SQL), hay tres tipo de JOIN: interno, externo, y cruzado.
En casos especiales una tabla puede unirse a sí misma, produciendo una auto-combinación, SELF-JOIN.
Matemáticamente, JOIN es composición relacional, la operación fundamental en el álgebra relacional, y generalizando es una función de composición.

Investigacion - Diccionario de Datos

Diccionario de Datos
Un
diccionario de datos
es un conjunto de
metadatos
que contiene las características lógicas y
puntuales de los datos que se van a utilizar en el
sistema que se programa, incluyendo nombre,
descripción, alias, contenido y organización.
Metadatos: Es un término que se refiere a
datos
sobre los propios
datos. Un ejemplo es un folleto
que nos informa sobre el lugar y el tipo de un libro.
Nos está dando datos sobre otros datos.

En un diccionario de datos se encuentra la lista de
todos los elementos que forman parte del flujo de
datos de todo el sistema. Los elementos más
importantes son flujos de datos, almacenes de
datos y procesos. El diccionario de datos guarda los
detalles y descripción de todos estos elementos.

Definiciones:
Una definición de un dato se introduce mediante el
símbolo “=”; en este contexto
El “ = ” se lee como “está definido por”, o “está
compuesto de”, o “significa”.
Para definir un dato completamente, la definición
debe incluir:
El significado del dato en el contexto de la
aplicación. Esto se documenta en forma de
comentario.
La composición del dato, si es que está compuesto
de otros elementos significativos.

Datos elementales:
Son aquellos para los cuales no hay una
descomposición significativa. Por ejemplo, puede
ser que no se requiera descomponer el nombre de
una persona en primer-nombre, apellido-materno y
apellido-paterno; esto depende del contexto del
sistema que se esté modelando.
Cuando se han identificado los datos elementales,
deben ser introducidos en el DD y proveer una
breve descripción que describa el significado del
dato. En el caso de que el dato tenga un nombre
significativo, se puede omitir la descripción, sin
embargo; es importante especificar las unidades de
medida que el dato puede tomar.

Datos opcionales:
Un dato opcional es aquel que puede o no estar
presente como componente de un dato compuesto.
Se caracteriza por estar encerrado entre
paréntesis.
Selección:
Indica que un elemento consiste de exactamente
una opción de un conjunto de alternativas que se
encierran entre corchetes.

Iteración:
Se usa para indicar ocurrencias repetidas de un
componente en un elemento compuesto.
Ejemplo: Orden-de-compra = nombre-cliente +
dirección-de-envío + {artículo} significa que una
orden de compra siempre debe contener un nombre
de cliente, una dirección de envío y cero o más
ocurrencias de un artículo.
Ejemplo 2: Se pueden especificar límites superiores
e inferiores a las iteraciones. Orden-de compra =
nombre-cliente + dirección-de-envío + 1{artículo}10.




lunes, 1 de octubre de 2012

Fragmentacion De Datos


Fragmentacion Vertical,Horizontal Y Mixta

El problema de fragmentación 

El problema de fragmentación se refiere al particionamiento de la información para distribuir cada parte a los diferentes sitios de la red, como se observa en la Figura 3.2. Inmediatamente aparece la siguiente pregunta: ¿cuál es la unidad razonable de distribución?. Se puede considerar que una relación completa es lo adecuado ya que las vistas de usuario son subconjuntos de las relaciones. Sin embargo, el uso completo de relaciones no favorece las cuestiones de eficiencia sobre todo aquellas relacionadas con el procesamiento de consultas.
La otra posibilidad es usar fragmentos de relaciones (sub-relaciones) lo cual favorece la ejecución concurrente de varias transacciones que accesan porciones diferentes de una relación. Sin embargo, el uso de sub-relaciones también presenta inconvenientes. Por ejemplo, las vistas de usuario que no se pueden definir sobre un solo fragmento necesitarán un procesamiento adicional a fin de localizar todos los fragmentos de una vista. Aunado a esto, el control semántico de datos es mucho más complejo ya que, por ejemplo, el manejo de llaves únicas requiere considerar todos los fragmentos en los que se distribuyen todos los registros de la relación. En resumen, el objetivo de la fragmentación es encontrar un nivel de particionamiento adecuado en el rango que va desde tuplas o atributos hasta relaciones completas.

Tipos de fragmentación de datos
Existen tres tipos de fragmentación:
Fragmentación horizontal
Fragmentación vertical
Fragmentación híbrida

3.4.3 Fragmentación vertical
La fragmentación vertical es la subdivisión de atributos en grupos. Los fragmentos se obtienen proyectando la relación global sobre cada grupo. La fragmentación es correcta si cada atributo se mapea en al menos un atributo del fragmento.
Ejemplo 3.5. Considere la siguiente relación global:
EMP( empnum, name, sal, tax, mgrnum, depnum )
una fragmentación vertical de esta relación puede ser definida como:
EMP1 = PJempnum, name, mgrnum, depnum EMP
EMP2 = PJempnum, sal, tax EMP
la reconstrucción de la relación EMP puede ser obtenida como:
EMP = EMP1 (JN empnum) EMP2 porque empnum es una clave de EMP
Fragmentación híbrida
En la que respecto a la fragmentación híbrida, esta consiste en aplicar la fragmentación vertical seguida de la fragmentación horizontal o viceversa.
Ejemplo 3.6. Considere la relación global
EMP( empnum, name, sal, tax, mrgnum, depnum )
Las siguientes son para obtener una fragmentación mixta, aplicando la vertical seguida de la horizontal:
EMP1 = SL depnum <= 10 PJempnum, name, mgrnum, depnum EMP
EMP2 = SL 10 < depnum <= 20 PJempnum, name, mgrnum, depnum EMP
EMP3 = SL depnum > 20 PJempnum, name, mgrnum, depnum EMP
EMP4 = PJ empnum, name, sal, tax EMP
La reconstrucción de la relación EMP es definida por la siguiente expresión:
EMP = UN(EMP1, EMP2, EMP3)JNempnum = empnumPJempnum, sal, tax EMP4
Finalmente, como otro ejemplo considere el siguiente esquema global
EMP(EMPNUM, NAME, SAL, TAX, MGRNUM, DEPNUM)
DEP(DEPNUM, NAME, AREA, MGRNUM)
SUPPLIER(SNUM, NAME, CITY)
SUPPLY(SNUM, PNUM, DEPNUM, QUAN)
Después de aplicar una fragmentación mixta se obtiene el siguiente esquema fragmentado
EMP1 = Sldepnum <= 10 PJempnum, name, mgrnum, depnum (EMP)
EMP2 = SL 10 < depnum <= 20 PJempnum, name, mgrnum, depnum (EMP)
EMP3 = SL depnum > 20 PJempnum, name, mgrnum, depnum (EMP)
EMP4 = PJ empnum, name, sal, tax (EMP)
DEP1 = SL depnum <= 10 (DEP)
DEP2 = SL 10 < depnum <= 20 (DEP)
DEP3 = SL depnum > 20 (DEP)
SUPPLIER1 = SL city == "SF" (SUPPLIER)
SUPPLIER2 = SL city == "LA" (SUPPLIER)
SUPPLY1 = SUPPLYSJsnum == snumSUPPLIER1
SUPPLY2 = SUPPLYSJsnum == snumSUPPLIER2
¨
Fragmentación horizontal
En las siguientes secciones revisaremos de manera más formal la forma de construir los diferentes tipos de fragmentación.
La fragmentación horizontal primaria de una relación se obtiene usando predicados que están definidos en esa relación. La fragmentación horizontal derivada, por otra parte, es el particionamiento de una relación como resultado de predicados que se definen en otra relación.
Para poder construir una fragmentación, es necesario proporcionar información acerca de la base de datos y acerca de las aplicaciones que las utilizan. En primer término, es necesario proporcionar la información acerca del esquema conceptual global. En este sentido es importante dar información acerca de las relaciones que componen a la base de datos, la cardinalidad de cada relación y las dependencias entre relaciones. Por ejemplo, en la Figura 3.4 se presenta un diagrama mostrando el esquema conceptual de la base de datos de ejemplo del capítulo 2.
En segundo lugar se debe proporcionar información acerca de la aplicación que utiliza la base de datos. Este tipo de información es cuantitativa y consiste de los predicados usados en las consultas de usuario.

MySQL


Conectar con una base de datos MySQL remota

 
MySQL tiene algunas particularidades a la hora de realizar una conexión desde un cliente remoto que si no las sabemos nos pueden complicar un poco el acceso a una base de datos MySQL desde una máquina diferente a la que aloja la BD.
Con otras bases de datos, como Oracle o SQL Server, una vez que ningún firewall ni nada por el estilo nos impide acceder desde la máquina cliente a la servidora, con utilizar los datos de acceso de un usuario de base de datos normalmente ya se puede 'entrar'.
Con MySQL, aunque el acceso al puerto, normalmente el 3306, esté abierto, la base de datos puede estar configurada para no dejar pasar conexiones externas, y el resultado es el mismo que si el puerto estuviera cerrado por un firewall:
telnet mysql.dataprix.es 3306
Trying 188.166.233.199...
telnet: connect to address 188.166.233.199: Connection refused
telnet: Unable to connect to remote host
Si se obtiene este resultado conviene consultar el fichero /etc/my.cnf, y comprobar si contiene las variables bind-address oskip-networking.
Si se encuentra skip-networking y no está comentada, hay que editar el fichero y eliminarla, o convertirla en un comentario para que no tenga efecto y se permitan conexiones externas:
#skip-networking
Si se encuentra bind-address=127.0.0.1 o bind-address= localhost también hay que editarlo y cambiar el valor por el de la ip externa desde la que se quiera conectar (sólo se permite una), o por 0.0.0.0 para dejar pasar todas, y después filtrarlas por otros medios (firewall o seguridad a nivel de control de acceso)
bind-address=0.0.0.0
Con esto, después de reiniciar la base de datos, el telnet anterior ya debería aceptar nuestra conexión externa por el puerto 3306

MySQL tiene además un mecanismo de seguridad de control de acceso que tiene en cuenta, aparte del usuario y contraseña, la IP o el dominio de la máquina desde la que se realiza la conexión. Desde el mismo servidor (localhost) normalmente se puede conectar, pero si se accede desde un cliente o servidor externo hay que asegurarse de que la combinación IP/Dominio + Usuario tiene permiso de acceso a la base de datos.
Si hemos pasado la prueba del telnet y al intentar conectar con un usuario/password correcto obtenemos un mensaje de error parecido a este:
Access denied for user 'miuser'@'55.66.77.88' (using password: YES)
Es cuestión de conectar a la base de datos con el usuario administrador, abriendo una sesión en el servidor por ssh, o con phpMyAdmin, por ejemplo, y en la base de datos 'mysql', consultar el valor del campo 'Host' para el 'User' con el que se intenta conectar.
Si el valor es 'localhost', este usuario sólo puede conectar desde el mismo server, por eso se rechaza la conexión remota. Si el valor fuera '%' se podría conectar desde cualquier máquina, y habría que buscar otra razón para el mensaje de error.
Este valor se puede modificar por el dominio o el valor de la ip de la máquina desde la que se quiere conectar, y se pueden utilizar caracteres comodín como % para permitir rangos de ip's.
Para consultar las diferentes opciones, el capítulo Control de acceso, nivel 1: Comprobación de la conexión del manual de referencia de MySQL lo explica detalladamente.
Por ejemplo, para dar acceso y privilegios a 'miuser' desde la ip '55.66.77.88':
GRANT ALL PRIVILEGES ON db.* to miuser@'55.66.77.88' IDENTIFIED BY 'password';
flush privileges;

MySQL


MySQL es un sistema de gestión de bases de datos claramente orientado a la web, y una de los síntomas en su arquitectura ha venido siendo que la creación de los usuarios se realiza en la misma sentencia que el permiso (grant) de acceso a una o varias bases de datos. La orientación de MySQL va cambiando con el tiempo y el uso que se le da a las bases de datos cada vez trasciende más el entorno web, actualmente hay tres formas de crear un usuario:

la forma clásica, con la sentencia GRANT

Utilizando la sentencia GRANT podemos crear un usuario a la par que otorgarle uno o varios privilegios sobre los objetos de una base de datos, o la base de datos completa.
Al encontrarse una sentencia de tipo GRANT, el motor de MySQL revisa si el usuario existe previamente para el contexto que estamos asignándole permisos, y si dicho usuario no está presente en el sistema, lo crea.
No entraré en detalles sobre todas las opciones que nos permite ejecutar la sentencia GRANT, sino solo en las que se refieren a la creación del usuario.
Pongamos un ejemplo, queremos crear el usuario adolfo para la base de datos test:
- Nos conectamos con un usuario que tenga privilegios, root, como propietario de la base de datos, los tiene.
$ mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 17
Server version: 5.0.67 Source distribution
Nos conectamos utilizando -u para indicarle el usuario y si quisieramos indicarle un password, deberiamos poner -p (sin añadirle la contraseña), en este caso la cuenta root, al ser una máquina de desarrollo, está desprotegida.
- Lanzamos la sentencia GRANT, indicando los permisos que otorgamos, la base de datos y los objetos de la misma sobre los que estamos asignando privilegios, el nombre del usuario y el password:
mysql> GRANT SELECT, INSERT ON test.* TO 'adolfo'@'localhost' IDENTIFIED BY 'pass_adolfo';
En este ejemplo permitimos al usuario adolfo que seleccione (SELECT) e inserte (INSERT) en todos los objetos (*) de la base de datos test, además indicamos que el contexto sea la máquina local de la base de datos (localhost), lo que impedirá que el usuario se conecte desde otras máquinas, y finalmente asignamos un password mediante IDENTIFIED BY.
Si quisieramos que el usuario no tuviera un password, deberemos omitir la cláusula IDENTIFIED BY.
En el caso de que el modo SQL del servidor estuviera en NO_AUTO_CREATE_USER, la creación de usuarios no estaría permitida a no ser que tuvieran asignado un password no vacío.
- Una vez hecho esto, podremos conectarnos con nuestro usuario y realizar las acciones para las que hemos asignado permisos:
$ mysql -u adolfo -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 19
Server version: 5.0.67 Source distribution
mysql> use test;
Database changed
mysql> select * from frutas;
+-----------+----------+
| nombre    | color    |
+-----------+----------+
| fresa     | rojo     |
| manzana   | verde    |
| uva       | verde    |
+-----------+----------+
3 rows in set (0,03 sec)
Más detalles sobre la sentencia GRANT y los privilegios disponibles en la documentación de mysql.

la sentencia CREATE USER

A partir de la versión MySQL 5.0.2 existe la posibilidad de crear usuarios sin necesidad de asignarles privilegios, utilizando la sentencia CREATE USER.
Por ejemplo, para crear el usuario fernando:
$ mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 20
Server version: 5.0.67 Source distribution
mysql> CREATE USER 'fernando'@'localhost' IDENTIFIED BY 'fer_pass';
Query OK, 0 rows affected (0,00 sec)
Al igual que con la sentencia GRANT, el contexto 'localhost' define que el usuario solamente se puede conectar desde el servidor de MySQL, y el IDENTIFIED BY define el password del usuario, se puede omitir, para un usuario sin password, siempre que el modo SQL no sea NO_AUTO_CREATE_USER.
Conexión con el usuario, utilizando la opción -p:
$ mysql -u fernando -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 22
Server version: 5.0.67 Source distribution
Los privilegios necesarios para ejecutar la sentencia CREATE USER son CREATE USER o bien INSERT en la base de datos mysql.
El usuario recién creado no tiene privilegio alguno, por lo que deberemos asignarle permisos utilizando sentencias GRANT(esta vez sin la cláusula IDENTIFIED BY).
Más detalles sobre esta sentencia en la documentación de mysql.

modo hardcore: insertando en la tabla users

Este es un método que MySQL no recomienda demasiado, es un poco más complejo que los otros dos, pero va bien a la hora de resolver problemas, como que por ejemplo alguno de las formas anteriores esté dando algún problema extraño.
Para ello es necesario un usuario con privilegio INSERT en la base de datos mysql. También debo decir que se ha de tener mucho cuidado con esta base de datos, ya que contiene toda la información de usuarios y permisos.
Ejemplo de creación del usuario mariano usando INSERT en nuestra base de datos. Nos conectamos con un usuario con privilegios, en este caso root, y seleccionamos la base de datos mysql mediante la sentencia USE.
$ mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 23
Server version: 5.0.67 Source distribution
mysql> use mysql
Database changed
Y después realizamos la sentencia de inserción para añadir nuestro usuario:
mysql> INSERT INTO user VALUES('localhost','mariano',PASSWORD('pass_mariano'),'Y','Y',
'N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N',
'N','N','N','','','','',0,0,0,0);
Query OK, 1 row affected (0,00 sec)
Es necesario llamar a la función PASSWORD() para almacenar el password codificado, en los otros casos, el IDENTIFIED BY se encarga de hacer la codificación.
En este caso se le dan permisos globales de INSERT y SELECT, para saber a qué corresponde cada columna, se puede hacer un DESCRIBE user.
mysql> DESCRIBE user;
+-----------------------+-----------------------------------+------+-----+---------+-------+
| Field                 | Type                              | Null | Key | Default | Extra |
+-----------------------+-----------------------------------+------+-----+---------+-------+
| Host                  | char(60)                          | NO   | PRI |         |       |
| User                  | char(16)                          | NO   | PRI |         |       |
| Password              | char(41)                          | NO   |     |         |       |
| Select_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Insert_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Update_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Delete_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Create_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Drop_priv             | enum('N','Y')                     | NO   |     | N       |       |
| Reload_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Shutdown_priv         | enum('N','Y')                     | NO   |     | N       |       |
(...)
Para asignar privilegios a bases de datos específicas o tablas específicas, se debe usar GRANT.
Utilizando este método, tenemos que forzar que se refresquen las tablas de permisos usando FLUSH PRIVILEGES.
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0,01 sec)
Una vez hecho esto, ya nos podremos conectar:
$ mysql -u mariano -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 28
Server version: 5.0.67 Source distribution
Más información sobre el uso de este método, en comparación con el GRANT, en la documentación de mysql.



Para que un usuario pueda hacer algo más que consultar algunas variables del sistema debe tener algún privilegio. Lo más simple es conceder el privilegio para seleccionar datos de una tabla concreta. Esto se haría así:
La misma sentencia GRANT se usa para añadir privilegios a un usuario existente.
mysql> GRANT SELECT ON prueba.gente TO anonimo;
Query OK, 0 rows affected (0.02 sec)
Esta sentencia concede al usuario 'anonimo' el privilegio de ejecutar sentencias SELECT sobre la tabla 'gente' de la base de datos 'prueba'.
Un usuario que abra una sesión y se identifique como 'anonimo' podrá ejecutar estas sentencias:
mysql> SHOW DATABASES;
+----------+
| Database |
+----------+
| prueba   |
+----------+
1 row in set (0.01 sec)

mysql> USE prueba;
Database changed
mysql> SHOW TABLES;
+------------------+
| Tables_in_prueba |
+------------------+
| gente            |
+------------------+
1 row in set (0.00 sec)

mysql> SELECT * FROM gente;
+----------+------------+
| nombre   | fecha      |
+----------+------------+
| Fulano   | 1985-04-12 |
| Mengano  | 1978-06-15 |
| Tulano   | 2001-12-02 |
| Pegano   | 1993-02-10 |
| Pimplano | 1978-06-15 |
| Frutano  | 1985-04-12 |
+----------+------------+
6 rows in set (0.05 sec)

mysql>
Como se ve, para este usuario sólo existe la base de datos 'prueba' y dentro de esta, la tabla 'gente'. Además, podrá hacer consultas sobre esa tabla, pero no podrá añadir ni modificar datos, ni por supuesto, crear o destruir tablas ni bases de datos.
Para conceder privilegios globales se usa ON *.*, para indicar que los privilegios se conceden en todas las tablas de todas las bases de datos.
Para conceder privilegios en bases de datos se usa ON nombre_db.*, indicando que los privilegios se conceden sobre todas las tablas de la base de datos 'nombre_db'.
Usando ON nombre_db.nombre_tabla, concedemos privilegios de nivel de tabla para la tabla y base de datos especificada.
En cuanto a los privilegios de columna, para concederlos se usa la sintaxis tipo_privilegio (lista_de_columnas), [tipo_privilegio (lista_de_columnas)].
Otros privilegios que se pueden conceder son:
  • ALL: para conceder todos los privilegios.
  • CREATE: permite crear nuevas tablas.
  • DELETE: permite usar la sentencia DELETE.
  • DROP: permite borrar tablas.
  • INSERT: permite insertar datos en tablas.
  • UPDATE: permite usar la sentencia UPDATE.
Para ver una lista de todos los privilegios existentes consultar la sintaxis de la sentencia GRANT.
Se pueden conceder varios privilegios en una única sentencia. Por ejemplo:
mysql> GRANT SELECT, UPDATE ON prueba.gente TO anonimo IDENTIFIED BY 'clave';
Query OK, 0 rows affected (0.22 sec)

mysql>
Un detalle importante es que para crear usuarios se debe tener el privilegio GRANT OPTION, y que sólo se pueden conceder privilegios que se posean.

Revocar privilegios

^
Para revocar privilegios se usa la sentencia REVOKE.
REVOKE priv_type [(column_list)] [, priv_type [(column_list)]] ...
    ON 
    FROM user [, user] ...
La sintaxis es similar a la de GRANT, por ejemplo, para revocar el privilegio SELECT de nuestro usuario 'anonimo', usaremos la sentencia:
mysql> REVOKE SELECT ON prueba.gente FROM anonimo;
Query OK, 0 rows affected (0.05 sec).

Mostrar los privilegios de un usuario

^
Podemos ver qué privilegios se han concedido a un usuario mediante la sentencia SHOW GRANTS. La salida de esta sentencia es una lista de sentencias GRANT que se deben ejecutar para conceder los privilegios que tiene el usuario. Por ejemplo:
mysql> SHOW GRANTS FOR anonimo;
+--------------------------------------------------------------------+
| Grants for anonimo@%                                               |
+--------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'anonimo'@'%' IDENTIFIED BY PASSWORD '*5...' |
| GRANT SELECT ON `prueba`.`gente` TO 'anonimo'@'%'                  |
+--------------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql>

Nombres de usuarios y contraseñas

^
Como podemos ver por la salida de la sentencia SHOW GRANTS, el nombre de usuario no se limita a un nombre simple, sino que tiene dos partes. La primera consiste en un nombre de usuario, en nuestro ejemplo 'anonimo'. La segunda parte, que aparece separada de la primera por el carácter '@' es un nombre de máquina (host). Este nombre puede ser bien el de una máquina, por ejemplo, 'localhost' para referirse al ordenador local, o cualquier otro nombre, o bien una ip.
La parte de la máquina es opcional, y si como en nuestro caso, no se pone, el usuario podrá conectarse desde cualquier máquina. La salida de SHOW GRANTS lo indica usando el comodín '%' para el nombre de la máquina.
Si creamos un usuario para una máquina o conjunto de máquinas determinado, ese usuario no podrá conectar desde otras máquinas. Por ejemplo:
mysql> GRANT USAGE ON * TO anonimo@localhost IDENTIFIED BY 'clave';
Query OK, 0 rows affected (0.00 sec)
Un usuario que se identifique como 'anonimo' sólo podrá entrar desde el mismo ordenador donde se está ejecutando el servidor.
En este otro ejemplo:
mysql> GRANT USAGE ON * TO anonimo@10.28.56.15 IDENTIFIED BY 'clave';
Query OK, 0 rows affected (0.00 sec)
El usuario 'anonimo' sólo puede conectarse desde un ordenador cuyo IP sea '10.28.56.15'.
Aunque asignar una constraseña es opcional, por motivos de seguridad es recomendable asignar siempre una.
La contraseña se puede escribir entre comillas simples cuando se crea un usuario, o se puede usar la salida de la función PASSWORD() de forma literal, para evitar enviar la clave en texto legible.
Si al añadir privilegios se usa una clave diferente en la cláusula IDENTIFIED BY, sencillamente se sustituye la contraseña por la nueva.

Borrar usuarios

^
Para eliminar usuarios se usa la sentencia DROP USER.
No se puede eliminar un usuario que tenga privilegios, por ejemplo:
mysql> DROP USER anonimo;
ERROR 1268 (HY000): Can't drop one or more of the requested users
mysql>
Para eliminar el usuario primero hay que revocar todos sus privilegios:
mysql> SHOW GRANTS FOR anonimo;
+--------------------------------------------------------------------+
| Grants for anonimo@%                                               |
+--------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'anonimo'@'%' IDENTIFIED BY PASSWORD '*5...' |
| GRANT SELECT ON `prueba`.`gente` TO 'anonimo'@'%'                  |
+--------------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql> REVOKE SELECT ON prueba.gente FROM anonimo;
Query OK, 0 rows affected (0.00 sec)

mysql> DROP USER anonimo;
Query OK, 0 rows affected (0.00 sec)

mysql>