Tutorial de SQL
![]()
Qué es SQL
Las aplicaciones en red son cada día más numerosas y versátiles. En muchos
casos, el esquema básico de operación es una serie de scripts que rigen el
comportamiento de una base de datos.
Debido a la diversidad de lenguajes y de bases de datos existentes, la manera de comunicar
entre unos y otras sería realmente complicada a gestionar de no ser por la existencia de
estándares que nos permiten el realizar las operaciones básicas de una forma universal.
Es de eso de lo que trata el Structured Query Language que no es mas que un lenguaje
estándar de comunicación con bases de datos. Hablamos por tanto de un lenguaje
normalizado que nos permite trabajar con cualquier tipo de lenguaje (ASP o PHP) en
combinación con cualquier tipo de base de datos (MS Access, SQL Server, MySQL...).
El hecho de que sea estándar no quiere decir que sea idéntico para cada base de datos.
En efecto, determinadas bases de datos implementan funciones específicas que no tienen
necesariamente que funcionar en otras.
Aparte de esta universalidad, el SQL posee otras dos características muy apreciadas. Por
una parte, presenta una potencia y versatilidad notables que contrasta, por otra, con su
accesibilidad de aprendizaje.
Este manual pretende dar a conocer las operaciones básicas que se pueden realizar con SQL
y que tienen una aplicación directa con la creación de aplicaciones en red sin
profundizar más de lo estrictamente necesario. Se busca crear un manual de referencia
práctico y aplicado.
Tipos de campo
Una base de datos esta compuesta de tablas donde almacenamos registros catalogados en
función de distintos campos (atributos).
Un aspecto previo a considerar es la naturaleza de los valores que introducimos en esos
campos. Dado que una base de datos trabaja con todo tipo de informaciones, es importante
especificarle qué tipo de valor le estamos introduciendo de manera a, por un lado,
facilitar la búsqueda posteriormente y por otro, optimizar los recursos de memoria.
Cada base de datos introduce tipos de valores de campo que no necesariamente están
presentes en otras. Sin embargo, existe un conjunto de tipos que están representados en
la totalidad de estas bases. Estos tipos comunes son los siguientes:
| Alfanuméricos | Contienen cifras y letras. Presentan una longitud limitada (255 caracteres) |
| Numéricos | Existen de varios tipos, principalmente, enteros (sin decimales) y reales (con decimales). |
| Booleanos | Poseen dos formas: Verdadero y falso (Sí o No) |
| Fechas | Almacenan fechas facilitando posteriormente su explotación. Almacenar fechas de esta forma posibilita ordenar los registros por fechas o calcular los días entre una fecha y otra... |
| Memos | Son campos alfanuméricos de longitud ilimitada. Presentan el inconveniente de no poder ser indexados (veremos más adelante lo que esto quiere decir). |
| Autoincrementables | Son campos numéricos enteros que incrementan en una unidad su valor para cada registro incorporado. Su utilidad resulta más que evidente: Servir de identificador ya que resultan exclusivos de un registro. |
Añadir un nuevo registro
Los registros pueden ser introducidos a partir de sentencias que emplean la instrucción
Insert.
La sintaxis utilizada es la siguiente:
Insert Into nombre_tabla (nombre_campo1, nombre_campo2,...) Values (valor_campo1,
valor_campo2...)
Un ejemplo sencillo a partir de nuestra tabla modelo es la introducción de un nuevo
cliente lo cual se haría con una instrucción de este tipo:
Insert Into clientes (nombre, apellidos, direccion, poblacion, codigopostal, email,
pedidos) Values ('Perico', 'Palotes', 'Percebe n°13', 'Lepe', '123456',
'buceo@anep.edu.uy', 33)
Como puede verse, los campos no numéricos o booleanos van delimitados por apostrofes: '.
También resulta interesante ver que el código postal lo hemos guardado como un campo no
numérico. Esto es debido a que en determinados paises (Inglaterra p.e.) los codigos
postales contienen también letras.
Por supuesto, no es imprescindible rellenar todos los campos del registro. Eso sí, puede
ser que determinados campos sean necesarios. Estos campos necesarios pueden ser definidos
cuando construimos nuestra tabla mediante la base de datos.
Resulta muy interesante, ya veremos más adelante el por qué, el introducir durante la
creación de nuestra tabla un campo autoincrementable que nos permita asignar un único
número a cada uno de los registros. De este modo, nuestra tabla clientes presentaría
para cada registro un número exclusivo del cliente el cual nos será muy util cuando
consultemos varias tablas simultáneamente.
Borrar un registro
Para borrar un registro nos servimos de la instrucción Delete. En este caso debemos
especificar cual o cuales son los registros que queremos borrar. Es por ello necesario
establecer una selección que se llevara a cabo mediante la cláusula Where.
La forma de seleccionar se verá detalladamente en capítulos posteriores. Por ahora nos
contentaremos de mostrar cuál es el tipo de sintaxis utilizado para efectuar estas
supresiones:
Delete From nombre_tabla Where condiciones_de_selección
Si queremos por ejemplo borrar todos los registros de los clientes que se llamen Perico lo
haríamos del siguiente modo:
Delete From clientes Where nombre='Perico'
Hay que tener cuidado con esta instrucción ya que si no especificamos una condición con
Where, lo que estamos haciendo es borrar toda la tabla:
Delete From clientes
Actualizar un registro
Update es la instrucción que nos sirve para modificar nuestros registros. Como para el
caso de Delete, necesitamos especificar por medio de Where cuáles son los registros en
los que queremos hacer efectivas nuestras modificaciones. Además, obviamente, tendremos
que especificar cuáles son los nuevos valores de los campos que deseamos actualizar. La
sintaxis es de este tipo:
Update nombre_tabla Set nombre_campo1 = valor_campo1, nombre_campo2 = valor_campo2,...
Where condiciones_de_selección
Un ejemplo aplicado:
Update clientes Set nombre='José' Where nombre='Pepe'
Mediante esta sentencia cambiamos el nombre Pepe por el de José en todos los registros
cuyo nombre sea Pepe.
Aquí también hay que ser cuidadoso de no olvidarse de usar Where, de lo contrario,
modificaríamos todos los registros de nuestra tabla.
Selección de tablas I
La selección total o parcial de una tabla se lleva a cabo mediante la instrucción
Select. En dicha selección hay que especificar:
-Los campos que queremos seleccionar
-La tabla en la que hacemos la selección
En nuestra tabla modelo de clientes podríamos hacer por ejemplo una selección del nombre
y dirección de los clientes con una instrucción de este tipo:
Select nombre, dirección From clientes
Si quisiésemos seleccionar todos los campos, es decir, toda la tabla,
podríamos utilizar el comodín * del siguiente modo:
Select * From clientes
Resulta también muy útil el filtrar los registros mediante condiciones que vienen
expresadas después de la cláusula Where. Si quisiésemos mostrar los
clientes de una determinada ciudad usaríamos una expresión como esta:
Select * From clientes Where poblacion Like 'Madrid'
Además, podríamos ordenar los resultados en función de uno o varios de
sus campos. Para este ultimo ejemplo los podríamos ordenar por nombre así:
Select * From clientes Where poblacion Like 'Madrid' Order By nombre
Teniendo en cuenta que puede haber más de un cliente con el mismo nombre, podríamos dar
un segundo criterio que podría ser el apellido:
Select * From clientes Where poblacion Like 'Madrid' Order By nombre, apellido
Si invirtiésemos el orden « nombre,apellido » por « apellido, nombre », el resultado
sería distinto. Tendríamos los clientes ordenados por apellido y aquellos que tuviesen
apellidos idénticos se subclasificarían por el nombre.
Es posible también clasificar por orden inverso. Si por ejemplo
quisiésemos ver nuestros clientes por orden de pedidos realizados teniendo a los mayores
en primer lugar escribiríamos algo así:
Select * From clientes Order By pedidos Desc
Una opción interesante es la de efectuar selecciones sin coincidencia.
Si por ejemplo buscásemos el saber en qué ciudades se encuentran nuestros clientes sin
necesidad de que para ello aparezca varias veces la misma ciudad usaríamos una sentencia
de esta clase:
Select Distinct poblacion From clientes Order By poblacion
Así evitaríamos ver repetido Madrid tantas veces como clientes tengamos en esa
población.
Selección de tablas II
Hemos querido compilar a modo de tabla ciertos operadores que pueden resultar útiles en
determinados casos. Estos operadores serán utilizados después de la cláusula Where y
pueden ser combinados hábilmente mediante paréntesis para optimizar
nuestra selección a muy altos niveles.
| Operadores matemáticos: | |
|---|---|
| > | Mayor que |
| < | Menor que |
| >= | Mayor o igual que |
| <= | Menor o igual que |
| <> | Distinto |
| = | Igual |
| Operadores lógicos |
|---|
| And |
| Or |
| Not |
| Otros operadores | |
|---|---|
| Like | Selecciona los registros cuyo valor de campo se asemeje, no teniendo en cuenta mayúsculas y minúsculas. |
| In y Not In | Da un conjunto de valores para un campo para los cuales la condición de selección es (o no) valida |
| Is Null y Is Not Null | Selecciona aquellos registros donde el campo especificado esta (o no) vacío. |
| Between...And | Selecciona los registros comprendidos en un intervalo |
| Distinct | Selecciona los registros no coincidentes |
| Desc | Clasifica los registros por orden inverso |
| Comodines | |
|---|---|
| * | Sustituye a todos los campos |
| % | Sustituye a cualquier cosa o nada dentro de una cadena |
| _ | Sustituye un solo carácter dentro de una cadena |
Veamos a continuación aplicaciones practicas de estos operadores.
En esta sentencia seleccionamos todos los clientes de Madrid cuyo nombre no es Pepe. Como
puede verse, empleamos Like en lugar de = simplemente
para evitar inconvenientes debido al empleo o no de mayúsculas.
Select * From clientes Where poblacion Like 'madrid' And Not
nombre Like 'Pepe'
Si quisiéramos recoger en una selección a los clientes de nuestra tabla cuyo apellido
comienza por A y cuyo número de pedidos esta comprendido entre 20 y 40:
Select * From clientes Where apellidos like 'A%' And pedidos Between
20 And 40
El operador In, lo veremos más adelante, es muy práctico para consultas
en varias tablas. Para casos en una sola tabla es empleado del siguiente modo:
Select * From clientes Where poblacion In ('Madrid','Barcelona','Valencia')
De esta forma seleccionamos aquellos clientes que vivan en esas tres ciudades.
Selección de tablas III
Una base de datos puede ser considerada como un
conjunto de tablas. Estas tablas en muchos casos están relacionadas entre ellas y se
complementan unas con otras.
Refiriéndonos a nuestro clásico ejemplo de una base de datos para una aplicación de
e-comercio, la tabla clientes de la que hemos estado hablando puede estar perfectamente
coordinada con una tabla donde almacenamos los pedidos realizados por cada cliente. Esta
tabla de pedidos puede a su vez estar conectada con una tabla donde almacenamos los datos
correspondientes a cada artículo del inventario.
De este modo podríamos fácilmente obtener informaciones contenidas en esas tres tablas
como puede ser la designación del artículo más popular en una determinada región donde
la designación del artículo sería obtenida de la tabla de artículos, la popularidad
(cantidad de veces que ese artículo ha sido vendido) vendría de la tabla de pedidos y la
región estaría comprendida obviamente en la tabla clientes.
Este tipo de organización basada en múltiples tablas conectadas nos permite trabajar con
tablas mucho más manejables a la vez que nos evita copiar el mismo campo en varios sitios
ya que podemos acceder a él a partir de una simple llamada a la tabla que lo contiene.
En este capítulo veremos como, sirviéndonos de lo aprendido hasta ahora, podemos
realizar fácilmente selecciones sobre varias tablas. Definamos antes de nada las
diferentes tablas y campos que vamos a utilizar en nuestros ejemplos:
| Tabla de clientes | |
|---|---|
| Nombre campo | Tipo campo |
| id_cliente | Numérico entero |
| nombre | Texto |
| apellidos | Texto |
| direccion | Texto |
| poblacion | Texto |
| codigopostal | Texto |
| telefono | Numérico entero |
| Texto | |
| Tabla de pedidos | |
|---|---|
| Nombre campo | Tipo campo |
| id_pedido | Numérico entero |
| id_cliente | Numérico entero |
| id_articulo | Numérico entero |
| fecha | Fecha |
| cantidad | Numérico entero |
| Tabla de artículos | |
|---|---|
| Nombre campo | Tipo campo |
| id_articulo | Numérico entero |
| titulo | Alfanumérico |
| autor | Alfanumérico |
| editorial | Alfanumérico |
| precio | Numérico real |
Estas tablas pueden ser utilizadas simultáneamente para extraer
informaciones de todo tipo. Supongamos que queremos enviar un mailing a todos aquellos que
hayan realizado un pedido ese mismo día. Podríamos escribir algo así:
Select clientes.apellidos, clientes.email From clientes,pedidos Where
pedidos.fecha like '25/02/00' And pedidos.id_cliente= clientes.id_cliente
Como puede verse esta vez, después de la cláusula From, introducimos el nombre de las
dos tablas de donde sacamos las informaciones. Además, el nombre de cada campo va
precedido de la tabla de provenencia separados ambos por un punto. En los campos que
poseen un nombre que solo aparece en una de las tablas, no es necesario especificar su
origen aunque a la hora de leer la sentencia puede resultar más claro el precisarlo. En
este caso el campo fecha podría haber sido designado como "fecha" en lugar de
"pedidos.fecha".
Veamos otro ejemplo más para consolidar estos nuevos conceptos. Esta vez queremos ver el
título del libro correspondiente a cada uno de los pedidos realizados:
Select pedidos.id_pedido, articulos.titulo From pedidos, articulos Where
pedidos.id_articulo=articulos.id_articulo
En realidad la filosofía continua siendo la misma que para la consulta de una única
tabla.
Selección de tablas IV
Además de los criterios hasta ahora explicados para realizar las consultas en tablas, SQL
permite también aplicar un conjunto de funciones predefinidas. Estas funciones, aunque
básicas, pueden ayudarnos en algunos momentos a expresar nuestra selección de una manera
más simple sin tener que recurrir a operaciones adicionales por parte del script que
estemos ejecutando.
Algunas de estas funciones son representadas en la tabla siguiente :
| Función | Descripción |
|---|---|
| Sum(campo) | Calcula la suma de los registros del campo especificado |
| Avg(Campo) | Calcula la media de los registros del campo especificado |
| Count(*) | Nos proporciona el valor del numero de registros que han sido seleccionados |
| Max(Campo) | Nos indica cual es el valor máximo del campo |
| Min(Campo) | Nos indica cual es el valor mínimo del campo |
Dado que el campo de la función no existe en la base de datos, sino que lo estamos
generando virtualmente, esto puede crear inconvenientes cuando estamos trabajando con
nuestros scripts a la hora de tratar su valor y su nombre de campo. Es por ello que el
valor de la función ha de ser recuperada a partir de un alias que
nosotros especificaremos en la sentencia SQL a partir de la instrucción AS.
La cosa podría quedar así:
Select Sum(total) As suma_pedidos From pedidos
A partir de esta sentencia calculamos la suma de los valores de todos los pedidos
realizados y almacenamos ese valor en un campo virtual llamado suma_pedidos que podrá ser
utilizado como cualquier otro campo por nuestras paginas dinámicas.
Por supuesto, todo lo visto hasta ahora puede ser aplicado en este tipo de funciones de
modo que, por ejemplo, podemos establecer condiciones con la cláusula Where construyendo
sentencias como esta:
Select Sum(cantidad) as suma_articulos From pedidos Where id_articulo=6
Esto nos proporcionaría la cantidad de ejemplares de un determinado libro que han
sido vendidos.
Otra propiedad interesante de estas funciones es que permiten realizar operaciones
con varios campos dentro de un mismo paréntesis:
Select Avg(total/cantidad) From pedidos
Esta sentencia da como resultado el precio medio al que se están vendiendo los
libros. Este resultado no tiene por qué coincidir con el del precio
medio de los libros presentes en el inventario, ya que, puede ser que la gente
tenga tendencia a comprar los libros caros o los baratos:
Select Avg(precio) as precio_venta From articulos
Una cláusula interesante en el uso de funciones es Group By. Esta cláusula nos permite
agrupar registros a los cuales vamos a aplicar la función. Podemos por ejemplo calcular
el dinero gastado por cada cliente:
Select id_cliente, Sum(total) as suma_pedidos From pedidos Group By id_cliente
O saber el numero de pedidos que han realizado:
Select id_cliente, Count(*) as numero_pedidos From pedidos Group By id_cliente
Las posibilidades como vemos son numerosas y pueden resultar prácticas. Todo queda ahora
a disposición de nuestras ocurrencias e imaginación.
Optimizar prestaciones I
Las bases de datos (BD) cuanto más extensas requieren una mayor atención a la hora de
organizar sus contenidos. Cuando se trabaja con tablas de miles o decenas de miles de
registros la búsqueda de un determinado dato puede resultar un proceso largo que
ralentiza enormemente la creación de nuestra página.
Es por ello importante tener en cuenta una serie de aspectos indispensables para el mejor
funcionanmiento de la base.
Gestión y elección de los índices
Los índices son campos elegidos arbitrariamente por el constructor de la BD que permiten
la búsqueda a partir de dicho campo a una velocidad notablemente superior. Sin embargo,
esta ventaja se ve contrarrestada por el hecho de ocupar mucha más memoria (el doble más
o menos) y de requerir para su inserción y actualización un tiempo de proceso superior.
Evidentemente, no podemos indexar todos los campos de una tabla extensa
ya que doblamos el tamaño de la BD. Igualmente, tampoco sirve de mucho el indexar todos
los campos en una tabla pequeña ya que las selecciones pueden efectuarse rápidamente de
todos modos.
Un caso en el que los índices pueden resultar muy útiles es cuando realizamos peticiones
simultáneas sobre varias tablas. En este caso, el proceso de selección puede acelerarse
sensiblemente si indexamos los campos que sirven de nexo entre las dos tablas.
En el ejemplo de nuestra librería virtual estos campos serían id_cliente e id_articulo.
Los índices pueden resultar contraproducentes si los introducimos sobre campos triviales
a partir de los cuales no se realiza ningún tipo de petición ya que, además del
problema de memoria ya mencionado, estamos ralentizando otras tareas de la base de datos
como son la edición, inserción y borrado. Es por ello que vale la pena pensarselo dos
veces antes de indexar un campo que no sirve de criterio para búsquedas de los
internautas y que es usado con muy poca frecuencia por razones de mantenimiento.
Gestión de los nexos entre tablas
El enlace entre tablas es uno de los puntos más peliagudos y que puede llevar a la
absoluta ralentización de la base de datos a causa "pequeños" detalles que
resultan ser fatales.
Imaginemos que trabajamos con una pequeña BD constituida por dos tablas de 1000 registros
cada una. Imaginemos ahora una selección simultánea en la que imponemos la condición de
que el valor un campo de la primera sea igual a de una segunda, algo que se realiza con
mucha frecuencia. En este tipo de casos, la BD leerá y comparará cada valor de campo de
una con cada valor de campo de la otra. Esto representaría un millón de lecturas. Este
hecho podría agravarse si consultamos una tercera tabla al mismo tiempo y podría llegar
a ser catastrófico si tenemos en cuenta que la BD esta siendo consultada por varios
internautas al mismo tiempo.
Para evitar situaciones de colapso, es necesario indexar cada uno de los campos
que sirven de enlace entre esas tablas. En el ejemplo de nuestra librería
virtual, ya lo hemos dicho, estos campos serían id_cliente e id_articulo. Además,
resulta también de vital importancia el definir esos campos de una forma
estrictamente idéntica en cada una de las tablas, es decir, el campo ha de ser
de la misma naturaleza y características. No vale definirlo como real en una tabla y
entero en otra o cambiar la longitud máxima para los alfanuméricos o que en una tabla
sea de longitud constante y en otra variable...
El gestionar inteligentemente estos aspectos puede solucionarnos muchos quebraderos de
cabeza y permitir a los internautas navegar más agradablemente por nuestro sitio.
Optimizar prestaciones II
Gestion de los campos
Ya hemos comentado por encima los diferentes tipos de campo existentes en una base de
datos. La elección del tipo de campo apropiado para cada caso puede ayudarnos también a
optimizar el tamaño y rapidez de nuestra base de datos.
La preguntas que hay que hacerse a la hora de elegir la naturaleza y dimensiones del campo
son:
-¿Qué tipo de dato voy a almacenar en el campo? Números, texto, fechas...
-¿Cuál es el tamaño máximo que espero que pueda alcanzar alguno de los
registros del campo?
Hay que tener en cuenta que cuanto más margen le demos al valor máximo del campo, más
aumentará el tamaño de nuestra base de datos y más tiempo tardara en realizar las
consultas. Además, el factor tamaño puede verse agravado si estamos definiendo un campo
indexado, para los cuales, el espacio ocupado es aproximadamente del doble.
Un consejo práctico es que las fechas sean almacenadas en formato de fecha ya que ello
nos permite reducir el espacio que ocupan en memoria de más del doble y por otro lado,
podremos aprovechar las prestaciones que SQL y nuestro lenguaje de servidor nos ofrecen.
Podremos calcular la diferencia de días entre dos fechas, ordenar los registros por
fecha, mostrar los registros comprendidos en un intervalo de tiempo...
Existe la posibilidad para los campos de texto de fijar una cierta longitud para el campo
o dejar que cada registro tenga una longitud variable en función del número de
carácteres que posea. Elegir campos de longitud variable nos puede ayudar a optimizar los
recursos de memoria de la BD, no obstante, es un arma de doble filo ya que las consultas
se realizan más lentamente puesto que obligamos a la tabla a establecer cuál es el
tamaño de cada registro que se está comparando en lugar de saberlo de antemano. Es por
tanto aconsejable, para los campos indexados de pequeño tamaño, atribuirles una longitud
fija.
Algunos trucos prácticos
Eliminar llamadas a bases de datos
En páginas tipo portal en las que a los lados se encuentran enlaces que son impresos a
partir de bases de datos (distintas secciones, servicios,...) existe siempre un efecto
ralentizador debido a que se trata de páginas altamente visitadas que efectúan
múltiples llamadas a BD sistemáticamente en cada una de sus páginas.
Una forma de agilizar la visualización de estas páginas es textualizando estos enlaces a
partir de scripts internos. Pongamos el ejemplo de Desarrolloweb:
Como puede verse, a los lados hay secciones como "Vuestras páginas",
"Cosecha del 2000", "Manuales" cuyos enlaces están almacenados en
bases de datos. Sin embargo, los enlaces que se visualizan en la página no han sido
obtenidos por llamadas a bases de datos sino que, cada vez que un nuevo elemento de la
sección es añadido, esto actualiza automáticamente, por medio de un script, un archivo
texto en el que el nuevo enlace es incluido y él más antiguo es eliminado. Es, de hecho,
este archivo texto el que es insertado en el código fuente de la página. De este modo
evitamos media docena de llamadas a bases de datos cada vez que una página es vista lo
cual permite optimizar recursos de servidor de una manera significativa.
Eliminar palabras cortas y repeticiones
En situaciones en la que nuestra base de datos tiene que almacenar campos de texto
extremadamente largos y dichos campos son requeridos para realizar selecciones del tipo
LIKE '%algo%', los recursos de la BD pueden verse sensiblemente mermados. Una forma de
ayudar a gestionar este tipo búsquedas es incluyendo un campo adicional.
Este campo adicional puede ser creado automáticamente por medio de scripts y en él
incluiríamos el texto original, del cual habremos eliminado palabras triviales como
artículos, preposiciones o posesivos. Nos encargaremos además de eliminar las palabras
que estén repetidas. De esta forma podremos disminuir sensiblemente el tamaño del campo
que va a ser realmente consultado.
Hemos comentado en otros capítulos que los campos texto de mas de 255 caracteres
denominados memo no pueden ser indexados. Si aún después de esta primera filtración
nuestro campo continua siendo demasiado largo para ser indexado, lo que se puede hacer es
cortarlo en trozos de 255 caracteres de manera a que lo almacenemos en distintos campos
que podrán ser indexados y por tanto consultados con mayor rapidez.
Creación de tablas
En general, la mayoría de las bases de datos poseen potentes editores de bases que
permiten la creación rápida y sencilla de cualquier tipo de tabla con cualquier tipo de
formato.
Sin embargo, una vez la base de datos está alojada en el servidor, puede darse el caso de
que queramos introducir una nueva tabla ya sea con carácter temporal (para gestionar un
carrito de compra por ejemplo) o bien permanente por necesidades concretas de nuestra
aplicación.
En estos casos, podemos, a partir de una sentencia SQL, crear la tabla con el formato que
deseemos lo cual nos puede ahorrar más de un quebradero de cabeza.
Este tipo de sentencias son especialmente útiles para bases de datos como Mysql, las
cuales trabajan directamente con comandos SQL y no por medio de editores.
Para crear una tabla debemos especificar diversos datos: El nombre que le queremos
asignar, los nombres de los campos y sus características. Además, puede ser necesario
especificar cuáles de estos campos van a ser índices y de qué tipo van a serlo.
La sintaxis de creación puede variar ligeramente de una base de datos a otra ya que los
tipos de campo aceptados no están completamente estandarizados.
A continuación os explicamos someramente la sintaxis de esta sentencia y os proponemos
una serie de ejemplos prácticos:
Sintaxis
Create Table nombre_tabla
(
nombre_campo_1 tipo_1
nombre_campo_2 tipo_2
nombre_campo_n tipo_n
Key(campo_x,...)
)
Pongamos ahora como ejemplo la creación de la tabla pedidos que hemos empleado en
capítulos previos:
Create Table pedidos
(
id_pedido INT(4) NOT NULL AUTO_INCREMENT,
id_cliente INT(4) NOT NULL,
id_articulo INT(4)NOT NULL,
fecha DATE,
cantidad INT(4),
total INT(4), KEY(id_pedido,id_cliente,id_articulo)
)
En este caso creamos los campos id los cuales son considerados de tipo entero de
una longitud especificada por el número entre paréntesis. Para id_pedido
requerimos que dicho campo se incremente automáticamente (AUTO_INCREMENT) de una unidad a
cada introducción de un nuevo registro para, de esta forma, automatizar su creación. Por
otra parte, para evitar un mensaje de error, es necesario requerir que los campos que van
a ser definidos como índices no puedan ser nulos (NOT NULL).
El campo fecha es almacenado con formato de fecha (DATE) para permitir su correcta
explotación a partir de las funciones previstas a tal efecto.
Finalmente, definimos los índices enumerándolos entre paréntesis precedidos de la
palabra KEY o INDEX.
Del mismo modo podríamos crear la tabla de artículos con una sentencia como
ésta:
Create Table articulos
(
id_articulo INT(4) NOT NULL AUTO_INCREMENT,
titulo VARCHAR(50),
autor VARCHAR(25),
editorial VARCHAR(25),
precio REAL,
KEY(id_articulo)
)
En este caso puede verse que los campos alfanuméricos son introducidos de la misma forma
que los numéricos. Volvemos a recordar que en tablas que tienen campos comunes es de
vital importancia definir estos campos de la misma forma para el buen funcionamiento de la
base.
Muchas son las opciones que se ofrecen al generar tablas. No vamos a tratarlas
detalladamente pues sale de lo estrictamente práctico. Tan sólo mostraremos algunos de
los tipos de campos que pueden ser empleados en la creación de tablas con sus
características:
| Tipo | Bytes | Descripción |
|---|---|---|
| INT o INTEGER | 4 | Números enteros. Existen otros tipos de mayor o menor longitud específicos de cada base de datos. |
| DOUBLE o REAL | 8 | Números reales (grandes y con decimales). Permiten almacenar todo tipo de número no entero. |
| CHAR | 1/caracter | Alfanuméricos de longitud fija predefinida |
| VARCHAR | 1/caracter+1 | Alfanuméricos de longitud variable |
| DATE | 3 | Fechas, existen multiples formatos específicos de cada base de datos |
| BLOB | 1/caracter+2 | Grandes textos no indexables |
| BIT o BOOLEAN | 1 | Almacenan un bit de información (verdadero o falso) |