Diseño de base de datos por primera vez: ¿estoy sobreingeniería?


Fondo

Soy estudiante de primer año de CS y trabajo a tiempo parcial para la pequeña empresa de mi padre. No tengo ninguna experiencia en el desarrollo de aplicaciones del mundo real. He escrito scripts en Python, algunos cursos en C, pero nada como esto.

Mi padre tiene un pequeño negocio de capacitación y actualmente todas las clases están programadas, grabadas y seguidas a través de una aplicación web externa. Hay una función de exportación / "informes", pero es muy genérica y necesitamos informes específicos. Nos no tiene acceso a la base de datos real para ejecutar las consultas. Me han pedido que establezca un sistema de informes personalizado.

Mi idea es crear las exportaciones CSV genéricas e importarlas (probablemente con Python) en una base de datos MySQL alojada en la oficina todas las noches, desde donde puedo ejecutar las consultas específicas que se necesitan. No tengo experiencia en bases de datos, pero entiendo lo básico. He leído un poco sobre la creación de bases de datos y formularios normales.

Podemos empezar a tener clientes internacionales pronto, así que quiero que la base de datos no explote si/cuando eso sucede. Actualmente también tenemos un par de grandes corporaciones como clientes, con diferentes divisiones (por ejemplo, la empresa matriz de ACME, ACME healthcare division, ACME bodycare division)

El esquema que se me ha ocurrido es el siguiente:

  1. Desde la perspectiva del cliente:
    • Clientes es la tabla principal
    • Los clientes están vinculados al departamento que trabajan para
      • Los departamentos pueden estar dispersos por un país: Recursos Humanos en Londres, Marketing en Swansea, etc.
      • Los departamentos están vinculados a la división de una empresa
    • Las divisiones están vinculadas a la sociedad matriz
  2. Desde la perspectiva de las clases:
    • Sesiones es la tabla principal
      • Un profesor está vinculado a cada sesión
      • Se le da un statusid a cada sesión. Por ejemplo, 0-Completado, 1 - Cancelada
      • Las sesiones se agrupan en" paquetes " de un tamaño arbitrario
    • Cada paquete se asigna a un cliente

"diseñé" (más bien garabateé) el esquema en un pedazo de papel, tratando de mantenerlo normalizado a la 3a forma. Luego lo conecté a MySQL Workbench y lo hizo todo bonito para mí:
(Haga clic aquí para ver el gráfico de tamaño completo )

Texto alternativo http://maian.org/img/schema.png

Ejemplo consultas que voy a ejecutar

  • Qué clientes con crédito aún quedan están inactivos (aquellos sin una clase programada en el futuro)
  • Cuál es la tasa de asistencia por cliente / departamento / división (medida por el status id en cada sesión)
  • Cuántas clases tiene un profesor en un mes
  • Marque los clientes que tienen baja tasa de asistencia
  • Informes personalizados para los departamentos de recursos humanos con las tasas de asistencia de las personas en su división

Pregunta(s)

  • ¿Esto está sobrecargado o voy en la dirección correcta?
  • ¿La necesidad de unir varias tablas para la mayoría de las consultas resultará en un gran éxito de rendimiento?
  • He añadido una columna 'lastsession' a los clientes, ya que probablemente va a ser una consulta común. ¿Es una buena idea o debo mantener la base de datos estrictamente normalizada?

Gracias por su tiempo

Author: manlio, 2010-02-23

12 answers

Algunas respuestas más a sus preguntas:

1) Estás más o menos en el blanco para alguien que se está acercando a un problema como este por primera vez. Creo que los consejos de otros sobre esta cuestión hasta ahora casi lo cubren. Buen trabajo!

2 & 3) El golpe de rendimiento que recibirá dependerá en gran medida de tener y optimizar los índices correctos para sus consultas / procedimientos particulares y, lo que es más importante, el volumen de registros. A menos que usted está hablando de más de un millones de registros en sus tablas principales parece estar en camino de tener un diseño lo suficientemente convencional como para que el rendimiento no sea un problema en un hardware razonable.

Dicho esto, y esto se relaciona con su pregunta 3, con el comienzo que tiene probablemente no debería estar demasiado preocupado por el rendimiento o la hiper sensibilidad a la ortodoxia de normalización aquí. Este es un servidor de informes que está construyendo, no un backend de aplicación basado en transacciones, que tendría una muy diferente perfil con respecto a la importancia del desempeño o normalización. Una base de datos que respalda una aplicación de registro y programación en vivo debe tener en cuenta las consultas que tardan segundos en devolver los datos. Una función de servidor de informes no solo tiene más tolerancia para consultas complejas y largas, sino que las estrategias para mejorar el rendimiento son muy diferentes.

Por ejemplo, en un entorno de aplicación basado en transacciones, sus opciones de mejora del rendimiento podrían incluir la refactorización de procedimientos y estructuras de tablas al enésimo grado, o desarrollar una estrategia de almacenamiento en caché para pequeñas cantidades de datos comúnmente solicitados. En un entorno de informes, sin duda puede hacer esto, pero puede tener un impacto aún mayor en el rendimiento al introducir un mecanismo de instantáneas donde un proceso programado ejecuta y almacena informes preconfigurados y sus usuarios acceden a los datos de instantáneas sin estrés en su nivel de base de datos por solicitud.

Todo esto es una diatriba larga para ilustrar que los principios y trucos de diseño que emplees pueden diferir dado el papel de la base de datos que estás creando. Espero que sea útil.

 40
Author: Tom Crowe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-23 19:44:49

Tienes la idea correcta. Sin embargo, puede limpiarlo y eliminar algunas de las tablas de asignación (has*).

Lo que puede hacer es añadir CityID y DivisionId en la tabla Departments.

Además de eso, creo que todo está bien...

 14
Author: Reverend Gonzo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-23 18:28:30

Los únicos cambios que haría son:
1-Cambie su VARCHAR a NVARCHAR, si es posible que vaya internacional, es posible que desee unicode.

2 - Cambie su id int a GUIDs (uniqueidentifier) si es posible (esto podría ser solo mi preferencia personal). Suponiendo que finalmente llegue al punto en el que tenga varios entornos (dev/test/staging/prod), es posible que desee migrar datos de uno a otro. Tener ID de GUID hace esto significativamente más fácil.

3-Tres capas para su empresa -> División -> La estructura del departamento puede no ser suficiente. Ahora, esto podría ser sobre-ingeniería, pero usted podría generalizar esa jerarquía tal que usted puede soportar n-niveles de profundidad. Esto hará que algunas de sus consultas sean más complejas, por lo que puede que no valga la pena compensarlas. Además, podría ser que cualquier cliente que tenga más capas puede ser fácilmente "rellenable" en este modelo.

4-También tiene un Estado en la tabla Cliente que es un VARCHAR y no tiene enlace a los Estados tabla. Esperaría un poco más de claridad en cuanto a lo que representa el Estatus de Cliente.

 6
Author: Jacob G,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-23 18:45:55

No. Parece que estás diseñando con un buen nivel de detalle.

Creo que los Países y las Empresas son realmente la misma entidad en su diseño, al igual que las Ciudades y las Divisiones. Me desharía de las tablas de Países y Ciudades (y Cities_Has_Departments) y, si es necesario, agregaría una bandera booleana IsPublicSector a la tabla de Empresas (o una columna CompanyType si hay más opciones que simplemente Sector Privado / Sector Público).

También, creo que hay un error en su uso de la mesa de los Departamentos. Parece que la tabla Departamentos sirve como una referencia a los diversos tipos de departamentos que cada división de clientes puede tener. Si es así, debería llamarse DepartmentTypes. Pero sus clientes (que son, supongo, asistentes) no pertenecen a un TIPO de departamento, sino a una instancia de departamento real en una empresa. Tal como está ahora, sabrá que un cliente dado pertenece a un departamento de recursos humanos en algún lugar, ¡pero no a cuál!

En otras palabras, los clientes deben estar vinculado a la tabla que usted llama Divisions_Has_Departments (pero que yo llamaría simplemente Departamentos). Si esto es así, entonces debe colapsar las ciudades en Divisiones como se discutió anteriormente si desea usar integridad referencial estándar en la base de datos.

 6
Author: Larry Lustig,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-23 20:21:54

Por cierto, vale la pena señalar que si ya está generando CSV y desea cargarlos en una base de datos MySQL, CARGAR DATOS LOCAL INFILE es su mejor amigo: http://dev.mysql.com/doc/refman/5.1/en/load-data.html . Mysqlimport también vale la pena mirar, y es una herramienta de línea de comandos que es básicamente un buen envoltorio alrededor de cargar datos infile.

 5
Author: jrheard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-01 19:59:52

La mayoría de las cosas ya se han dicho, pero siento que puedo agregar una cosa: es bastante común que los desarrolladores más jóvenes se preocupen por el rendimiento un poco demasiado por adelantado, y su pregunta sobre unirse a las tablas parece ir en esa dirección. Este es un anti-patrón de desarrollo de software llamado'Optimización prematura'. Trata de desterrar ese reflejo de tu mente:)

Una cosa más: ¿Crees que realmente necesitas las tablas de' ciudades 'y' países'? No tendría un ¿Las columnas' ciudad 'y' país ' en la tabla departamentos son suficientes para sus casos de uso? Por ejemplo, ¿su solicitud necesita enumerar departamentos por ciudad y ciudades por país?

 3
Author: Hans Westerbeek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-23 20:11:13

Siguientes comentarios basados en el papel como especialista en Inteligencia de Negocios/Informes y gerente de estrategia/planificación:

  1. Estoy de acuerdo con la dirección de Larry arriba. En mi humilde opinión, no está demasiado diseñado, algunas cosas parecen un poco fuera de lugar. Para mantenerlo simple, etiquetaría al cliente directamente a un ID de Empresa, Descripción de Departamento, Descripción de División, ID de Tipo de Departamento, ID de Tipo de División. Use el ID de tipo de Departamento y el ID de tipo de división como referencias a las tablas de búsqueda y campos de informes/análisis internos para una consistencia a largo plazo.

  2. La tabla de paquetes contiene la columna "Crédito", ¿no debería estar vinculada a la tabla de la base de clientes para que si hay muchos paquetes, pueda ver cuánto crédito se debe para las clases futuras? La aplicación puede cuidar el calc y almacenarlo centralmente en la tabla del cliente.

  3. La información de la compañía podría usar muchos más campos, incluida la dirección/teléfono / etc. obvios. información. También estaría preparado para agregar D & B Columnas" DUNs " (Site / Branch / Ultimate) a largo plazo, Dun and Bradstreet (D&B) tiene un enorme catálogo de empresas y más adelante encontrará que su información es muy útil para informes/análisis. Esto se encargará del problema de división múltiple que mencione, y le permitirá enrollar su jerarquía para sub / división / ramas / etc. de gran cuerpo.

  4. No mencionas con cuántos registros trabajarás, lo que podría implicar prepararte para un gran desarrollo iniciativa que se podría haber hecho más rápido y mucho menos dolores de cabeza con el software de "informes" preempaquetado. Si no está tratando con una base de datos grande (

  5. FYI-Reporting insight: para bases de datos grandes, normalmente tiene dos bases de datos instancias a) base de datos de transacciones para registrar cada registro detallado. b) base de datos de informes (data mart/data warehouse) alojada en una máquina separada. Para obtener más información, busque en Google tanto Star Schema como Snowflake Schema.

Saludos.

 3
Author: Will,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-23 21:53:29

Solo quiero abordar la preocupación de que unirse a varias tablas causará un éxito de rendimiento. No tengas miedo de normalizar porque tendrás que hacer joins. Las uniones son normales y esperadas en bases de datos relacionales y están diseñadas para manejarlas bien. Tendrá que establecer relaciones PK / FK (para la integridad de los datos, esto es importante tener en cuenta en el diseño), pero en muchas bases de datos FKs no se indexan automáticamente. Dado que se usarán en las uniones, definitivamente querrá comenzar indexando el FKS. Los PK generalmente obtienen un índice sobre la creación, ya que tienen que ser únicos. Es cierto que el diseño de datawarehouse reduce el número de uniones, pero generalmente uno no llega al punto de almacenamiento de datos hasta que tiene que acceder a millones de registros en un informe. Incluso entonces, casi todos los almacenes de datos comienzan con una base de datos transaccional para recopilar los datos en tiempo real y luego los datos se mueven al almacén en un horario (nocturno o mensual o lo que sea que necesite la empresa ser). Por lo tanto, este es un buen comienzo, incluso si necesita diseñar un almacén de datos más tarde para mejorar el rendimiento del informe.

Debo decir que su diseño es impresionante para un estudiante de primer año de CS.

 2
Author: HLGEM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-24 16:33:27

No está sobre-diseñado, así es como yo abordaría el problema. Unirse está bien, no habrá mucho de un éxito de rendimiento (es completamente necesario a menos que des-normalice la base de datos que no se recomienda!). Para los estados, vea si puede usar un tipo de datos enum en su lugar para optimizar esa tabla.

 1
Author: Chris Dennett,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-23 18:21:04

He trabajado en el dominio de formación / escuela y pensé en señalar que generalmente hay una relación M:1 entre lo que llamas "sesiones" (instancias de un curso dado) y el curso en sí. En otras palabras, su catálogo ofrece el curso ("Español 101" o lo que sea), pero es posible que tenga dos instancias diferentes durante un solo semestre (Tu-Th impartido por Smith, Miércoles-Viernes impartido por Jones).

Aparte de eso, parece un buen comienzo. Apuesto a que encontrará que el cliente el dominio (gráficos que conducen a "clientes") es más complejo de lo que has modelado, pero no exageres con eso hasta que tengas algunos datos reales que te guíen.

 1
Author: Larry OBrien,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-23 18:40:24

Algunas cosas vinieron a la mente:

  1. Las tablas parecían orientadas a la presentación de informes, pero no realmente el funcionamiento del negocio. Creo que cuando un cliente se registra, esencialmente hay un pedido que se coloca para el cliente que asiste a una lista de sesiones, y ese pedido podría ser para varios empleados en una empresa. Parecería que una tabla de "pedidos" realmente estaría en el centro de su sistema y la conducción de su captura de datos y los informes eventuales. (Compare los documentos en papel que ha sido usar para ejecutar el negocio con el diseño de su base de datos para ver si hay una coincidencia lógica.)

  2. Las empresas a menudo no tienen divisiones. Los empleados a veces cambian de divisiones / departamentos, tal vez incluso a mitad de la sesión. Las empresas a veces agregan / eliminan / renombran divisiones / departamentos. Asegúrese de que el posible cambio en tiempo real de los contenidos de sus tablas no dificulta la generación de informes/agrupación posteriores. Con tantos datos de contacto divididos en tantas tablas, es posible que tenga que hacer cumplir muy estricto validación de entrada de datos para mantener sus informes significativos e inclusivos. Por ejemplo, cuando se agrega un nuevo cliente, asegurándose de que su empresa/división/departamento/ciudad coincida con los mismos valores que sus compañeros de trabajo.

  3. El concepto de "packs" no está claro en absoluto.

  4. Dado que indica que es una pequeña empresa, sería sorprendente si el rendimiento fuera un problema, teniendo en cuenta la velocidad y la capacidad de las máquinas actuales.

 0
Author: joe snyder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-28 00:02:09

Gran trabajo!

No, no estás sobre-ingenierizando, lo estás haciendo muy bien. Recuerdo mi primer proyecto, era un sitio web que he aceptado construir a pesar de que no sabía nada de programación. Sin embargo, lo construí. De todos modos, aquí hay algunos consejos útiles mientras se construye el primer diseño de la base de datos;

  • Mantenga las mesas pequeñas (no desperdicie espacio innecesariamente).

  • No busque más información de la que necesita.

  • Si usaMs, tenga cuidado de trampas comunes como el problema N + 1.

  • Manténgase alejado de operadores problemáticos (por ejemplo, como '%Smith%').

  • Diseñe sus índices de manera inteligente y asegúrese de que cubran el la mayoría de los usos (aquí es un decente, si la luz, el tratamiento de índices).

  • Recuerde que las consultas basadas en conjuntos suelen ser muy superiores en términos de rendimiento que iterar a través de los datos.

  • Saber cuándo desnormalizar los datos para el rendimiento motivo.

  • Dolor todo lo que se puede almacenar en caché (económicamente) para aliviar la base de datos.

Sin embargo, también hay muchas herramientas que pueden ayudarlo. Por ejemplo, estoy usando SQLDbm que me parece más eficaz.

SQLDBM le ofrece una manera fácil y conveniente de diseñar su base de datos absolutamente en cualquier lugar en cualquier navegador, trabajando sin necesidad de ningún motor de base de datos adicional o herramientas o aplicaciones de modelado de base de datos. Utilice SQLDBM para diseñar y administrar tanto grandes como pequeños bases de datos y modelos de datos sobre la marcha. Todo ello incorporando las reglas y objetos de base de datos necesarios, como claves de base de datos, esquemas, índices, restricciones de columna y relaciones.

 0
Author: halcosho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-29 10:05:43