MMORPG DB: PL/SQL

Juan Mellado, 31 Mayo, 2008 - 10:19

Una de las cosas que más me llamó la atención cuando estuve buscando información acerca de cómo se organizaban en la práctica algunos MMORPG comerciales fue el hecho de que muchos desarrolladores hacían mención a procedimientos y funciones escritas en (algún tipo de) PL/SQL. A priori no vi ningún sentido en utilizarlos, ya que normalmente el conjunto de operaciones a realizar contra base de datos se limita a la ejecución de unas pocas sentencias SQL en transacciones de muy corta duración. A saber, insertar un objeto en el inventario, actualizar algún tipo de contador de vida, y así sucesivamente. Sentencias pequeñas que afectan a un registro, o a una cantidad muy pequeña de ellos, donde ni siquiera es de esperar que haya grandes consultas, ya que normalmente las tablas maestras se encontrarán en memoria, en algún tipo de cache, y se accederá por su correspondiente ID, o puntero, dependiendo de la implementación concreta de la capa de persistencia. Incluso algunas consultas, como la búsqueda de personajes cercanos al del jugador, tendrán que resolverse manteniendo en memoria diversos tipos de jerarquías con criterios distintos para poder recorrerlas según interese en cada caso. Además de que normalmente las consultas no son precisamente lo que motiva la creación de procedimientos o funciones PL/SQL.

A fin de encontrar cierta justificación a la necesidad del uso masivo de PL/SQL comencé a buscar los beneficios que pudieran desprenderse de su uso, como si fuera yo el que tuviera que justificar su uso y sus posibles contrapartidas.

Por ejemplo, un motivo práctico de primer orden por el que veo útil la utilización de PL/SQL es la reducción del número de accesos y volumen de información intercambiada entre el cliente y el gestor de base de datos. En operaciones muy habituales, como despojar de un objeto a un enemigo vencido (looting), es mejor realizar una única llamada a un procedimiento PL/SQL pasándole tres parámetros como argumento (un ID del personaje, un ID del enemigo y un ID del objeto) que realizar varias llamadas para la ejecución de varias sentencias en SQL (eliminar objeto del inventario del enemigo, insertar objeto en el inventario del personaje, fin de transacción), obviando las comprobaciones previas (comprobar que el enemigo está muerto, comprobar que el personaje tiene derecho a robar el objeto, comprobar que el enemigo tiene el objeto). Muchas veces no es la ejecución de las sentencias SQL individuales lo que más tiempo demora, sino el número total de sentencias que se tienen que ejecutar cada vez. Una actualización que tarde muy poco tiempo puede estar bien dentro de un determinado contexto, pero si ha de ejecutarse mil veces seguidas entonces puede que ya no lo sea. El tiempo que se tarda en establecer conexión con el servidor de base de datos, en autentificar dicha conexión, y en validar la sentencia a ejecutar, es un tiempo que nunca debería despreciarse alegremente. Hay que lograr que con un única conexión con el servidor se actualicen mil registros, en vez de tener que actualizarlos uno a uno con mil llamadas. En este sentido un procedimiento PL/SQL puede ser de gran ayuda. Aunque sin perder de vista otras opciones que ofrezca el gestor, como bulk arrays, que son actualizaciones masivas, generalmente disponibles a través de algún mecanismo propietario, u optimizaciones, como las caches de últimas sentencias SQL ejecutadas, sobre las que no es necesario volver a aplicar el proceso de parser, algo que normalmente va también implícito en el uso de funciones y procedimientos almacenados.

El uso de PL/SQL también tiene la ventaja de encapsular en el servidor todos los accesos a base de datos, evitando tener que embeber sentencias SQL en el resto del código fuente, aunque esto en realidad dependerá bastante de cómo se monte la capa de abstracción correspondiente. Lo que está claro es que todas las aplicaciones clientes podrán usar ese mismo código, evitando tener que repetirlo en cada programa y distribuirlo en librerías que tengan que mantenerse actualizadas. Además, manteniendo todo el código en la parte del servidor se consigue aislar los detalles específicos del funcionamiento de un determinado gestor, de forma que las posibles migraciones que se quieran realizar una vez iniciado el desarrollo, e incluso con el software en producción, sean menos traumáticas. Naturalmente esta última frase no deja de ser una utopía hoy en día. No hay más que echar un vistazo a la documentación de las distintas bases de datos para darse cuenta que cada cual implementa el lenguaje, e incluso varios de ellos, según sus propias reglas, normalmente incompatibles entre los distintos fabricantes. Más allá de la nomenclatura, o sintaxis de declaración, hay muchos detalles que normalmente obligan a programar de una forma u otra el código según el gestor concreto que se esté utilizando. En MySQL el soporte de esta característica es limitado, y en PostgreSQL tiene algunas particularidades como la gestión de excepciones que fuerzan un ROLLBACK.

La ejecución de procedimientos y funciones, al realizarse en el servidor, proporcionan un extra de seguridad. Con una gestión de permisos adecuada, se puede hacer que todos los accesos al modelo por parte de los clientes se realice de forma exclusiva a través de procedimientos y funciones PL/SQL, evitando que tengan acceso directo a las tablas y a como se encuentran definidas y organizadas estas. Es decir, el concepto de "interface" llevado al modelo de base de datos relacional. "Capas de abstracción" (modelo cebolla) es un término que nos encanta utilizar a los informáticos. Naturalmente la contrapartida de este planteamiento es que el servidor de base de datos deberá hacer más trabajo del que ya normalmente le toca, al trasladarle las reglas de negocio que residen habitualmente en el código de los clientes. Por no mencionar el hecho que hacer grandes desarrollos en la parte servidora puede resultar bastante costoso si el gestor no proporciona las facilidades necesarias para la activación de trazas o realizar labores de depuración online.

Llegado este punto, creo que debería estar claro cuales son las ventajas e inconvenientes más importantes del uso de PL/SQL. Y lo mejor que se puede decir a modo de resumen es que no hay un factor decisivo que decante la balanza de forma clara en cuanto a la necesidad de su uso o no. Creo que la única solución será probar ambas alternativas, o una mezcla de ambas, a fin de determinar si el gestor que estemos utilizando marca una diferencia clara, sin dejar de recordar que las características o rendimiento que ofrezca una base de datos podemos no encontrarla en otra.

Probar, medir, y decidir.

¿No encontró lo que buscaba?

Utilice el buscador para encontrar más páginas en esta web o en toda Internet.
 
Web www.inmensia.com
yens (no verificado), 1 Junio, 2008 - 12:51

Yo llevo un buen tiempo utilizando junto con php los procedures, functions y demás posibilidades de mysql, que pensé que no tenían a diferencia de SQL... y es un auténtico lujo, además de que son bastante más rápidas las consultas, tener bien separado la base de datos del resto de la aplicación es un puntazo, sobretodo en aplicaciones web