Toda gran historia comienza con una crisis de identidad. Luke, el gran Maestro Jedi, comienza inseguro:"¿Quién soy?" - ¿Y cómo podría ser alguien importante? Se necesita a Yoda, el que tiene la Fuerza, para que le enseñe cómo aprovechar sus poderes.
Hoy, déjame ser tu Yoda.
Comenzaremos con cómo elegir una clave principal, combatir una crisis de identidad y luego terminar con ejemplos de código para crear una clave principal en una base de datos.
Cómo elegir una clave principal
Puedes pensar que Luke es el único con una crisis de identidad, pero eso no es cierto. Al crear una base de datos, todo está en una crisis de identidad. Y es exactamente por eso que necesitamos claves primarias:resuelven la crisis. Nos dicen cómo encontrar a todos.
Imagina que eres el gobierno y quieres identificar a cada uno de tus ciudadanos digitalmente. Entonces, creas esta base de datos con todo sobre ellos:
First Name
Last Name
Passport Number
Usted elige el número de pasaporte como clave principal:la identidad para todos. Calculas que eso es todo lo que necesitas ya que el pasaporte tiene la dirección y todo lo demás. Usted sabe que los números de pasaporte son únicos, por lo que se siente bien e implementa este sistema.
Luego, unos años más tarde, descubres una horrible verdad:todo el país se enfrenta a una crisis de identidad.
Cada vez que vence el pasaporte de alguien, obtienen uno nuevo. Su identidad cambia. Otros sistemas siguen usando los números de pasaporte antiguos, por lo que ahora apuntan a personas fantasma.
La singularidad no es suficiente. El valor no debe cambiar durante la vigencia de la fila.
Y luego, encuentras que hay algunas personas que ni siquiera tienen pasaportes. No puede ingresarlos en su sistema, ya que las claves principales no pueden ser NULL
. ¿Cómo puedes identificar a alguien con un NULL
? clave?
Cada fila debe tener un identificador. NULL no permitidos.
La siguiente iteración significa encontrar un identificador que no cambie con el tiempo y que todos tengan. En India, se está convirtiendo en la tarjeta Adhaar. En los EE. UU., el Número de Seguro Social.
Si está creando una base de datos, conviértalas en sus claves principales.
A veces, no tienes ninguna de esas claves. Considere un país que aún no tiene un Número de Seguro Social y quiere crear un registro digital de cada ciudadano. Podrían crear un nuevo SSN, o simplemente podrían aprovechar el poder de las bases de datos y usar una clave sustituta.
Una clave sustituta no tiene un equivalente en el mundo real. Es solo un número dentro de una base de datos. Entonces, tienes esta tabla en el nuevo país:
userID
First Name
Last Name
Passport Number
Los números de pasaporte son únicos. Siempre que desee obtener el identificador de un usuario, puede obtenerlo a través del número de pasaporte.
El ID de usuario nunca cambia. El número de pasaporte puede cambiar, pero siempre es único, por lo que siempre obtiene el usuario correcto. El ID de usuario es un sustituto para un Número de Seguro Social inexistente en este país.
Dato curioso:el número de pasaporte aquí también es una clave de candidato. Podría haber sido la clave principal, si nunca cambió. Esta es una distinción de lógica empresarial.
La conclusión principal es esta:siempre que elijas una clave principal, piensa en una crisis de identidad . ¿Es posible que alguien cambie su identificador en el futuro? ¿Podemos entrar en un estado en el que varias personas tengan el mismo identificador?
Uso a las personas como ejemplo, porque aclara la identidad:sabemos que se supone que cada persona tiene una identidad. Transfiera este pensamiento a sus bases de datos. Todo tiene una identidad, razón por la cual necesitas claves principales.
Nota:A veces, es posible y deseable usar varias columnas juntas como clave principal. Esta es una clave compuesta.
Ahora intentemos definir Claves primarias con ejemplos de código reales. Hay dos cosas que hacer aquí:primero, identificará la clave principal. Luego, aprenderá la sintaxis para definirlo en una base de datos.
Un ejemplo del mundo real
Supongamos que ejecuta una empresa de envíos, muy parecida a Flexport. Tienes paquetes que necesitan ir de un lugar a otro y barcos que los transportan. Además, tiene clientes que solicitan estos paquetes.
Calcula que necesitará una tabla para los clientes, otra para los paquetes y otra para el transporte, que muestren qué paquete está en qué lugar en este momento.
Piense en qué columnas necesitará y cuál debería ser la clave principal. Si fuera ingeniero en Flexport, esta es una pregunta real que tendría que resolver. Nada se regala, todo se descubre en el mundo real.
Dada esta información, diseñaría estas tablas así:
Customers: first_name, last_name, email, address (for deliveries to their location)
Packages: weight, content
Transportation: <package_primary_key>, Port, time
Nos faltan las claves primarias. Piense en ellos antes de seguir leyendo.
Para el paquete, elegiré un sustituto ID del paquete. Podría haber intentado enumerar todos los atributos del paquete:peso, volumen, densidad, edad. Identificarían el paquete de forma única, pero esto es muy difícil de hacer en la práctica. A la gente no le importa esto, solo les importa que el paquete llegue de un lugar a otro.
Por lo tanto, tiene sentido crear un número aleatorio y usarlo como ID. Esta es exactamente la razón por la que FedEx, UPS y todos los servicios de entrega usan códigos de barras e identificaciones. Estas son claves sustitutas generadas para rastrear paquetes.
Para el cliente, elegiré un sustituto Identificación del cliente. Aquí, nuevamente, tuve la opción de elegir, digamos, el Número de Seguro Social de mis clientes. Pero los clientes no quieren compartir esto conmigo solo para que pueda enviarles algo. Por lo tanto, generamos una clave internamente, no le informamos a nuestros clientes sobre esta clave y continuamos llamándolos CustomerNo. 345681.
Historia divertida:Conozco algunas empresas en las que expusieron este CustomerNo, y los clientes insistieron en obtener el No. 1. Fue muy divertido:los ingenieros en realidad tuvieron que cambiar su código front-end a:if (cust == 345681) print(1);
Para Transporte, elegiré un compuesto PackageID+Puerto+hora. Esto es un poco más interesante. Podría haber creado un sustituto aquí también, y funcionaría igual de bien.
Pero aquí radica la magia de la indexación. Las claves principales obtienen un índice automáticamente, lo que significa que la búsqueda es mucho más eficiente que las claves principales.
Cuando busque en esta base de datos, la mayoría de las consultas serán del tipo "¿dónde está este paquete?". En otras palabras, dado este ID de paquete, dígame el puerto y la hora en que se encuentra ahora. Necesitaría un índice adicional sobre PackageID si no lo tengo como parte de mi clave principal.
¿Esto suena bien? Paso final, definamos estas 3 tablas en SQL. La sintaxis varía ligeramente según la base de datos que esté utilizando.
Definiendo Claves Primarias en MySQL
CREATE TABLE customers
( customerID INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
last_name VARCHAR(30) NOT NULL,
first_name VARCHAR(25) NOT NULL,
email VARCHAR(50) NOT NULL,
address VARCHAR(300)
);
CREATE TABLE packages
( packageID INT(15) NOT NULL AUTO_INCREMENT,
weight DECIMAL (10, 2) NOT NULL,
content VARCHAR(50),
CONSTRAINT packages_pk PRIMARY KEY (packageID) # An alternative way to above,
# when you want to name the constraint as well.
);
CREATE TABLE transportation
( package INT(15) NOT NULL,
port INT(15) NOT NULL,
time DATE NOT NULL,
PRIMARY KEY (package, port, time),
FOREIGN KEY package
REFERENCES packages(packageID)
ON DELETE RESTRICT # It's good practice to define what should happen on deletion. In this case, I don't want things to get deleted.
);
Definición de claves primarias en PostgreSQL
CREATE TABLE customers
( customerID SERIAL NOT NULL PRIMARY KEY, # In PostgreSQL SERIAL is same as AUTO_INCREMENT - it adds 1 to every new row.
last_name VARCHAR(30) NOT NULL,
first_name VARCHAR(25) NOT NULL,
address TEXT,
email VARCHAR(50) NOT NULL
);
CREATE TABLE packages
( packageID SERIAL NOT NULL,
weight NUMERIC NOT NULL,
content TEXT,
CONSTRAINT packages_pk PRIMARY KEY (packageID) # In PostgreSQL, this alternative way works too.
);
CREATE TABLE transportation
( package INTEGER NOT NULL,
port INT(15) NOT NULL,
time DATE NOT NULL,
PRIMARY KEY (package, port, time),
FOREIGN KEY package
REFERENCES packages(packageID)
ON DELETE RESTRICT # It's good practice to define what should happen on deletion. In this case, I don't want things to get deleted.
);
No es muy diferente, ¿verdad? Una vez que tenga los conceptos básicos, puede aplicarlos a casi cualquier base de datos con solo un vistazo rápido a la documentación. ¡La clave es saber qué buscar!
Buena suerte, joven padawan.
¿Disfrutaste esto? También podría interesarle Cosas que aprendí de un ingeniero de software sénior