Skip to the content.

Curso PostgreSQL

Autor: Luis Fernando Apáez Álvarez
Restricciones

Desde hace dos clase hemos estado trabajando con las restricciones sobre nuestras tablas. Dichas restricciones fueron especificamente las llaves primarias y foráneas, las cuales son de enorme importancia para maneter la integridad de los datos en nuestra BD; asimismo, las restricciones que veremos en esta clase son útiles para maneter dicha integridad.

Restricción CHECK

Comencemos por ver los primeros registros de la tabla empleados:

y supongamos, por ejemplo, que por políticas de la empresa ningún empleado puede ganar más de 65000 mensuales. Así como hemos construido nuestra tabla no tendríamos problema alguno en ingresar un empleado cuyo salario exceda esta cifra. Por ello es necesario la implementación de una restricción sobre esta columna para impedir que se ingresen valores superiores a los 65000, lo cual conseguiremos al definir la restricción del tipo CHECK sobre al columna salario, de modo que con esta retricción logramos controlar los valores que se ingresan en una columna en especifico.

Para agregar dicha restricción escribimos:

ALTER TABLE <<nombre_tabla>> ADD CONSTRAINT ck_<<nombre_tabla>>_<<nombre_columna>> CHECK (<<condicion>>)

donde notamos que en el CHECK debemos definir alguna condición en especifico. En nuestro ejemplo, la condición sería que salario < 65000. Por consiguiente, definimos el siguiente CHECK sobre la columna salario:

ALTER TABLE empleados ADD CONSTRAINT ck_empleados_salario CHECK(salario < 65000);

cuando lo ejecutemos probablemente nos salga un error que nos diga que dicha restricción es violada por algunos registros en nuestra tabla, es decir, ya existen empleados que ganan más de 65000. En mi caso sólo hay un empleado y éste es:

SELECT * FROM empleados WHERE salario > 65000;

cuyo salario es exorbitante. Recordemos que los datos los generamos de amnera aleatoria, por lo que casos como estos se nos presentan. Se puede solucionar fácilmente este problema si actualizamos el valor del salario para este empleado:

UPDATE empleados SET salario = 60000 WHERE id_empleados = 80; 

nuevamente ejecutamos el código para definir el CHECK y ahora no deberíamos tener problemas. Ahora bien, ya hemos definido la restricción CHECK sobre la columna salarios, de esta forma, si intentaramos ingresar un empleado nuevo o actualizar los datos de un empleado y colocar en la columna salario un valor mayor a los 65000 obtendríamos seguramente un error. Comprebemos lo dicho anteriromente

INSERT INTO empleados(nombre, app, apm, puesto, salario, horario) 
	VALUES('Jenny', 'López', 'López', 'Vendedor', 70000, '7:00-10:00'); 

con lo que obtenemos

un error. Así, estamos garantizando que los registros de la tabla empleados, en especifico los valores de la columna salario, mantenga una integridad de acuerdo a nuestra necesidades. Otro ejemplo de la restricción CHECK es en campos referentes al sexo. Supongamos que en la tabla empleados tenemos una columna destinada al sexo del empleado; para esta columna podríamos definir una restricción CHECK de la siguiente forma

ALTER TABLE empleados ADD CONSTRAINT ck_empleados_sexo 
	CHECK(sexo IN ('Masculino', 'Femenino', 'Otro'))

donde sólo estamos premitiendo que los valores de la tabla empleados en la columna sexo sean Masculino, Femenino u Otros. Así, si llegaramos a ingresar hombre, entonces se nos arrojaría un error.

Otro ejemplo común es agregar una restricción CHECK sobre columnas de números telefónico. Por ejemplo, supongamos que tenemos la columna num_tel en la tabla empleados y deseamos que no sean ingresados números telefónicos con más de 10 cifras, o que lleguen a ingresarse números telefónicos con alguna letra. Entonces emplearemos la siguiente restricción CHECK sobre la columna num_tel

ALTER TABLE empleados ADD CONSTRAINT ck_empleados_num_tel 
	CHECK(num_tel ~ '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]') 

donde especificamos que el número telefónico debe ser de 10 cifras y cada una de estas cifras será un entero entre el 0 y el 9, además es necesario colocar el símbolo ~ después del nombre de la columna a la cual le aplicares la restricción CHECK. También podemos utilizar intervalos de letras en vez de numéricos (enteros), por ejemplo '[A-Z][A-Z]' indicaría que se debe escribir una palabra conformada de dos letras mayúsculas entre la A y la Z.

Ahora bien, podemos eliminar restricciones CHECK; por ejemplo eliminemos la restricción ck_salario de la tabla empleados

ALTER TABLE empleados DROP CONSTRAINT ck_empleados_salario;

es decir, la sintaxis general para eliminar una restricción CHECK es

ALTER TABLE <<nombre_tabla>> DROP CONSTRAINT ck_<<nombre_tabla>>_<<nombre_columna>>;
Restricción NOT NULL

Hay veces en las que no podemos permitir valores nulos dentro de una columna. Por ejemplo, en la tabla empleados, en la columna puesto debemos especificar para cada uno de los empleados el puesto que éstos llevarán a cabo. Así, de manera general, la restricción NOT NULL nos sirve para forzar el ingreso de datos para ciertas columnas.

Para definir esta restricción sobre la columna puesto escribimos

ALTER TABLE empleados ALTER COLUMN puesto SET NOT NULL;

de tal manera, si nosotros intentamos registrar a un empleado nuevo y omitimos el valor correspondiente a la columna puesto, entonces postgres nos arrojará un error:

INSERT INTO empleados(nombre, app, apm, salario, horario) 
	VALUES('Jenny', 'López', 'López', 10000, '6:00-9:00');

Restricción unique

Como vimos en la restricción de llave primaria al definirla sobre una columna, dentro de esta columna no se aceptarán valores repetidos. Es decir, si definimos la llave primaria, por ejemplo, sobre el id_empleados de la tabla empleados, entonces no se pirmitirán id’s repetidos.

La restricción unique actúa de manera muy similar, pues al definir ésta sobre alguna columna, no se permitirán valores duplicados. Sin embargo, dicha columna no tiene la características principales para ser considerada como llave primaria dentro de esta tabla y además ésta permite valores nulos (lo cual la llave primaria no permite). Por ejemplo, si en la tabla empleados tuvieramos una columna denominada curp, entonces sería necesario definir la restricción unique para dicha columna, lo cual conseguiríamos escribiendo

ALTER TABLE empleados ADD CONSTRAINT uq_empleados_curp UNIQUE(curp);

Observación: El proceso que estamos siguiendo para definir las restricciones no es el mejor, si bien es ilustrativo, éste debe realizarse desde que definimos las tablas y no después como lo estamos haciendo ahora. De tal manera, lo primero que se debe hacer en un proyecto es pensar las tablas que se crearán, pensar las columnas de cada tabla y definir las restricciones sobre las columnas que sean necesarias.

Por ende, la forma en la que estamos llevando el curso es, primero, aprender el código SQL y, después, sobre la marcha ir modificando el proyecto, lo cual es bastante ilustrativo y práctico; sin embargo no es la forma correcta de trabajar, pero, una vez que finalices el curso tendrás de igual manera las herramientas que te peritan trabajar con proyectos de la mejor forma posibble.


Ejercicio
  1. Dentro de la tabla productos tenemos distintos productos que vendemos en la papelería. Use el siguiente código
   SELECT DISTINCT nombre_productos FROM productos;

para conocer todos los productos que se venden en la papelería.

​ a. Define una restricción CHECK sobre la columna nombre_productos de la tabla productos, basándote en la información que obtuviste de la consulta anterior.

​ b. Intenta ingresar un registro que viole la restricción creada en el punto anterior.

​ c. Elimina la restricción creada en el punto a.

  1. Elige cualquiera de tus tablas y coloca una restricción de no nulidad en alguna de sus columnas, así como una restricción UNIQUE

Regresar