db-dao.md 22.2 KB
Newer Older
larnu committed
1 2 3 4 5
Objetos de Acceso a Bases de Datos
==================================

> Nota: Esta sección está en desarrollo.

6 7 8 9 10
Yii incluye una capa de acceso a bases de datos basado en el [PDO](http://php.net/manual/es/book.pdo.php) de PHP. La
interfaz de objetos de acceso a bases de datos (DAO) proporciona una API uniforme y soluciona algunas inconsistencias
que existen entre diferentes aplicaciones de bases de datos. Mientras el Active Record proporciona interacciones con
los modelos, y el Constructor de Consultas (Query Builder) ayuda en la composición de consultas dinámicas, DAO es una
manera simple y eficiente para ejecutar SQL en la base de datos. Por lo general, se usará DAO cuando la ejecución de
larnu committed
11 12 13 14 15 16 17 18
la consulta sea muy costosa y/o no se requieran modelos de aplicación y sus correspondientes lógicas de negocio.

De forma predeterminada, Yii soporta los siguientes DBMS (Sistemas de Gestión de Base de Datos):

- [MySQL](http://www.mysql.com/)
- [MariaDB](https://mariadb.com/)
- [SQLite](http://sqlite.org/)
- [PostgreSQL](http://www.postgresql.org/)
19 20
- [CUBRID](http://www.cubrid.org/): versión 9.3 o superior. (Tenga en cuenta que debido al
  [bug](http://jira.cubrid.org/browse/APIS-658) en la extensión PDO de cubrid, los valores entrecomillados no
larnu committed
21 22
  funcionarán, por lo que se necesita CUBRID 9.3 tanto para el cliente como para el servidor)
- [Oracle](http://www.oracle.com/us/products/database/overview/index.html)
23
- [MSSQL](https://www.microsoft.com/en-us/sqlserver/default.aspx): versión 2008 o superior.
larnu committed
24 25 26 27

Configuración
-------------

28 29
Para empezar a interaccionar con la base de datos (usando DAO o de otra forma), se tiene que configurar el componente
de conexión a la base de datos de la aplicación. El DSN (Nombre de Origen de Datos) configura que aplicación de BBDD y
larnu committed
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
que BBDD especifica debe conectar la aplicación:

```php
return [
    // ...
    'components' => [
        // ...
        'db' => [
            'class' => 'yii\db\Connection',
            'dsn' => 'mysql:host=localhost;dbname=mydatabase', // MySQL, MariaDB
            //'dsn' => 'sqlite:/path/to/database/file', // SQLite
            //'dsn' => 'pgsql:host=localhost;port=5432;dbname=mydatabase', // PostgreSQL
            //'dsn' => 'cubrid:dbname=demodb;host=localhost;port=33000', // CUBRID
            //'dsn' => 'sqlsrv:Server=localhost;Database=mydatabase', // MS SQL Server, sqlsrv driver
            //'dsn' => 'dblib:host=localhost;dbname=mydatabase', // MS SQL Server, dblib driver
            //'dsn' => 'mssql:host=localhost;dbname=mydatabase', // MS SQL Server, mssql driver
            //'dsn' => 'oci:dbname=//localhost:1521/mydatabase', // Oracle
            'username' => 'root',
            'password' => '',
            'charset' => 'utf8',
        ],
    ],
    // ...
];
```

56 57
Se puede encontrar más información del formato de la cadena DSN en el
[manual de PHP](http://php.net/manual/es/pdo.construct.php). Además se puede encontrar el listado completo de
larnu committed
58 59
propiedades que se pueden configurar en la clase en [[yii\db\Connection]].

60
Hay que tener en cuenta que si se conecta a una base de datos mediante ODBC, se debe configurar la propiedad
larnu committed
61 62 63 64 65 66 67 68 69 70 71 72
[[yii\db\Connection::driverName]] para que Yii sepa el tipo de bases de datos actual. Por ejemplo,

```php
'db' => [
    'class' => 'yii\db\Connection',
    'driverName' => 'mysql',
    'dsn' => 'odbc:Driver={MySQL};Server=localhost;Database=test',
    'username' => 'root',
    'password' => '',
],
```

73 74
Se puede acceder a la conexión `db` primaria mediante la expresión `\Yii::$app->db`. También se pueden configurar
múltiples conexiones de BBDD en una única aplicación. Simplemente asignándoles diferentes IDs en la configuración de
larnu committed
75 76 77 78 79 80 81 82 83
la aplicación:

```php
return [
    // ...
    'components' => [
        // ...
        'db' => [
            'class' => 'yii\db\Connection',
84
            'dsn' => 'mysql:host=localhost;dbname=mydatabase',
larnu committed
85 86 87 88 89 90
            'username' => 'root',
            'password' => '',
            'charset' => 'utf8',
        ],
        'secondDb' => [
            'class' => 'yii\db\Connection',
91
            'dsn' => 'sqlite:/path/to/database/file',
larnu committed
92 93 94 95 96 97 98 99 100 101 102 103 104
        ],
    ],
    // ...
];
```

Ahora se pueden usar las dos conexiones a la base de datos al mismo tiempo si es necesario:

```php
$primaryConnection = \Yii::$app->db;
$secondaryConnection = \Yii::$app->secondDb;
```

105
Si no se quiere definir la conexión como un [componente de aplicación](structure-application-components.md), se puede
larnu committed
106 107 108 109 110 111 112 113 114 115 116
instanciar directamente:

```php
$connection = new \yii\db\Connection([
    'dsn' => $dsn,
    'username' => $username,
    'password' => $password,
]);
$connection->open();
```

117 118
> Consejo: Si se necesita ejecutar una consulta SQL inmediatamente después de establecer la conexión
  (ej. para establecer la zona horaria (timezone) o el juego de caracteres), se puede añadir el siguiente código en el
larnu committed
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
  archivo de configuración de la aplicación:
>
```php
return [
    // ...
    'components' => [
        // ...
        'db' => [
            'class' => 'yii\db\Connection',
            // ...
            'on afterOpen' => function($event) {
                $event->sender->createCommand("SET time_zone = 'UTC'")->execute();
            }
        ],
    ],
    // ...
];
```

138
Ejecución de Consultas SQL Básicas
larnu committed
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
----------------------------------

Una vez instanciada una conexión a la base de datos, se pueden ejecutar consultas SQL usando [[yii\db\Command]].

### Ejecutando Consultas SELECT

Cuando la consulta que tiene que ser ejecutada devuelve un conjunto de filas, se usará `queryAll`:

```php
$command = $connection->createCommand('SELECT * FROM post');
$posts = $command->queryAll();
```

Cuando la consulta que se ejecute devuelva una única fila, se usará `queryOne`:

```php
$command = $connection->createCommand('SELECT * FROM post WHERE id=1');
$post = $command->queryOne();
```

Cuando la consulta devuelva múltiples filas pero solo una columna, se usará `queryColumn`:

```php
$command = $connection->createCommand('SELECT title FROM post');
$titles = $command->queryColumn();
```

Cuando la consulta solo devuelva un valor escalar, se usará `queryScalar`:

```php
$command = $connection->createCommand('SELECT COUNT(*) FROM post');
$postCount = $command->queryScalar();
```

### Ejecución de Consultas que No Devuelvan Valores

Si el SQL ejecutado no devuelve ningún dato, por ejemplo, INSER, UPDATE, y DELETE, se puede usar el método `execute`:

```php
$command = $connection->createCommand('UPDATE post SET status=1 WHERE id=1');
$command->execute();
```

182
De forma alternativa, se pueden usar los métodos `insert`, `update`, y `delete`. Estos métodos se encargarán de
183
gestionar el entrecomillado de los nombres de las tablas y de las columnas que se usen en la consulta, y solo se
larnu committed
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
tendrá que proporcionar los valores necesarios.

[[Se tiene que poner el enlace de documentación aquí.]]

```php
// INSERT
$connection->createCommand()->insert('user', [
    'name' => 'Sam',
    'age' => 30,
])->execute();

// insertar múltiples filas a la vez
$connection->createCommand()->batchInsert('user', ['name', 'age'], [
    ['Tom', 30],
    ['Jane', 20],
    ['Linda', 25],
])->execute();

// UPDATE
$connection->createCommand()->update('user', ['status' => 1], 'age > 30')->execute();

// DELETE
$connection->createCommand()->delete('user', 'status = 0')->execute();
```

209 210
Entrecomillado de los Nombres de las Tablas y las Columnas <a name="quoting-table-and-column-names"></a>
----------------------------------------------------------
larnu committed
211

212
Para hacer que los nombres de las columnas y las tablas sean seguros para usarse en las consultas, se puede utilizar Yii
larnu committed
213 214 215 216 217 218 219
adecuadamente para que los entrecomille:

```php
$sql = "SELECT COUNT([[$column]]) FROM {{table}}";
$rowCount = $connection->createCommand($sql)->queryScalar();
```

220
En el código anterior, se convertirá `[[$column]]` a un nombre de columna debidamente entrecomillado, mientras que se
larnu committed
221 222
convertirá `{{table}}` a un nombre de tabla debidamente entrecomillado.

223
Hay una variante especial de esta sintaxis especifica para que los nombres de las tablas: `{{%Y}}` añade automáticamente
larnu committed
224 225 226 227 228 229 230
el prefijo de la tabla de la aplicación para proporcionar un valor, si se ha establecido un prefijo de tabla:

```php
$sql = "SELECT COUNT([[$column]]) FROM {{%table}}";
$rowCount = $connection->createCommand($sql)->queryScalar();
```

231
El código anterior dará como resultado una consulta de selección de la tabla `tbl_table`, si se tiene el prefijo de
larnu committed
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
tabla configurado como el siguiente:

```php
return [
    // ...
    'components' => [
        // ...
        'db' => [
            // ...
            'tablePrefix' => 'tbl_',
        ],
    ],
];
```

247
La alternativa es entrecomillar los nombres de las tablas y las columnas manualmente usando
larnu committed
248 249 250 251 252 253 254 255 256 257 258 259
[[yii\db\Connection::quoteTableName()]] y [[yii\db\Connection::quoteColumnName()]]:

```php
$column = $connection->quoteColumnName($column);
$table = $connection->quoteTableName($table);
$sql = "SELECT COUNT($column) FROM $table";
$rowCount = $connection->createCommand($sql)->queryScalar();
```

Uso de Sentencias Preparadas
----------------------------

260 261
Para pasar parámetros seguros a las consultas, se deben usar las sentencias preparadas. Primero, se tiene que crear un
*parámetro de substitución* (placeholder) en una consulta (usando la sintaxis `:placeholder`). Después intercambiar el
larnu committed
262 263 264 265 266 267 268 269
parámetro de substitución por una variable y ejecutar la consulta:

```php
$command = $connection->createCommand('SELECT * FROM post WHERE id=:id');
$command->bindValue(':id', $_GET['id']);
$post = $command->queryOne();
```

270
Otra finalidad de las sentencias preparadas (aparte de mejorar la seguridad) es la habilidad de ejecutar una consulta
larnu committed
271 272 273 274 275 276 277 278 279 280 281 282 283
múltiples veces mientras que sólo se ha preparado una vez:

```php
$command = $connection->createCommand('DELETE FROM post WHERE id=:id');
$command->bindParam(':id', $id);

$id = 1;
$command->execute();

$id = 2;
$command->execute();
```

284 285
Tenga en cuenta que se efectúa la asignación del parámetro de substitución antes de su ejecución, y después se cambia
el valor antes de la siguiente ejecución (normalmente se ejecuta en bucles). La ejecución de consultas con este
larnu committed
286 287 288 289 290
método, puede ser mucho más eficiente que la ejecución de una consulta cada vez.

Realización de Transacciones
----------------------------

291 292 293 294
Cuando se ejecutan múltiples, consultas relacionadas en una secuencia, puede que se tengan que envolver en una
transacción para proteger la integridad de los datos. Las transacciones permiten escribir una serie de consultas de
forma que o todas se ejecutan correctamente o no tendrán ningún efecto. Yii proporciona una interfaz sencilla para
trabajar con transacciones en casos simples pero también para el uso avanzado cuando tengan que definir los niveles de
larnu committed
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
aislamiento.

El siguiente código muestra un patrón simple que debe seguir todo código que utilice consultas transaccionales:

```php
$transaction = $connection->beginTransaction();
try {
    $connection->createCommand($sql1)->execute();
    $connection->createCommand($sql2)->execute();
    // ... executing other SQL statements ...
    $transaction->commit();
} catch(\Exception $e) {
    $transaction->rollBack();
    throw $e;
}
```

312 313 314 315 316 317 318
La primera linea empieza una nueva transacción usando el método
[[yii\db\Connection::beginTransaction()|beginTransaction()]] del objeto de conexión a la base de datos. La transacción
en si misma se representa con el objeto [[yii\db\Transaction]] almacenado en `$transaction`. Nosotros encapsulamos la
ejecución de todas las consultas en un bloque try-catch para poder gestionar los errores. Llamamos a
[[yii\db\Transaction::commit()|commit()]] cuando todo es correcto para efectuar la transacción y si sucede algún error
ejecutamos [[yii\db\Transaction::rollBack()|rollBack()]]. Esto revertirá el efecto de todas las consultas que se hayan
ejecutado dentro de la transacción. Se usa `throw $e` para relanzar la excepción en caso de que nosotros no podamos
larnu committed
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343
gestionar el error y se delega a otro código del gestor de errores de Yii.

Es posible anidar múltiples transacciones si es necesario:

```php
// transacción exterior
$transaction1 = $connection->beginTransaction();
try {
    $connection->createCommand($sql1)->execute();

    // transacción interior
    $transaction2 = $connection->beginTransaction();
    try {
        $connection->createCommand($sql2)->execute();
        $transaction2->commit();
    } catch (Exception $e) {
        $transaction2->rollBack();
    }

    $transaction1->commit();
} catch (Exception $e) {
    $transaction1->rollBack();
}
```

344 345
Tenga en cuanta que el DBMS debe soportar Puntos de Registro (Savepoints) para que funcionen correctamente. El código
anterior, trabajará con cualquier DBMS pero sólo se garantizarán las transacciones que se ejecuten bajo un DBMS
larnu committed
346 347
que las soporte.

348 349 350
Yii también soporta la configuración de [niveles de aislamiento] en las transacciones. Cuando empiece una transacción
se ejecutará con el nivel predeterminado de aislamiento definido por la base de datos. Se puede especificar un nivel
de aislamiento específico cuando se empieza una transacción:
larnu committed
351 352 353 354 355 356 357

```php
$transaction = $connection->beginTransaction(\yii\db\Transaction::REPEATABLE_READ);
```

Yii proporciona cuatro constantes para los niveles de aislamiento más comunes:

358
- [[\yii\db\Transaction::READ_UNCOMMITTED]] - el nivel más bajo, pueden ocurrir lecturas Dirty, lecturas
larnu committed
359 360 361 362 363
  Non-repeatable y Phantoms.
- [[\yii\db\Transaction::READ_COMMITTED]] - evita lecturas Dirty.
- [[\yii\db\Transaction::REPEATABLE_READ]] - evita lecturas Dirty y lecturas Non-repeatable.
- [[\yii\db\Transaction::SERIALIZABLE]] - el nivel más fuerte, evita todos los problemas nombrados anteriormente.

364 365
Se pueden usar las constantes descritas anteriormente aunque también se pueden usar cadenas de texto que representen
la sintaxis que puede ser utilizada en el DBMS seguido de `SET TRANSACTION ISOLATION LEVEL`.  Para postgres podría
larnu committed
366 367
utilizarse, por ejemplo, `SERIALIZABLE READ ONLY DEFERRABLE`.

368 369 370
Tenga en cuenta que algunos DBMS permiten configuraciones de niveles de aislamiento solo a nivel de conexión y por
consiguiente las transacciones pueden obtener el mismo nivel de aislamiento incluso si no se especifica ninguno.
Cuando se usa esta característica, se puede tener que establecer el nivel de aislamiento explícitamente para evitar
larnu committed
371 372
conflictos de configuración. En este momento se ven afectados los DBMS MSSQL y SQLite.

373
> NOTA: SQLite solo soporta dos niveles de aislamiento, por lo que solo se puede usar `READ UNCOMMITTED` y
larnu committed
374 375
`SERIALIZABLE`. El uso de otros niveles causará el lanzamiento de una excepción.

376 377
> Nota: PostgreSQL no permite configurar el nivel de aislamiento antes que la transacción empiece por lo que no se
  puede especificar el nivel de aislamiento directamente cuando empieza la transacción. Se tiene que ejecutar
larnu committed
378 379 380 381
  [[yii\db\Transaction::setIsolationLevel()]] después de que la transacción haya empezado.

[isolation levels]: http://en.wikipedia.org/wiki/Isolation_%28database_systems%29#Isolation_levels

382
Réplicas y División Lectura-Escritura
larnu committed
383 384
-------------------------------------

385 386 387 388 389
Muchos DBMS soportan
[replicación de bases de datos](http://en.wikipedia.org/wiki/Replication_(computing)#Database_replication) para tener
una mejor disponibilidad de la base de datos y un mejor tiempo de respuesta del servidor. Con la replicación de bases
de datos, los datos están replicados en los llamados *servidores maestros* (master servers) y *servidores esclavos*
(slave servers). Todas las escrituras y actualizaciones deben hacerse en el servidor maestro mientras que las lecturas
larnu committed
390 391
se efectuarán en los servidores esclavos.

392
Para aprovechar las ventajas de la replicación de BBDD y lograr una división de lecuta-escritura, se puede configurar
larnu committed
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408
el componente [[yii\db\Connection]] como se muestra a continuación:

```php
[
    'class' => 'yii\db\Connection',

    // configuración para el maestro
    'dsn' => 'dsn for master server',
    'username' => 'master',
    'password' => '',

    // configuración para los esclavos
    'slaveConfig' => [
        'username' => 'slave',
        'password' => '',
        'attributes' => [
409
            // utiliza un tiempo de espera de conexión más pequeña
larnu committed
410 411 412 413 414 415 416 417 418 419 420 421 422 423
            PDO::ATTR_TIMEOUT => 10,
        ],
    ],

    // listado de configuraciones de esclavos
    'slaves' => [
        ['dsn' => 'dsn for slave server 1'],
        ['dsn' => 'dsn for slave server 2'],
        ['dsn' => 'dsn for slave server 3'],
        ['dsn' => 'dsn for slave server 4'],
    ],
]
```

424 425
La configuración anterior especifica una configuración con un único maestro y múltiples esclavos. Uno de los esclavos
se conectará y se usará para ejecutar consultas de lectura mientras que el maestro se usará para realizar consultas de
larnu committed
426 427 428 429 430 431 432 433 434 435 436 437 438
escritura. De este modo la división de lectura-escritura se logra automáticamente con esta configuración, Por ejemplo,

```php
// crea una instancia de Connection usando la configuración anterior
$db = Yii::createObject($config);

// consulta contra uno de los esclavos
$rows = $db->createCommand('SELECT * FROM user LIMIT 10')->queryAll();

// consulta contra el maestro
$db->createCommand("UPDATE user SET username='demo' WHERE id=1")->execute();
```

439 440
> Información: Las consultas realizadas ejecutando [[yii\db\Command::execute()]] se consideran consultas de escritura,
  mientras que todas las demás se ejecutan mediante alguno de los métodos "query" de [[yii\db\Command]] son consultas
larnu committed
441 442
  de lectura. Se puede obtener la conexión de esclavo activa mediante `$db->slave`.

443 444 445 446 447
El componente `Connection` soporta el balanceo de carga y la conmutación de errores entre esclavos. Cuando se realiza
una consulta de lectura por primera vez, el componente `Connection` elegirá un esclavo aleatorio e intentará realizar
una conexión a este. Si está "muerto", se intentará con otro. Si no está disponible ningún esclavo, se conectará al
maestro. Configurando una [[yii\db\Connection::serverStatusCache|server status cache]], se recordarán los servidores
"muertos" por lo que no se intentará volver a conectar a ellos durante
larnu committed
448 449
[[yii\db\Connection::serverRetryInterval|certain period of time]].

450 451
> Información: En la configuración anterior, se especifica un tiempo de espera (timeout) de conexión de 10 segundos
  para cada esclavo. Esto significa que si no se puede conectar a un esclavo en 10 segundos, este será considerado
larnu committed
452 453 454 455 456 457 458 459 460 461 462 463 464
  como "muerto". Se puede ajustar el parámetro basado en el entorno actual.

También se pueden configurar múltiples parámetros para múltiples esclavos. Por ejemplo,

```php
[
    'class' => 'yii\db\Connection',

    // configuracion habitual para los maestros
    'masterConfig' => [
        'username' => 'master',
        'password' => '',
        'attributes' => [
465
            // utilizar un tiempo de espera de conexión más pequeña
larnu committed
466 467 468 469 470 471 472 473 474 475 476 477 478 479 480
            PDO::ATTR_TIMEOUT => 10,
        ],
    ],

    // listado de configuraciones de maestros
    'masters' => [
        ['dsn' => 'dsn for master server 1'],
        ['dsn' => 'dsn for master server 2'],
    ],

    // configuración habitual para esclavos
    'slaveConfig' => [
        'username' => 'slave',
        'password' => '',
        'attributes' => [
481
            // utilizar un tiempo de espera de conexión más pequeña
larnu committed
482 483 484 485 486 487 488 489 490 491 492 493 494 495
            PDO::ATTR_TIMEOUT => 10,
        ],
    ],

    // listado de configuración de esclavos
    'slaves' => [
        ['dsn' => 'dsn for slave server 1'],
        ['dsn' => 'dsn for slave server 2'],
        ['dsn' => 'dsn for slave server 3'],
        ['dsn' => 'dsn for slave server 4'],
    ],
]
```

496 497
La configuración anterior especifica dos maestros y cuatro esclavos. El componente `Connection` también da soporte al
balanceo de carga y la conmutación de errores entre maestros igual que hace con los esclavos. La diferencia es que
larnu committed
498 499
cuando no se encuentra ningún maestro disponible se lanza una excepción.

500 501 502
> Nota: cuando se usa la propiedad [[yii\db\Connection::masters|masters]] para configurar uno o múltiples maestros, se
  ignorarán todas las otras propiedades que especifiquen una conexión de base de datos
  (ej. `dsn`, `username`, `password`), junto con el mismo objeto `Connection`.
larnu committed
503

504
Las conexiones usan la conexión de maestro de forma predeterminada. Y todas las operaciones de BBDD que estén dentro
larnu committed
505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522
de una transacción, usaran la conexión de maestro. Por ejemplo,

```php
// la transacción empieza con la conexión al maestro
$transaction = $db->beginTransaction();

try {
    // las dos consultas se ejecutan contra el maestro
    $rows = $db->createCommand('SELECT * FROM user LIMIT 10')->queryAll();
    $db->createCommand("UPDATE user SET username='demo' WHERE id=1")->execute();

    $transaction->commit();
} catch(\Exception $e) {
    $transaction->rollBack();
    throw $e;
}
```

523
Si se quiere empezar la conexión con una conexión a un esclavo, se debe hacer explícitamente como se muestra a
larnu committed
524 525 526 527 528 529
continuación:

```php
$transaction = $db->slave->beginTransaction();
```

530
A veces, se puede querer forzar el uso de una conexión maestra para realizar una consulta de lectura. Se puede lograr
larnu committed
531 532 533 534 535 536 537 538
usando el método `useMaster()`:

```php
$rows = $db->useMaster(function ($db) {
    return $db->createCommand('SELECT * FROM user LIMIT 10')->queryAll();
});
```

539
También se puede utilizar directamente estableciendo `$db->enableSlaves` a `false` para que se redirijan todas las
larnu committed
540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562
consultas a la conexión de maestro.

Trabajar con Esquemas de Bases de Datos
---------------------------------------

### Obtención de la información del esquema

Se puede obtener una instancia de [[yii\db\Schema]] como se muestra a continuación:

```php
$schema = $connection->getSchema();
```

Contiene una serie de métodos que permiten obtener información varia acerca de la base de datos:

```php
$tables = $schema->getTableNames();
```

Para hacer referencia al esquema entero, se puede revisar [[yii\db\Schema]].

### Modificación de esquemas

563
Aparte de consultas SQL básicas, [[yii\db\Command]] contiene un conjunto de métodos que permiten modificar el esquema
larnu committed
564 565 566 567 568 569 570 571 572 573 574
de la base de datos:

- createTable, renameTable, dropTable, truncateTable
- addColumn, renameColumn, dropColumn, alterColumn
- addPrimaryKey, dropPrimaryKey
- addForeignKey, dropForeignKey
- createIndex, dropIndex

Que pueden usarse como se muestra a continuación:

```php
575
// CREAR TABLA
larnu committed
576 577 578 579 580 581 582 583
$connection->createCommand()->createTable('post', [
    'id' => 'pk',
    'title' => 'string',
    'text' => 'text',
]);
```

Para la referencia completa, se puede revisar [[yii\db\Command]].