Curso
En las bases de datos relacionales, los datos suelen distribuirse en varias tablas, cada una de las cuales almacena un aspecto específico de un sistema más amplio. Esta separación es una buena elección de diseño, pero plantea un reto, ya que los datos pueden volverse rápidamente difíciles de interpretar.
Para abordar este reto, las bases de datos relacionales se basan en reglas que imponen relaciones entre tablas. Uno de los mecanismos más importantes para mantener esta estructura y fiabilidad es el uso de claves externas, que se utilizan para garantizar que los datos relacionados permanezcan alineados.
En este tutorial, explicaré cómo funcionan las claves externas. Si estás empezando como ingeniero de bases de datos, te recomiendo que realices nuestros cursos Introducción a las bases de datos relacionales en SQL y Diseño de bases de datos para aprender a crear relaciones al definir el esquema de tu base de datos.
Clave primaria frente a Clave externa
Tanto la clave principal, sobre la que tenemos otro artículo, como la clave externa ayudan a mantener la estructura y la integridad de una base de datos relacional. Déjame explicarte ambas cosas:
¿Qué es una clave externa?
Una clave externa es un campo o conjunto de campos de una tabla que hace referencia a la clave principal de otra tabla. Esta clave externa crea un vínculo entre tablas para garantizar que los datos de la tabla de referencia coincidan con las entradas válidas de la tabla referenciada.
Supongamos que tienes una base de datos con una tabla users y una tabla orders. La tabla ` orders ` puede incluir una columna ` user_id `, que debe coincidir con un ` user_id ` existente en la tabla ` users `. La restricción de clave externa garantiza que no puedas crear un pedido vinculado a un usuario inexistente.
Para comprender las claves externas también es necesario comprender las claves primarias, ya que las claves externas dependen de las claves primarias para establecer y mantener estas relaciones.
¿Qué es una clave principal?
Una clave primaria es una columna o combinación de columnas que identifica de forma única cada registro de una tabla. Ninguna fila puede compartir el mismo valor de clave principal, y nunca puede ser un NULL. Por lo tanto, una tabla debe tener una clave principal que sea el identificador único que haga referencia a todas las claves externas de otras tablas.
Por ejemplo, la consulta siguiente crea la tabla users, con la columna user_id como clave principal:
-- Create users table with user_id as primary key
CREATE TABLE users (
user_id INT PRIMARY KEY,
username VARCHAR(100),
email VARCHAR(255)
);
Las principales diferencias entre claves primarias y claves externas
He resumido las diferencias entre las claves primarias y las claves externas en la siguiente tabla:
|
Aspecto |
Clave principal |
Clave externa |
|
Objetivo |
Identifica de forma única cada registro dentro de una tabla. |
Crea una relación haciendo referencia a una clave principal en otra tabla. |
|
Singularidad |
Debe ser único. |
Puede contener valores duplicados. |
|
Valores NULL |
No puede ser NULL |
Puede ser NULL (a menos que esté restringido). |
|
Ubicación |
Definido en la misma tabla |
Hace referencia a la clave principal de otra tabla. |
De la explicación anterior, vemos que las claves primarias y externas son importantes para crear bases de datos estructuradas y fiables. Trabajan juntos para garantizar que los datos sean coherentes, se mantengan las relaciones y se preserve la integridad de la base de datos.
Creación y gestión de claves externas en SQL
Ahora que ya sabes qué son las claves externas y por qué son importantes en las bases de datos, aprendamos a definir, gestionar y controlar su comportamiento al diseñar tu base de datos.
Definición de claves externas con SQL
Puedes configurar una clave externa en SQL de dos maneras: al crear la tabla o añadiéndola posteriormente si la tabla ya existe.
El siguiente ejemplo muestra la primera opción para definir una clave externa al crear una tabla en SQL Server.
-- Create parent table: users
CREATE TABLE users (
user_id INT IDENTITY(1,1) PRIMARY KEY,
username NVARCHAR(100),
email NVARCHAR(255)
);
-- Create child table: orders
CREATE TABLE orders (
order_id INT IDENTITY(1,1) PRIMARY KEY,
user_id INT,
order_date DATE,
CONSTRAINT fk_orders_users FOREIGN KEY (user_id)
REFERENCES users(user_id)
);
La sintaxis es la misma para PostgreSQL, aunque usamos SERIAL para los autoincrementos de la clave principal.
-- Create parent table: users
CREATE TABLE users (
user_id SERIAL PRIMARY KEY, -- SERIAL auto-increments
username VARCHAR(100),
email VARCHAR(255)
);
-- Create child table: orders
CREATE TABLE orders (
order_id SERIAL PRIMARY KEY,
user_id INT,
order_date DATE,
CONSTRAINT fk_orders_users FOREIGN KEY (user_id)
REFERENCES users(user_id)
);
Al configurar una clave externa en MySQL, debes utilizar InnoDB como se muestra a continuación.
-- Create parent table: users
CREATE TABLE users (
user_id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(100),
email VARCHAR(255)
) ENGINE=InnoDB; -- Must use InnoDB for FK support
-- Create child table: orders
CREATE TABLE orders (
order_id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT,
order_date DATE,
CONSTRAINT fk_orders_users FOREIGN KEY (user_id)
REFERENCES users(user_id)
) ENGINE=InnoDB;
Si utilizas una base de datos Oracle, puedes definir la clave externa, pero asegúrate de que los tipos de datos coincidan exactamente en ambas tablas.
-- Create parent table: users
CREATE TABLE users (
user_id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
username VARCHAR2(100),
email VARCHAR2(255)
);
-- Create child table: orders
CREATE TABLE orders (
order_id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
user_id NUMBER,
order_date DATE,
CONSTRAINT fk_orders_users FOREIGN KEY (user_id)
REFERENCES users(user_id)
);
Para añadir una clave externa a una tabla existente, utiliza la siguiente consulta:
-- Assuming orders table already exists
ALTER TABLE orders
ADD CONSTRAINT fk_orders_users
FOREIGN KEY (user_id)
REFERENCES users(user_id);
Recomiendo realizar nuestros cursos Introducción a SQL Server y Creación de bases de datos PostgreSQL para obtener más información sobre las diferencias entre los dialectos SQL a la hora de crear bases de datos.
Gestión de restricciones y convenciones de nomenclatura
Las claves externas son un tipo de restricción, una regla impuesta por el sistema de gestión de bases de datos (DBMS) para validar los datos durante operaciones como inserciones, actualizaciones y eliminaciones. Cuando una restricción de clave externa está activa, la base de datos garantiza que cualquier valor introducido en la columna de clave externa ya exista en la columna de clave primaria a la que se hace referencia.
Una práctica habitual es nombrar las restricciones siguiendo el patrón fk__. A partir de nuestros ejemplos, la clave externa se convierte en fk_orders_users. Si nombras tus claves externas de esta manera, los esquemas serán más legibles, te ayudará a depurar las violaciones de restricciones y funcionará bien con las herramientas de migración. La validación de restricciones funciona si realizas las siguientes operaciones:
-
INSERT: Rechaza una fila si el valor principal al que se hace referencia no existe. -
UPDATE: Evita modificaciones que romperían las relaciones. -
DELETE: Bloquea las operaciones de eliminación cuando existen filas secundarias dependientes.
Integridad referencial y acciones en cascada
La integridad referencial es el principio fundamental que aplica la restricción de clave externa. Las claves externas ayudan a garantizar esto al evitar registros huérfanos, que se producen cuando las filas de una tabla secundaria apuntan a filas inexistentes en una tabla principal.
SQL también te permite configurar acciones en cascada. Son instrucciones automáticas que indican al sistema de gestión de bases de datos (DBMS) exactamente cómo gestionar los cambios realizados en el registro al que se hace referencia. Por ejemplo, puedes utilizar estas operaciones en cascada para hacer cosas como:
|
Acción |
Comportamiento |
|
|
Eliminar filas secundarias cuando se elimina la fila principal. |
|
|
Actualiza la clave secundaria cuando cambie la clave principal. |
|
|
La clave externa secundaria se convierte en |
|
|
El niño recibe el valor predeterminado. |
|
|
Evita cambios que rompan relaciones. |
Por ejemplo, la siguiente consulta añade las operaciones en cascada para eliminar el registro de un usuario si este cancela su pedido, y se actualiza automáticamente si cambia su user_id.
-- Adds cascading rules to enforce hierarchical cleanup
ALTER TABLE orders
ADD CONSTRAINT fk_orders_users
FOREIGN KEY (user_id)
REFERENCES users(user_id)
ON DELETE CASCADE -- deleting a user deletes their orders
ON UPDATE CASCADE; -- if user_id changes, update automatically
Diseño de relaciones entre tablas
Las claves externas son los componentes básicos utilizados en el modelado de datos que definen las relaciones entre las tablas de una base de datos. En esta sección, veremos los diferentes métodos mediante los cuales las claves externas garantizan la coherencia de los datos al vincular tablas.
Relaciones uno a muchos y muchos a muchos
En una relación uno a muchos (1:N), una fila de una tabla principal puede vincularse a muchos registros de una tabla secundaria. Esta relación se aplica colocando la clave principal de la tabla principal, como users.user_id, como clave externa en la tabla secundaria, como orders.customer_id.
Por ejemplo, un usuario puede tener muchos pedidos, o un departamento puede tener muchos empleados.

Ejemplo de relación uno a muchos. Imagen del autor.
Por otro lado, una relación muchos a muchos (M:N) se produce cuando varios registros de una tabla pueden estar relacionados con varios registros de otra. Dado que no es posible implementar directamente una relación muchos a muchos en una base de datos normalizada, utilizamos una tabla de unión (tabla puente) que contiene dos claves externas.

Ejemplo de relación muchos a muchos. Imagen del autor.
Claves externas compuestas y autorreferenciales
Una clave compuesta consta de dos o más columnas que identifican de forma única un registro y deben referenciarse juntas. Este patrón se utiliza cuando la clave natural abarca varios campos o si deseas evitar relaciones duplicadas. Por ejemplo, puedes tener una oferta de cursos identificada por (course_id, semester) o una tabla de unión con student_id y course_id como clave primaria compuesta.
-- Defines courses table
CREATE TABLE course_offerings (
course_id INT,
semester VARCHAR(10),
-- Composite primary key ensures a course can only be offered once per semester
PRIMARY KEY (course_id, semester)
);
-- Create enrollment table
CREATE TABLE enrollment (
student_id INT,
course_id INT,
semester VARCHAR(10),
-- This foreign key links enrollment records to a valid course offering
FOREIGN KEY (course_id, semester)
REFERENCES course_offerings(course_id, semester)
);
Una clave externa autorreferencial o clave externa recursiva es una clave externa que hace referencia a la clave principal dentro de la misma tabla. Este patrón es común en datos jerárquicos como Empleado → Gerente. Esto permite representar relaciones recursivas sin crear tablas adicionales.
En la consulta siguiente, la tabla « manager_id » hace referencia a la tabla « employee_id » en la misma tabla.
CREATE TABLE employees (
employee_id INT PRIMARY KEY,
name VARCHAR(100),
-- manager_id references employee_id in the same table
manager_id INT,
FOREIGN KEY (manager_id) REFERENCES employees(employee_id)
);
Trabajar con datos y garantizar la integridad
Ahora sabemos que las claves externas se utilizan para garantizar la integridad de los datos en las bases de datos. En esta sección, analizaremos las consideraciones prácticas a la hora de trabajar con claves externas para operaciones SQL, los retos más comunes y cómo gestionar las restricciones.
Operaciones INSERT, UPDATE y DELETE
Veamos cómo interactúan estas operaciones con las claves externas.
Operaciones de inserción con claves externas
Para insertar un registro secundario, el valor principal al que se hace referencia debe existir. Si no es así, la inserción falla. Por ejemplo, la consulta siguiente insertará el registro en la tabla orders si la tabla users contiene un registro en el que user_id es 1.
-- users table contains user_id = 1
INSERT INTO orders (order_id, user_id, order_date)
VALUES (100, 1, '2024-02-01');
Si intentas insertar un registro para un usuario que no existe en la tabla principal, aparecerá un error indicando una violación de la restricción de clave externa.
-- user_id = 999 does NOT exist in users table
INSERT INTO orders (order_id, user_id, order_date)
VALUES (101, 999, '2024-02-01');
ERROR: insert or update on table "orders" violates foreign key constraint "fk_orders_users"
Operaciones de actualización y comportamiento en cascada
Las actualizaciones pueden afectar tanto a la tabla de claves externas como a la tabla de claves primarias. Por ejemplo, si actualizas la clave externa en la tabla de pedidos, solo se realizará correctamente si la clave principal existe en la tabla principal. Por ejemplo, la actualización siguiente solo se realizará correctamente si users.user_id = 5 exists.
-- updating foreign key value
UPDATE orders
SET user_id = 5
WHERE order_id = 100;
En el ejemplo anterior, no puedes actualizar la clave principal sin una cláusula « ON UPDATE CASCADE », ya que las filas secundarias siguen haciendo referencia a 1. Para evitar esto, primero eliminamos la restricción de clave externa existente y, a continuación, la volvemos a crear con la opción « ON UPDATE CASCADE » (Incluir restricción de clave externa) habilitada. Con este método, los valores relacionados orders.user_id se actualizan automáticamente.
-- Drop existing foreign key constraint
ALTER TABLE orders
DROP CONSTRAINT fk_orders_users;
-- Recreate FK with ON UPDATE CASCADE enabled
ALTER TABLE orders
ADD CONSTRAINT fk_orders_users
FOREIGN KEY (user_id)
REFERENCES users(user_id)
ON UPDATE CASCADE; -- Automatically update child rows when parent key changes
UPDATE users
SET user_id = 500
WHERE user_id = 1;
Operaciones de eliminación y cascadas
Si intentas eliminar una fila principal sin ninguna regla en cascada establecida, la eliminación fallará y aparecerá un error. Cuando añades una cláusula « ON DELETE CASCADE », le indicas a la base de datos que elimine automáticamente todas las filas secundarias relacionadas cuando se elimine el registro principal, para mantener la coherencia.
En el ejemplo siguiente, creamos una clave externa en orders.user_id que hace referencia a users.user_id. Con ON DELETE CASCADE, si se elimina un usuario de la tabla de usuarios, todos los pedidos relacionados se eliminarán automáticamente.
-- Add a new foreign key constraint to the orders table
ALTER TABLE orders
ADD CONSTRAINT fk_orders_users
FOREIGN KEY (user_id)
REFERENCES users(user_id)
ON DELETE CASCADE; -- Delete orders automatically when user is deleted
A veces, es posible que desees que la base de datos gestione las eliminaciones automáticamente. Puedes aplicar esto con ON DELETE SET NULL al crear la tabla. Esto establecerá las columnas de clave externa en la tabla secundaria como « NULL » si el registro principal cambia o se elimina.
CREATE TABLE orders (
order_id INT PRIMARY KEY,
user_id INT, -- FK referencing users.user_id
order_date DATE,
FOREIGN KEY (user_id)
REFERENCES users(user_id)
ON DELETE SET NULL -- If a user is deleted, set user_id in orders to NULL
);
Afrontar retos comunes
Al diseñar bases de datos complejas, es probable que te encuentres con dificultades relacionadas con las claves externas. A continuación, se describen los problemas más comunes que he experimentado con las claves externas y las soluciones prácticas para cada uno de ellos.
-
Tipos de datos incompatibles: Si la clave externa y las columnas de clave primaria referenciadas tienen tipos de datos incompatibles, no se podrá crear la restricción. Para evitar esto, estandariza siempre los tipos en las tablas relacionadas.
-
Dependencias circulares: Se producen cuando dos tablas se hacen referencia entre sí, lo que puede provocar bloqueos de inserción. Para resolver este problema, debes volver a evaluar el diseño del esquema o crear primero la tabla sin claves externas, cargar los datos base y, a continuación, utilizar
ALTER TABLEpara añadir las restricciones. -
Claves externas colgantes: Este problema se produce cuando la clave externa de un hijo apunta a una tabla principal que no existe. Para solucionar esto, utiliza acciones en cascada para validar los datos durante las operaciones de eliminación y actualización.
Gestión de modificaciones y eliminación de restricciones
A veces, es posible que quieras modificar las restricciones de clave externa al rediseñar el esquema de tu base de datos. A continuación se indican las formas de eliminar la clave externa con ligeras variaciones sintácticas entre los diferentes dialectos SQL.
En las bases de datos PostgreSQL, SQL Server y Oracle, utilizamos la instrucción « DROP CONSTRAINT ».
-- Drop foreign key
ALTER TABLE orders
DROP CONSTRAINT fk_orders_users;
Sin embargo, en MySQL, usamos la instrucción « DROP FOREIGN KEY » para eliminar la clave externa.
-- Drop foreign key
ALTER TABLE orders
DROP FOREIGN KEY fk_orders_users;
Ten en cuenta que al eliminar una restricción de clave externa, se elimina la aplicación de la integridad referencial de la base de datos. Después de la eliminación, puedes insertar o actualizar datos que infrinjan la relación, lo que puede dar lugar a datos incoherentes.
Rendimiento y optimización
En los ejemplos anteriores, hemos visto cómo las claves externas garantizan un diseño eficaz de los datos al mantener su integridad. Sin embargo, debes comprender cómo optimizar las claves externas para mejorar el rendimiento de tus bases de datos. A continuación, te ofrezco algunos consejos que me han resultado útiles al trabajar con claves externas:
Rendimiento de la indexación y las consultas
Cuando indexas una clave externa, la base de datos puede validar rápidamente los cambios durante las operaciones de inserción, actualización o eliminación localizando las claves correspondientes en la tabla principal. Del mismo modo, los índices aceleran las operaciones de unión que vinculan tablas secundarias y principales al permitir que el motor de la base de datos coincida las filas basándose en valores de claves externas.
Como práctica recomendada, te aconsejo que indexes explícitamente las columnas de claves externas si el DBMS no lo hace automáticamente.
Técnicas de optimización de consultas
Algunos motores SQL utilizan la existencia de claves externas para aplicar la eliminación de uniones, una técnica que identifica y elimina las uniones innecesarias del plan de ejecución de la consulta. Por ejemplo, si una consulta solo accede a columnas de la tabla secundaria, pero incluye una unión con una tabla principal para el filtrado garantizado por la restricción de clave externa, la operación de unión se puede optimizar.
Siempre puedes ver los planes de ejecución para comprobar cómo el optimizador de consultas gestiona las claves externas y las combinaciones. Estas optimizaciones y su eficacia varían según los motores SQL, como PostgreSQL, MySQL y SQL Server. Comprender el comportamiento del optimizador de tu base de datos específica ayuda a escribir consultas eficaces que aprovechan al máximo las restricciones de claves externas.
Por ejemplo, puedes utilizar la siguiente consulta para ver el plan de ejecución en PostgreSQL:
-- View execution plan
EXPLAIN ANALYZE
SELECT o.order_id, u.email
FROM orders o
JOIN users u ON o.user_id = u.user_id;
Esta tabla resume cómo ver el plan de ejecución en diferentes bases de datos:
|
Base de datos |
Comando |
|
PostgreSQL |
|
|
MySQL |
|
|
SQL Server |
Plan de ejecución estimado/real |
|
Oracle |
|
Terecomiendo que utilices nuestra función curso «Unir datos en SQL» para aprender los diferentes tipos de uniones en SQL y cómo trabajar con diferentes tablas relacionadas en la base de datos.
Casos de uso avanzados y mejores prácticas
Más allá de la implementación básica, puedes utilizar claves externas para crear una arquitectura de base de datos robusta, escalable y fácil de mantener. En esta sección, explicaré los escenarios especializados y los principios de diseño de alto nivel que hay que tener en cuenta al utilizar claves externas.
Relaciones entre bases de datos o entre esquemas
Si bien las claves externas están diseñadas para garantizar la integridad dentro de una sola base de datos o esquema, los entornos empresariales más complejos a menudo requieren relaciones que trascienden estos límites. La siguiente tabla resume la compatibilidad entre esquemas y bases de datos para diferentes dialectos SQL.
|
Base de datos |
Compatibilidad entre esquemas |
Compatibilidad entre bases de datos |
Limitaciones |
|
PostgreSQL |
Sí |
No |
Limitado a un único clúster de bases de datos. |
|
SQL Server |
Sí |
Sí |
La integridad entre bases de datos se gestiona mediante lógica de aplicación o desencadenadores, en lugar de claves foráneas nativas. |
|
Oracle |
Sí |
Sí |
Los enlaces de bases de datos sirven para acceder a los datos; normalmente, las restricciones FK nativas no se aplican en los enlaces. |
|
MySQL |
No |
No |
Estrictamente limitado a tablas dentro de la misma base de datos y motor de almacenamiento, como InnoDB. |
|
SQLite |
No |
No |
Limitado a la conexión específica del archivo/base de datos. |
Mantenimiento y auditoría
A medida que crees claves externas, notarás que cambian cada vez que cambia tu lógica de negocio. Ten en cuenta las siguientes formas de auditar y mantener las claves externas para garantizar que estén actualizadas:
- Revisar las restricciones: Audita periódicamente las restricciones de claves externas para garantizar que sigan estando en consonancia con la evolución de las reglas empresariales y los cambios en el esquema.
- Auditoría periódica del índice: Verifica siempre que existan índices en todas las columnas de claves externas para mantener un rendimiento óptimo de unión y validación, especialmente después de importaciones de datos de gran tamaño o actualizaciones del sistema.
- Documentación y visualización: Utiliza diagramas entidad-relación (ER) o herramientas de visualización de esquemas para documentar las relaciones. Estas ayudas visuales garantizarán que todos los programadores y analistas comprendan las relaciones y las reglas de integridad que imponen tus claves externas.
Mejores prácticas para un diseño de bases de datos robusto
Para sacar el máximo partido al funcionamiento de las claves externas, sigue estas directrices:
-
Alinea tus claves con la lógica empresarial real: Asegúrate de que las claves primarias y externas representen realmente entidades reales y las relaciones entre ellas, en lugar de basarse en identificadores artificiales o inestables.
-
Utiliza nombres claros y coherentes: Elige nombres descriptivos para las restricciones, como «
fk_orders_user_id», para que tu esquema sea más fácil de mantener, depurar y trabajar con otras personas. -
Equilibra el rigor y la flexibilidad: Las restricciones deben proteger la calidad de los datos, pero tu diseño debe seguir permitiendo casos extremos prácticos o validaciones gestionadas en la capa de aplicación.
-
Evita las relaciones circulares: Estructura tu esquema de manera que las dependencias de claves externas no se repitan entre sí, ya que esto complica innecesariamente las inserciones, actualizaciones y eliminaciones.
-
Optimizar el rendimiento: Indexa correctamente tus claves externas y aplica con cuidado las acciones en cascada para mantener la integridad sin ralentizar tu sistema.
Conclusión
Como con cualquier habilidad, dominar las claves externas se consigue con la práctica. Te animo a que experimentes con el modelado de esquemas, pruebes acciones en cascada y comprendas cómo se comportan las restricciones en situaciones reales. Con el tiempo, aprenderás a equilibrar las reglas estrictas con la flexibilidad que necesitan tus aplicaciones, creando bases de datos que sean resistentes y adaptables a medida que evolucionan los requisitos.
Ahora que ya sabes cómo utilizar las claves externas en el diseño de bases de datos, te recomiendo que pruebes nuestro programa de ingeniero de datos asociado en SQL para aprender los fundamentos de la ingeniería de datos y el almacenamiento de datos. Por último, si deseas mejorar tus habilidades de gestión de bases de datos para big data, te recomiendo que realices nuestro curso Introducción al modelado de datos en Snowflake para aprender más sobre el modelado dimensional.
Preguntas frecuentes
¿Cuál es la diferencia entre una clave primaria y una clave externa?
Una clave primaria identifica de forma única los registros de su propia tabla, mientras que una clave externa hace referencia a una clave primaria de otra tabla para establecer una relación.
¿Puede una tabla tener varias claves externas?
Sí, una tabla puede tener varias claves externas, cada una de ellas vinculada a diferentes tablas principales.
¿Debe una tabla tener columnas de clave externa únicas?
No, las columnas de claves externas pueden contener valores duplicados, pero deben hacer referencia a filas válidas en la tabla principal.
¿Qué sucede si eliminas un registro al que hace referencia una clave externa?
Dependiendo de las restricciones, la base de datos puede restringir la eliminación, eliminar en cascada las filas relacionadas o establecer los valores de las claves externas como NULL.
¿Son obligatorias las claves externas en las bases de datos relacionales?
Aunque no son obligatorias, las claves externas son esenciales para garantizar la integridad relacional y un diseño fiable de la base de datos.


