Soy novato y estoy diseñando con ayuda de gnzsoloyo una base de datos, pero no se como meterle mano a las claves primarias, y buscando me he encontrado este artículo, a ver que os parece y me interesa saber sobre todo como diseñais vosotros las claves primarias de las entidades maestras como de las entidades que surgen de las interrelaciones muchos a muchos.
Cómo elegir la clave primaria de una tabla
Temas: Oracle Programacion SQL
Juan Mellado, 23 Febrero, 2007 - 22:20
SQLA veces tengo la impresión de que elegir las columnas que constituirán la clave primaria de una tabla es una decisión que suele tomarse muy a la ligera, cuando la realidad es que la correcta elección de las claves primarias es un factor decisivo para poder construir un modelo relacional de base de datos bien formado, coherente, mantenible y fácilmente ampliable. Lo más irónico del asunto es que en realidad resulta una tarea muy sencilla si se comprende que ningún valor tomado del dominio que estamos intentando modelar sirve para identificar unívocamente a los registros en base de datos. Dicho de otra forma, no puede utilizarse como clave primaria una columna que contenga información que tenga significado para los usuarios; hay que crear una columna expresamente para la clave primaria. O dicho de una tercera forma, si tiene que crear una tabla de personas no utilice DNI como clave primaria.
¿Pero por qué no es una buena idea elegir DNI como clave primaria?, ¿acaso ese número no nos identifica de forma unívoca?. Pues sí, pero rotundamente NO. Piense por ejemplo que los menores de edad o los ciudadanos de otros paises no tienen normalmente un carnet de identidad, y todo ello sin mencionar además el hecho de que los números del DNI no son únicos, históricamente la misma numeración se ha reutilizado en distintas personas.
Puede que en este momento esté pensando en alternativas muy inteligentes para tratar de resolver los problemas que se plantean en el párrafo anterior, posiblemente mediante la incorporación de nuevas columnas a la clave primaria, pero créame, déjelo, el esfuerzo será inútil, la realidad es que los problemas no desaparecerán, se incrementarán. Por ejemplo, podemos pensar que podremos almacenar menores de edad en nuestra tabla si añadimos una nueva columna a la clave primaria que nos indique si en realidad el DNI es suyo o de su representante legal. Pero ocurre que una persona puede tener varios hijos, con lo cual necesitariamos otra nueva columna para distinguirlos. También podemos pensar que podremos almacenar personas de distintos paises si añadimos una nueva columna que nos indique la nacionalidad de cada persona, permitiendo así además que un mismo número se repita para personas de distintos paises. Pero ocurre que una persona puede tener varias nacionalidades. Y así, vuelta a empezar. Lo normal es que siguiendo esta línea de razonamiento se acabe necesitando facilmente 7 u 8 columnas más.
En lineas generales no se deben utilizar claves primarias compuestas en las tablas maestras, es decir, claves formadas por varias columnas en las tablas que almacenan las entidades básicas que gestiona un sistema. Complica los modelos haciéndolos difíciles de mantener y ampliar. Piense en el ejemplo anterior, en si persitieramos en nuestra idea original de utilizar DNI como clave primaria, de forma que el día de mañana nos encontráramos un problema de los antes citados, y que además lo solucionáramos añadiendo un nuevo campo a la clave primaria. Pues ocurriría que tendriamos que añadir ese nuevo campo a todas las tablas y procesos que hicieran referencia a la tabla de personas. El cambio no sería único y localizado, si no que se expandería como una enfermedad contagiosa por todas las entidades y procesos del sistema que tuvieran algún tipo de relación con la tabla de personas.
Hay que tener cuidado con las claves compuestas, sobre todo porque a veces se presentan camufladas bajo la apariencia de lo que normalmente se denominan "códigos inteligentes". Un código inteligente es la unión de varias claves en una sola columna, o sea, una clave primaria compuesta con piel de cordero. Un ejemplo típico de este tipo de código son los localizadores, como el de una entrada de cine en la que figura "S07-F12-B08", lo que vendría a significar "Sala 7" (S07) "Fila 12" (F12) "Butaca 8" (B08). Este tipo de composición se utiliza a veces para identificar las entidades por su ubicación, suponiendo el hecho de que sólo puede haber una entidad en un mismo sitio a un mismo tiempo. El principal problema que plantea este tipo de clave primaria es que a veces, en el mundo real, las entidades se extravían y acaban en localizaciones distintas a las que indican sus códigos, siendo necesario cambiar las claves primarias en la tabla principal y en todas las tablas en las que aparezcan referenciadas, lo que puede ser bastante laborioso, por no decir engorroso y proclive a errores.
El párrafo anterior nos da las dos últimas pistas definitivas para entender el por qué no hay que utilizar DNI como clave primaria de la tabla de personas. La primera pista es que una clave primaria nunca puede depender de información introducida manualmente. Si se hace depender el valor de una clave primaria de lo que escriba un usuario se está creando una dependencia brutal de éste con el funcionamiento interno del sistema. El acoplamiento entre capas de una aplicación siempre debe ser débil, de forma que se pueda modificar cada componente de forma individual sin afectar al resto, y en consecuencia, las reglas que rigen el mundo real no tienen porque influir en las que se establecen en el interior de una aplicación. Si la clave primaria de la tabla persona fuera DNI, y el día de mañana se decidiera utilizar el NIF, entonces se tendría que cambiar todo el modelo y los procesos para gestionar la clave como un campo alfanumérico en vez de como sólo nunérico. Si DNI no fuera clave entonces bastaría con cambiar ese campo concreto de forma aislada.
La segunda pista es que una clave primaria nunca ha de poder modificarse. La clave primaria de un registro identifica de forma unívoca a un objeto dentro del dominio que se está modelando. Si se cambia la clave primaria de un registro se produce una "mutación" por la cual el registro pasa a representar a otro objeto. Este aspecto quizás sea un poco sutil de entender, sobre todo por que conlleva cierto nivel de abstracción. Una persona se podría decir que es la suma de sus características individuales, así como del lugar que ocupa en cualquiera de las dimensiones en las que se proyecta (y posiblemente de su ausencia en las dimensiones en las que no se proyecta). Es una entidad, un ser único y distinguible. Su clave primaria ha de identificarlo de forma unívoca, si se cambia representaría otra entidad, no al individuo original. Piense en términos de variables, como las que se utilizan normalmente en cualquier lenguaje de programación. Primero se definen, y luego se les puede cambiar su contenido, de igual forma que una persona puede cambiarse de ropa o de peinado. Las variables siempren hacen referencia a una misma información concreta, independientemente del valor que contengan en un momento dado. Con las personas ocurre lo mismo, da igual el peinado o la ropa que llevemos, e incluso donde nos encontremos, por encima de todo seguimos siendo nosotros mismos, no otros. Si a una persona se le cambia su DNI porque se introdujo un número equivocado en el alta, debe seguir siendo la misma entidad que se insertó originalmente en el sistema, no otra distinta que implique una actualización masiva de las relaciones.
En definitiva, la forma correcta de identificar las entidades en una tabla es utilizar un código o identificador único que carezca de significado en el mundo real. Un simple valor numérico generado de forma secuencial es suficiente. La idea es crear una tabla con una primera columna de tipo numérico que sirva como clave primaria. En el ejemplo inicial, la tabla de personas, podría ser algo como: ID_PERSON NUMBER(10) NOT NULL. De forma que cuando se inserte una primera persona en la tabla se le asigne el valor 1 como clave primaria (ó 1527, es indistinto). Cuando se inserte una nueva persona se le asigne el 2 (ó 1528). Y así sucesivamente. De esta forma no hay posibilidad de conflictos, o lo que es lo mismo, de encontrarse con errores por claves primarias duplicadas. Cada persona queda emparejada con un identificador que le distingue unívocamente del resto. Y lo dicho para persona sirve para cualquier tipo de entidad. Un motor no se identifica por su número de bastidor, sino por su clave primaria. Un televisor no se identifica por su número de serie, sino por su clave primaria. Una factura no se identifica por su número, sino por su clave primaria. Un usuario no indentifica por su nombre, sino por clave primaria. ¿Captan la idea?
[URL="http://www.inmensia.com/blog/20070223/elegir_clave_primaria_tabla_base_datos_oracle.html "]http://www.inmensia.com/blog/20070223/elegir_clave_primaria_tabla_base_datos_oracle.html[/URL]