Normalizar sus tablas operativas como lo sugiere Transact Charlie, es una buena idea, y ahorrará muchos dolores de cabeza y problemas con el tiempo, pero existen tablas de interfaz , que admiten la integración con sistemas externos, y tablas de informes , que admiten cosas como análisis Procesando; y esos tipos de tablas no necesariamente deben normalizarse ; de hecho, muy a menudo es mucho, mucho más conveniente y eficaz para que no lo sean .
En este caso, creo que la propuesta de Transact Charlie para sus tablas operativas es buena.
Pero agregaría un índice (no necesariamente único) a CompetitorName en la tabla Competidores para admitir uniones eficientes en CompetitorName con fines de integración (carga de datos de fuentes externas), y pondría una tabla de interfaz en la mezcla: CompeticiónResultados.
Los resultados de la competencia deben contener los datos que contengan los resultados de su competencia. El objetivo de una tabla de interfaz como esta es hacer que sea lo más rápido y fácil posible truncar y volver a cargarlo desde una hoja de Excel o un archivo CSV, o cualquier forma en la que tenga esos datos.
Esa tabla de interfaz no debe considerarse parte del conjunto normalizado de tablas operativas. Luego puede unirse a CompetResults como lo sugiere Richard, para insertar registros en Competidores que aún no existen, y actualizar los que sí existen (por ejemplo, si realmente tiene más información sobre competidores, como su número de teléfono o dirección de correo electrónico).
Una cosa que señalaría: en realidad, el nombre de la competencia, me parece, es muy poco probable que sea único en sus datos . En 200,000 competidores, es muy posible que tenga 2 o más David Smiths, por ejemplo. Por lo tanto, le recomendaría que recopile más información de los competidores, como su número de teléfono o una dirección de correo electrónico, o algo que sea más probable que sea único.
Su tabla operativa, Competidores, solo debe tener una columna para cada elemento de datos que contribuya a una clave natural compuesta; por ejemplo, debe tener una columna para una dirección de correo electrónico principal. Pero la tabla de interfaz debe tener un espacio para los valores antiguos y nuevos para una dirección de correo electrónico principal, de modo que el valor anterior se pueda usar para buscar el registro en Competidores y actualizar esa parte al nuevo valor.
Por lo tanto, los resultados de la competencia deben tener algunos campos "antiguos" y "nuevos": correo electrónico antiguo, correo electrónico nuevo, teléfono antiguo, teléfono nuevo, etc. De esa manera puede formar una clave compuesta, en Competidores, desde Nombre de competidor, Correo electrónico y Teléfono.
Luego, cuando tenga algunos resultados de la competencia, puede truncar y volver a cargar su tabla de Resultados de Competencia desde su hoja de Excel o lo que sea que tenga, y ejecutar una inserción única y eficiente para insertar a todos los nuevos competidores en la tabla de Competidores, y una actualización única y eficiente para actualizar toda la información sobre los competidores existentes de los Resultados de la competencia. Y puede hacer una sola inserción para insertar nuevas filas en la tabla CompetitionCompetitors. Estas cosas se pueden hacer en un procedimiento almacenado ProcessCompetitionResults, que se puede ejecutar después de cargar la tabla CompetitionResults.
Esa es una especie de descripción rudimentaria de lo que he visto hacer una y otra vez en el mundo real con Oracle Applications, SAP, PeopleSoft y una larga lista de otras suites de software empresarial.
Un último comentario que haría es uno que he hecho antes sobre SO: si crea una clave foránea que asegura que existe un competidor en la tabla de competidores antes de poder agregar una fila con ese competidor en CompetitionCompetitors, asegúrese de que la clave externa se establece en actualizaciones y eliminaciones en cascada . De esa manera, si necesita eliminar un competidor, puede hacerlo y todas las filas asociadas con ese competidor se eliminarán automáticamente. De lo contrario, de forma predeterminada, la clave externa requerirá que elimine todas las filas relacionadas de CompetCompetitors antes de permitirle eliminar un Competidor.
(Algunas personas piensan que las claves externas no en cascada son una buena precaución de seguridad, pero mi experiencia es que solo son un dolor en el trasero que con frecuencia son simplemente el resultado de un descuido y crean un montón de trabajo). para DBA. Al tratar con personas que eliminan accidentalmente cosas, es por eso que tiene cosas como cuadros de diálogo "¿está seguro?" y varios tipos de copias de seguridad regulares y fuentes de datos redundantes. Es mucho, mucho más común querer eliminar un competidor, cuyos datos son todos en mal estado, por ejemplo, que eliminar accidentalmente uno y luego decir "¡Oh, no! ¡No quise hacer eso! ¡Y ahora no tengo los resultados de su competencia! ¡Aaaahh!" , debes estar preparado para ello, pero el primero es mucho más común,así que la manera más fácil y mejor de prepararse para la primera, imo, es simplemente realizar actualizaciones y eliminaciones en cascada de claves foráneas).
NVARCHAR(64)
columna su clave principal (y por lo tanto: agrupación)! En primer lugar, es una clave muy amplia , hasta 128 bytes; y en segundo lugar, es de tamaño variable, de nuevo: no es óptimo ... Esta es la peor opción que puede tener: su rendimiento será un infierno, y la fragmentación de tablas e índices estará en 99.9% todo el tiempo .....