Pregunta

Me pregunto cuál es la solución óptima aquí.

Digamos que tengo una base de datos normalizada. La clave principal de todo el sistema es un varchar. Lo que me pregunto es si debo relacionar esta varchar con un int para la normalización o dejarla. Es más sencillo dejarlo como varchar, pero podría ser más óptimo

Por ejemplo, puedo tener

People
======================
name      varchar(10)   
DoB       DateTime    
Height    int  

Phone_Number
======================
name      varchar(10)   
number    varchar(15)

O podría tener

People
======================
id        int Identity   
name      varchar(10)   
DoB       DateTime  
Height    int  

Phone_Number
======================
id        int   
number    varchar(15)  

Agregue varias otras relaciones de uno a muchos, por supuesto.

¿Qué piensan todos ustedes? ¿Cuál es mejor y por qué?

¿Fue útil?

Solución

¿Realmente puedes usar nombres como claves primarias? ¿No hay un alto riesgo de varias personas con el mismo nombre?

Si realmente tienes tanta suerte de que tu atributo de nombre pueda usarse como clave principal, entonces, por supuesto, úsalo. Sin embargo, a menudo, tendrá que inventar algo, como un ID de cliente, etc.

Y finalmente: " NOMBRE " es una palabra reservada en al menos un DBMS, así que considere usar otra cosa, por ejemplo, nombre completo.

Otros consejos

Creo que la mayoría de las personas que han desarrollado aplicaciones de bases de datos del mundo real de tamaño significativo le dirán que las claves sustitutas son la única solución realista.
Sé que la comunidad académica no estará de acuerdo, pero esa es la diferencia entre la pureza teórica y la practicidad.

Cualquier consulta de tamaño razonable que tenga que hacer uniones entre tablas que usen claves no sustitutas donde algunas tablas tienen claves primarias compuestas rápidamente no se puede mantener.

El uso de cualquier tipo de datos no sintéticos (es decir, cualquier cosa del usuario, a diferencia de la generada por la aplicación) como PK es problemático; tiene que preocuparse por las diferencias de cultura / localización, la sensibilidad a las mayúsculas y minúsculas (y otros problemas que dependen de la recopilación de DB), puede dar lugar a problemas en los datos si los datos introducidos por el usuario cambian, etc.

El uso de datos no generados por el usuario (GUID secuenciales (o no secuenciales si su base de datos no los admite o si no le importa la división de páginas) o los ints de identidad (si no necesita GUID)) es mucho más fácil y mucho más seguro.

Con respecto a los datos duplicados: no veo cómo el uso de claves no sintéticas lo protege de eso. Aún tienes problemas donde el usuario ingresa " Bob Smith " en lugar de " Bob K. Smith " o " Smith, Bob " o " bob smith " etc. La administración de la duplicación es necesaria (y casi idéntica) independientemente de si su clave es sintética o no sintética, y las claves no sintéticas tienen una serie de otros posibles problemas que las claves sintéticas evitan perfectamente.

Muchos proyectos no tienen que preocuparse por eso (por ejemplo, las opciones de compilación estrechamente restringidas evitan muchos de ellos), pero en general prefiero las claves sintéticas. Esto no quiere decir que no pueda tener éxito con las claves orgánicas, claramente puede, pero para muchos proyectos no son la mejor opción.

Creo que si su VARCHAR fuera más grande, notaría que está duplicando un poco de datos en toda la base de datos. Mientras que si eligió una columna de ID numérica, no está duplicando casi la misma cantidad de datos al agregar columnas de clave externa a otras tablas.

Además, los datos textuales son un dolor real en términos de comparaciones, su vida es mucho más fácil cuando está haciendo WHERE id = user_id en lugar de WHERE nombre LIKE inputname ( o algo similar).

Si el " nombre " El campo realmente es apropiado como clave principal, entonces hazlo. La base de datos no se normalizará más al crear una clave sustituta en ese caso. Obtendrá algunas cadenas duplicadas para claves externas, pero eso no es un problema de normalización, ya que la restricción FK garantiza la integridad de las cadenas tal como lo haría con las claves sustitutas.

Sin embargo, no está explicando cuál es el " nombre " es. En la práctica, es muy raro que una cadena sea apropiada como clave principal. Si es el nombre de una persona, no funcionará como un PK, ya que más de una persona puede tener el mismo nombre, las personas pueden cambiar nombres, etc.

Una cosa que otros no parecen haber mencionado es que las combinaciones en los campos int tienden a funcionar mejor que las combinaciones en los campos varchar.

Y definitivamente siempre usaría una clave sustituta sobre el uso de nombres (de personas o empresas) porque nunca son únicos en el tiempo. En nuestra base de datos, por ejemplo, tenemos 164 nombres con más de 100 instancias del mismo nombre. Esto muestra claramente los peligros de considerar el uso del nombre como campo clave.

La pregunta original no es de normalización. Si tiene una base de datos normalizada, como indicó, no necesita cambiarla por razones de normalización.

En realidad, hay dos cuestiones en su pregunta. La primera es si es preferible utilizar ints o varchars como claves primarias y foráneas. La segunda es si puede usar las claves naturales indicadas en la definición del problema, o si debe generar una clave sintética (clave sustituta) para reemplazar la clave natural.

Los

ints son un poco más concisos que los varchars, y un poco más eficientes para cosas como el procesamiento de índices. Pero la diferencia no es abrumadora. Probablemente no debería tomar su decisión solo sobre esta base.

La pregunta de si la clave natural proporcionada realmente funciona como una clave natural o no es mucho más importante. El problema de los duplicados en un " nombre " La columna no es el único problema. También está el problema de lo que sucede cuando una persona cambia su nombre. Es probable que este problema no aparezca en el ejemplo que has dado, pero sí aparece en muchas otras aplicaciones de bases de datos. Un ejemplo sería la transcripción durante cuatro años de todos los cursos tomados por un estudiante. Una mujer podría casarse y cambiar su nombre en el transcurso de cuatro años, y ahora estás estancada.

O bien debe dejar el nombre sin cambiar, en cuyo caso ya no está de acuerdo con el mundo real, o actualizarlo retroactivamente en todos los cursos que tomó la persona, lo que hace que la base de datos no esté de acuerdo con las listas impresas hechas en ese momento.

Si decide una clave sintética, ahora tiene que decidir si la aplicación va a revelar el valor de la clave sintética para la comunidad de usuarios. Esa es otra lata de gusanos, y está más allá del alcance de esta discusión.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top