Guia SQL
Guia SQL
Como resultado de lo anterior, SQL permite lograr con mayor rapidez y facilidad la definición
y manipulación de los objetos de base de datos, permitiendo así alcanzar una mayor
eficiencia y productividad en el desarrollo.
En todas las instrucciones DML, el único dato devuelto por el sistema es el número de filas
que se han modificado al ejecutar la instrucción.
SELECT [{ALL|DISTINCT}]
<nombre_campo>[, <nombre_campo>...]
FROM {<nombre_tabla>|<nombre_vista>}[,
{<nombre_tabla>|<nombre_vista>}...]
{<nombre_campo>|<indice_campo>} [{ASC|DESC}]]];
INSERT (Inserción de datos)
Añadir datos a una tabla se realiza mediante la instrucción INSERT. Su sintaxis fundamental
es:
La tabla representa la tabla a la que queremos añadir el registro y los valores que siguen a
la cláusula VALUES, son los valores que damos a los distintos campos del registro.
Las columnas no rellenadas explícitamente con la orden INSERT, se rellenan con su valor
por defecto (DEFAULT) o bien con NULL si no se indicó valor por defecto alguno. Si alguna
columna tiene restricción de obligatoriedad (NOT NULL), ocurrirá un error si no indicamos
un valor para dicha columna.
Por ejemplo, supongamos que tenemos una tabla de clientes cuyos campos son: dni,
nombre, apellido1, apellido2, localidad y dirección
supongamos que ese es el orden de creación de los campos de esa tabla y que la localidad
tiene como valor por defecto Palencia y la dirección no tiene valor por defecto. En ese caso,
estas dos instrucciones son equivalentes:
Su sintaxis es la siguiente:
Se modifican las columnas indicadas en el apartado SET con los valores indicados. La
cláusula WHERE permite especificar qué registros serán modificados.
Ejemplos:
La primera instrucción actualiza la provincia de los clientes de Orense para que aparezca
como Ourense.
El segundo UPDATE incrementa los precios en un 16%. La expresión para el valor puede
ser todo lo compleja que se desee (en el ejemplo se utilizan funciones de fecha para
conseguir que los partidos que se jugaban hoy, pasen a jugarse el siguiente martes):
Esta instrucción elimina las filas de la tabla que cumplan la condición indicada. Ejemplo:
Hay que tener en cuenta que el borrado de un registro no puede provocar fallos de
integridad y que la opción de integridad ON DELETE CASCADE hace que no solamente se
borren las filas indicadas, sino todas las relacionadas.
¿Que es DCL?
Un Lenguaje de Control de Datos (DCL, por sus siglas en inglés: Data Control Language) es
un lenguaje proporcionado por el sistema de gestión de base de datos que incluye una serie
de comandos SQL que permiten al administrador controlar el acceso a los datos contenidos
en la base de datos.
GRANT
Permite dar permisos a uno o varios usuarios o roles para realizar tareas determinadas.
TO <usuario1>, <usuario2> …
Las tareas sobre las que se pueden conceder o denegar permisos son las siguientes:
● SELECT
● INSERT
● UPDATE
● DELETE
REVOKE
Permite eliminar permisos que previamente se han concedido con GRANT
ON <nombre tabla>
¿Qué es DDL?
Lenguaje de definición de datos, en inglés Data Definition Language.
El DDL es la parte del lenguaje SQL que realiza la función de definición de datos.
Fundamentalmente, se encarga de la creación, modificación y eliminación de los objetos de
la base de datos (es decir, de los metadatos). Por supuesto, es el encargado de la creación
de las tablas.
Los elementos, llamados objetos, de la base de datos: tablas, vistas, columnas, índices; se
almacenan en el diccionario de datos. Por otro lado, muchos Sistemas Gestores de Bases
de Datos aportan elementos para organizar estos objetos (como catálogos y esquemas).
CREATE
Es un comando de lenguaje de definición de datos (DDL) que se utiliza para crear objetos
de base de datos, como bases de datos y tablas de bases de datos.
A la hora de crear tablas, hay que indicar el tipo de datos de cada campo. Necesitamos,
pues, conocer los distintos tipos de datos. Estos son:
ALTER
El comando ALTER en SQL se usa para agregar, renombrar o modificar, soltar/eliminar
columnas en una tabla de base de datos existente. Además, se puede emplear para
agregar y eliminar varias restricciones en una tabla de base de datos existente.
Ejemplo:
Borrar columnas
Ejemplo
TRUNCATE
El comando TRUNCATE TABLE se usa para eliminar todos los registros de datos de la tabla
de la base de datos. Elimina todas las filas de forma permanente. Ergo, no podemos realizar
una operación de reversión para deshacer un comando TRUNCATE.
DROP
El comando DROP se usa para eliminar un objeto de base de datos de la base de datos.
Incluso podemos eliminar la base de datos utilizando el comando DROP. No podemos
realizar una operación de reversión para deshacer un comando DROP de base de
datos/tabla.
Eliminar base de datos.
Eliminar tabla:
COMMIT
La instrucción COMMIT hace que los cambios realizados por la transacción sean definitivos,
irrevocables. Solo se debe utilizar si estamos de acuerdo con los cambios, conviene
asegurarse mucho antes de efectuar el COMMIT, ya que las instrucciones ejecutadas
pueden afectar a miles de registros.
Hay que recordar que si hemos ejecutado un INSERT, un DELETE y dos UPDATE (por
ejemplo), COMMIT acepta de golpe todas esas instrucciones, ya que la transacción será el
conjunto de todas ellas (si entre medias no hemos escrito una instrucción DDL o DCL).
Sintaxis:
COMMIT;
Ejemplo:
COMMIT;
ROLLBACK
Para identificar si lo hemos hecho de manera correcta debemos considerar los siguientes
aspectos:
1. Todos los atributos son atómicos. Un atributo es atómico si los elementos del
dominio son indivisibles, mínimos.
2. La tabla contiene una clave primaria única
3. La clave primaria no contiene atributos nulos
4. No debe existir variación en el número de columnas
5. Los campos no clave deben identificarse por la clave (dependencia funcional)
6. Debe existir una independencia del orden tanto de las filas como de las columnas,
es decir, si los datos cambian de orden no deben cambiar sus significados.
7. Una tabla no puede tener múltiples valores en cada columna
8. Los datos son atómicos (a cada valor de X le pertenece un valor de y viceversa)
Si nos damos cuenta, esta tabla no cumple con el requisito que dice que todos los atributos
deben ser atómicos, es decir, que debemos descomponerlo en su mínima expresión.
Siguiendo los aspectos a considerar podríamos decir que nuestra tabla inicial se
transformaría a:
Con esto podríamos decir que nuestra tabla cumple con la primera Forma Normal (1FN).
Sabremos si nuestra base de datos tiene en la segunda forma normal, si esta previamente
cumple con las normas de la Primera forma Normal y si sus atributos no principales
dependen de forma completa de la clave principal.
Ahora, si nos fijamos, esta aún no cumple con los requisitos que pide la segunda Forma
Normal (2FN).
Podríamos crear tablas separadas para cursos y para profesores y cada una de estas
tendría su clave primaria y estarían relacionadas por una clave externa (Foreign Key).
Tabla de Cursos:
Tabla Autores:
Podemos decir que nuestra tabla se encuentra en tercera normal si previamente estaba en
segunda forma normal y si no existe ninguna dependencia funcional transitiva entre los
atributos que no son clave.
En otras palabras, todo atributo no primo es implicado por la clave primaria en una
secuencia no transitiva.
Si detallamos nuestra tabla de cursos aún podríamos simplificarla, para esto podríamos
extraer la columna de materiales y crear una nueva tabla para esto.
Con esto, nuestra tabla cumpliría con los requisitos de la tercera Forma Normal (3FN) y
estaría lista.
Ciertos tipos de tablas 3NF, que en la práctica raramente se encuentran, son afectadas por
tales anomalías; estas son tablas que no satisfacen la forma normal de Boyce-Codd (BCNF)
o, si satisfacen la BCNF, son insuficientes para satisfacer las formas normales más altas
4NF o 5NF.
CONTROLADORES DE CONEXIÓN
Tipos de Controladores:
Tipo 1: Los controladores de tipo 1 son controladores "puente". Utilizan otra tecnología,
como por ejemplo, ODBC (Open Database Connectivity), para comunicarse con la base de
datos.
Tipo 2: Los controladores de tipo 2 utilizan una API nativa para comunicarse con un sistema
de base de datos.
Los controladores de tipo 2 son generalmente más rápidos que los controladores de tipo 1.
¿Qué es un ORM?
Sus siglas significan Object Relational Mapping (mapeo relacional de objetos) y su función
es abstraer la base de datos, de modo que tú como programador puedas hacer consultas
sin conocer SQL, y en su lugar, seguir usando el lenguaje de programación que ya conoces.
Lo que hace un ORM es mapear las bases de datos a objetos (por eso su nombre) y estos
objetos tendrán métodos para interactuar con ellos y hacer el CRUD sin comunicarte
directamente a la base de datos.
Hibernate: El ORM para Java:
Todo esto puede sonar confuso en principio, así que vamos a implementarlo de manera muy
sencilla con Spring Boot.
Partimos de Spring Initializr para generar nuestro proyecto con las siguientes dependencias:
Web, JPA, y H2.
Después de generar nuestro proyecto lo abrimos con nuestro IDE de preferencia y
revisamos nuestro archivo de configuración pom.xml, aquí podemos encontrar las
dependencias que hemos añadido con Spring, revisemos la que tenemos con JPA
Esta dependencia incluye JPA API, JPA Implementation, JDBC y otras librerías necesarias,
incluyendo a Hibernate dado que es su implementación por defecto.
Revisemos también la dependencia H2, que es una base de datos muy ligera.
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
Creando la entidad
Ahora crearemos nuestra entidad JPA en una carpeta que llamaremos modelo
@Entity
public class Libro{
@Id
@GeneratedValue
private Long id;
private String nombre;
// constructores
// getters y setters
}
Con esto tenemos nuestra entidad básica creada, de la cual H2 podrá crear una tabla, si
reiniciamos la aplicación y revisamos la consola de H2 encontraremos una nueva tabla
llamada libro.
Vamos a añadir unos valores iniciales a nuestra aplicación, así que vamos a crear un nuevo
archivo SQL y lo guardamos en una carpeta llamada recursos, vamos a llenar nuestro
archivo con las siguientes sentencias SQL.
Continuaremos creando los componentes básicos para probar nuestra aplicación, primero
añadiremos una repositorio JPA en una carpeta repositorios.
@Repository
public interface LibroRepository extends JpaRepository<Book, Long>
{
}
Podemos usar la interfaz de JpaRepository del framework Spring, la cual provee una
implementación por defecto para las operaciones CRUD básicas.
@Service
public class LibroService {
@Autowired
private LibroRepository libroRepository;
Para probar nuestra aplicación, vamos a revisar que los datos creados puedan ser traídos
desde el método list() del servicio, y listo.
spring.jpa.show-sql=true
Podemos mejorar la visualización del SQL añadiendo esto:
spring.jpa.properties.hibernate.format_sql=true
Vemos que de esta forma es super simple, pero no es recomendable, ya que imprime todo
en nuestra consola sin ninguna de las optimizaciones de un framework de logging. Además
no hace log a los parámetros de sentencias parametrizadas.
Vía Loggers
Ahora veamos cómo podemos hacer un log de las consultas SQL configurando los loggers
en el archivo de propiedades.
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
La primera línea hace un log de las sentencias SQL y la segunda hace log de los
parámetros de sentencias parametrizadas. Podemos mejorar nuevamente la visualización
de las consultas con la propiedad mencionada anteriormente.
Ajustando estas propiedades, los logs se enviarán al anexador (appender) configurado, por
defecto, Spring Boot usa logback.
Spring ddl-auto:
La propiedad spring.jpa.hibernate.ddl-auto es propia de Spring Data JPA y es su
forma de especificar un valor que finalmente se pasará a Hibernate bajo la propiedad que
conoce, hibernate.hbm2ddl.auto.
La operación update consultará la API del controlador JDBC para obtener los metadatos de
la base de datos y luego Hibernate compara el modelo de objetos que crea basándose en la
lectura de sus clases anotadas o asignaciones XML de HBM e intentará ajustar el esquema
sobre la marcha.
La operación create, por ejemplo, intentará agregar nuevas columnas, restricciones, etc.,
pero nunca eliminará una columna o restricción que puede haber existido anteriormente
pero que ya no forma parte del modelo de objetos de una ejecución anterior.
En el desarrollo, a menudo es común ver a los desarrolladores usar update para modificar
automáticamente el esquema para agregar nuevas adiciones al reiniciar. Pero entienda
nuevamente, esto no elimina una columna o restricción que pueda existir de ejecuciones
previas que ya no es necesaria.