Las restricciones en tablas y columnas le permiten imponer la calidad de los datos. En SQL, hay dos formas de crear restricciones en una tabla:en línea y fuera de línea .
En este artículo, voy a explorar estas limitaciones y las ventajas que tienen, además de explicar cuál recomiendo y por qué.
¿Qué es una restricción en línea?
Una restricción en línea es una restricción que declara en la misma línea que la columna al crear una tabla.
CREATE TABLE employee ( emp_id NUMBER(10) PRIMARY KEY, first_name VARCHAR2(200), last_name VARCHAR2(200), dept_id NUMBER(10) );
En este ejemplo, las palabras PRIMARY KEY después de la columna emp_id indican que emp_id es la clave principal.
Por lo tanto, hemos creado una restricción de clave principal en esta columna al agregar las palabras clave. El concepto es el mismo independientemente del tipo de restricción.
¿Qué es una restricción fuera de línea?
Una restricción fuera de línea es la restricción declarada en una línea separada para la columna. Lo agregamos al final de la instrucción CREATE TABLE.
Por ejemplo, tenemos el siguiente script:
CREATE TABLE employee ( emp_id NUMBER(10), first_name VARCHAR2(200), last_name VARCHAR2(200), dept_id NUMBER(10), CONSTRAINT pk_emp PRIMARY KEY (emp_id) );
Como puede ver, establecemos la restricción PRIMARY KEY, llamada pk_emp , a la columna emp_id al final de la instrucción.
Este concepto funciona de la misma manera independientemente del tipo de restricción.
Ahora, analicemos la diferencia entre estos dos tipos de restricciones, aparte de dónde se declaran.
Las restricciones fuera de línea pueden tener nombres especificados
Al crear restricciones fuera de línea, podemos especificar un nombre. Si bien esto puede parecer una pérdida de tiempo, puede ser útil.
Considere esto en un ejemplo particular:
CREATE TABLE employee ( emp_id NUMBER(10), first_name VARCHAR2(200), last_name VARCHAR2(200), dept_id NUMBER(10), CONSTRAINT pk_emp PRIMARY KEY (emp_id), CONSTRAINT fk_emp_deptid FOREIGN KEY (dept_id) REFERENCES department (dept_id), CONSTRAINT ck_emp_lnlen CHECK (LENGTH(last_name) > 3) );
Hemos especificado los siguientes nombres para algunas restricciones:
- pk_emp
- fk_emp_deptid
- ck_emp_lnlen
Puede parecer que es solo escribir innecesariamente, sin embargo, no lo es. Echaremos un vistazo más de cerca a esto.
Entonces, ¿por qué necesitamos asignar un nombre a una restricción?
Tener restricciones con nombre puede ser útil en varias situaciones. Sin especificar el nombre, Oracle genera automáticamente un nombre para la restricción que genera para todas las restricciones en línea. Por lo general, este nombre no proporciona ninguna información útil.
Cuando obtiene errores en sentencias SQL, código PL/SQL o código de aplicación, es una buena idea usar el nombre de la restricción y saber a qué se refiere o al menos hacer una suposición. Nombres como pk_emp o ck_emp_lnlen sería más descriptivo que el genérico EMP1290894FH nombre.
Además, cuando se revisan los planes de ejecución, el nombre de la restricción se usa a menudo en la salida, lo que facilita determinar cómo se ejecuta el plan. Especialmente, cuando tenemos casos que determinan si se está utilizando una clave principal o una clave externa.
Las restricciones NOT NULL solo se pueden declarar en línea
Solo hay un tipo de restricción que se puede declarar como una restricción en línea. Esta es la restricción NOT NULL.
Esto significa que no puede declararlo fuera de línea.
Ejecuta el siguiente código:
CREATE TABLE employee ( emp_id NUMBER(10), first_name VARCHAR2(200), last_name VARCHAR2(200) NOT NULL, dept_id NUMBER(10) );
Sin embargo, al ejecutar el siguiente código, podemos ver que no funciona:
CREATE TABLE employee ( emp_id NUMBER(10), first_name VARCHAR2(200), last_name VARCHAR2(200), dept_id NUMBER(10), CONSTRAINT nn_emp_ln NOT NULL (last_name) );
Para resumir, para las restricciones NOT NULL, debemos declararlas en línea.
Las restricciones CHECK pueden hacer referencia a varias columnas
Si crea una restricción en línea CHECK, solo puede hacer referencia a la columna en la que se está creando.
Sin embargo, si crea una restricción CHECK fuera de línea, puede hacer referencia a varias columnas.
Crear el empleado tabla con la restricción CHECK como se muestra a continuación:
CREATE TABLE employee ( emp_id NUMBER(10), first_name VARCHAR2(200) CHECK (LENGTH(first_name) > 10), last_name VARCHAR2(200), dept_id NUMBER(10) );
Esta restricción muestra que first_name debe tener más de 10 caracteres.
Sin embargo, ¿y si quisiéramos especificar que la combinación de nombre y apellido debe exceder los 10 caracteres?
Para hacer esto, vuelva a escribir el código como una restricción fuera de línea:
CREATE TABLE employee ( emp_id NUMBER(10), first_name VARCHAR2(200),, last_name VARCHAR2(200), dept_id NUMBER(10), CONSTRAINT ck_fullname_len CHECK (LENGTH(first_name || last_name) > 10) );
Podemos ver que esta regla solo se puede implementar con una restricción fuera de línea.
Método recomendado
Habiendo analizado ambos métodos:en línea o fuera de línea, recomiendo usar las restricciones fuera de línea.
Hay algunas razones para esto.
Primero, puede especificar un nombre para sus restricciones y verlos en mensajes de error y planes de ejecución internos. También puede ayudar a deshabilitar y habilitar restricciones.
En segundo lugar, las restricciones de verificación le permiten hacer referencia a columnas múltiples y únicas. Por lo tanto, es más flexible si los agrega como una restricción fuera de línea.
Finalmente, tener todas las restricciones declaradas como fuera de línea (excepto NOT NULL, que solo se puede definir como una restricción en línea) hace que sea más fácil mirar su sintaxis CREATE TABLE y ver todas sus restricciones en un solo lugar. Es importante especialmente en los casos en que hay tablas grandes con muchas restricciones.
En conclusión, puede crear restricciones utilizando dos métodos diferentes:en línea y fuera de línea. Recomiendo usar el método fuera de línea donde pueda, porque hay más flexibilidad, y establecer un nombre para las restricciones, simplificando así el análisis de sus planes de ejecución y otra información de SQL.