Ver índice de contenidos del libro

8.2. Esquema de base de datos de Symfony

Para crear el modelo de objetos de datos que utiliza Symfony, se debe traducir el modelo relacional de la base de datos a un modelo de objetos de datos. Para realizar ese mapeo o traducción, el ORM necesita una descripción del modelo relacional, que se llama "esquema" schema). En el esquema se definen las tablas, sus relaciones y las características de sus columnas.

La sintaxis que utiliza Symfony para definir los esquemas hace uso del formato YAML. Los archivos schema.yml deben guardarse en el directorio miproyecto/config/.

Nota Symfony también puede trabajar con el formato nativo de los esquemas en Propel, que está basado en XML. Más adelante en este capítulo se explican los detalles en la sección "Más allá del schema.yml: schema.xml".

8.2.1. Ejemplo de esquema

¿Cómo se traduce la estructura de una base de datos a un esquema? La mejor forma de entenderlo es mediante un ejemplo. En el ejemplo se supone que se tiene una base de datos de un blog con dos tablas: blog_article y blog_comment, con la estructura que se muestra en la figura 8-1.

Estructura de tablas de la base de datos del blog

Figura 8.1 Estructura de tablas de la base de datos del blog

En este caso, el archivo schema.yml debería ser el del listado 8-3.

Listado 8-3 - Ejemplo de schema.yml

propel:
  blog_article:
    _attributes: { phpName: Article }
    id:
    title:       varchar(255)
    content:     longvarchar
    created_at:
  blog_comment:
    _attributes: { phpName: Comment }
    id:
    article_id:
    author:      varchar(255)
    content:     longvarchar
    created_at:

Observa como el nombre de la propia base de datos (blog) no aparece en el archivo schema.yml. En su lugar, la base de datos se describe bajo el nombre de una conexión (propel en el ejemplo anterior). El motivo es que las opciones de conexión con la base de datos pueden depender del entorno en el que se está ejecutando la aplicación. Si se accede a la aplicación en el entorno de desarrollo, es posible que se acceda a la base de datos de desarrollo (por ejemplo blog_dev) pero con el mismo esquema que en la base de datos de producción. Las opciones de conexión con la base de datos se especifican en el archivo databases.yml, que se describe más adelante en este capítulo en la sección "Conexiones con la base de datos". El esquema no contiene ningún tipo de opción para la conexión a la base de datos, solo el nombre de la conexión, para mantener la abstracción de la base de datos.

8.2.2. Sintaxis básica de los esquemas

En el archivo schema.yml, la primera clave representa el nombre de la conexión. Puede contener varias tablas, cada una con varias columnas. Siguiendo la sintaxis de YAML, las claves terminan con dos puntos (:) y la estructura se define mediante la indentación con espacios, no con tabuladores.

Cada tabla puede definir varios atributos, incluyendo el atributo phpName (que es el nombre de la clase PHP que será generada para esa tabla). Si no se menciona el atributo phpName para una tabla, Symfony crea una clase con el mismo nombre que la tabla al que se aplica las normas del camelCase.

Truco La convención camelCase elimina los guiones bajos de las palabras y pasa a mayúsculas la primera letra de cada palabra. Las versiones camelCase por defecto de blog_article y blog_comment son BlogArticle y BlogComment. El nombre de esta convención para generar nombres viene del aspecto de las mayúsculas en una palabra larga, parecido a las jorobas de un camello.

Las tablas contienen columnas y el valor de las columnas se puede definir de 3 formas diferentes:

  • Si no se indica nada, Symfony intenta adivinar los atributos más adecuados para la columna en función de su nombre y de una serie de convenciones que se explican en la sección "Columnas vacías" un poco más adelante en este Capítulo. Por ejemplo, en el listado 8-3 no es necesario definir la columna id. Symfony por defecto la trata como de tipo entero integer), cuyo valor se auto-incrementa y además, clave principal de la tabla. En la tabla blog_comment, la columna article_id se trata como una clave externa a la tabla blog_article (las columnas que acaban en _id se consideran claves externas, y su tabla relacionada se determina automáticamente en función de la primera parte del nombre de la columna). Las columnas que se llaman created_at automáticamente se consideran de tipo timestamp. Para este tipo de columnas, no es necesario definir su tipo. Esta es una de las razones por las que es tan fácil crear archivos schema.yml.
  • Si sólo se define un atributo, se considera que es el tipo de columna. Symfony entiende los tipos de columna habituales: boolean, integer, float, date, varchar(tamaño), longvarchar (que se convierte, por ejemplo, en tipo text en MySQL), etc. Para contenidos de texto de más de 256 caracteres, se utiliza el tipo longvarchar, que no tiene tamaño definido (pero que no puede ser mayor que 65KB en MySQL). Los tipos date y timestamp tienen las limitaciones habituales de las fechas de Unix y no pueden almacenar valores anteriores al 1 de Enero de 1970. Como puede ser necesario almacenar fechas anteriores (por ejemplo para las fechas de nacimiento), existe un formato de fechas "anteriores a Unix" que son bu_date and bu_timestamp.
  • Si se necesitan definir otros atributos a la columna (por ejemplo su valor por defecto, si es obligatorio o no, etc.), se indican los atributos como pares clave: valor. Esta sintaxis avanzada del esquema se describe más adelante en este capítulo.

Las columnas también pueden definir el atributo phpName, que es la versión modificada de su nombre según las convenciones habituales (Id, Title, Content, etc) y que normalmente no es necesario redefinir.

Las tablas también pueden definir claves externas e índices de forma explícita, además de incluir definiciones específicas de su estructura para ciertas bases de datos. En la sección "Sintaxis avanzada del esquema" se detallan estos conceptos.