250 votes

Conception de base de données de première fois : je suis toute ?

Arrière-plan

Je suis en première année de CS étudiant et je travaille à temps partiel pour mon papa d'une petite entreprise. Je n'ai pas d'expérience dans le monde réel de développement d'applications. J'ai écrit des scripts en Python, certains cours en C, mais rien de ce genre.

Mon père a un petit secteur de formation et actuellement toutes les classes sont organisées en, de les enregistrer et d'un suivi par le biais d'un web externe de l'application. Il y a un export/"rapports" fonctionnalité, mais il est très générique et nous avons besoin de rapports spécifiques. Nous n'avons pas accès à la base de données pour exécuter les requêtes. J'ai été demandé de mettre en place un système de rapports personnalisés.

Mon idée est de créer le générique CSV exportations et des importations (probablement avec Python) dans une base de données MySQL hébergée dans le bureau tous les soirs, d'où je peux exécuter les requêtes spécifiques qui sont nécessaires. Je n'ai pas d'expérience dans les bases de données, mais de comprendre l'essentiel. J'ai lu un peu sur la création de la base et formes normales.

On peut commencer à avoir des clients internationaux, à bientôt, donc, je veux que la base de données pour ne pas exploser si/quand ça arrive. Nous avons aussi actuellement un couple de grandes entreprises en tant que clients, à des divisions différentes (par exemple ACME société mère, ACME division des soins de santé, l'ACME le corps de la division)

Le schéma que j'ai est le suivant:

  1. Du point de vue du client:
    • Les Clients sont au centre de la table
    • Les Clients sont liés au ministère qu'ils travaillent pour
      • Les départements peuvent être dispersés autour d'un pays: HR à Londres, le Marketing à Swansea, etc.
      • Les ministères sont liés à la division d'une société
    • Les Divisions sont liés à la société mère
  2. Du point de vue des classes:
    • Les Sessions est la table principale
      • Un enseignant est lié à chaque session
      • Un statusid est donné à chaque session. E. g. 0 - Terminé, 1 - Annulé
      • Les séances sont regroupés dans des "packs" d'une taille arbitraire
    • Chaque packs est attribuée à un client

J'ai "dessiné" (plus comme griffonné) le schéma sur une feuille de papier, en essayant de garder normalisée à la 3e. J'ai ensuite branché sur MySQL Workbench et il fait tout beau pour moi:
(Cliquez ici pour connaître la taille d'graphique)

alt text

Exemple de requêtes, je vais être en cours d'exécution

  • Les clients avec un crédit encore à gauche sont inactifs (ceux sans une classe prévue dans l'avenir)
  • Quel est le taux de fréquentation par client/département/division (mesurée par l'id d'état à chaque séance)
  • Combien de classes a un enseignant avait dans un mois
  • D'identifier les clients qui ont un faible taux de participation
  • Des rapports personnalisés pour les départements de ressources humaines avec un taux de fréquentation de personnes dans leur division

Question(s)

  • Est-ce overengineered ou suis-je dirigé dans le bon sens?
  • Le besoin de rejoindre plusieurs tables pour la plupart des requêtes résultat dans un grand gain de performance?
  • J'ai ajouté un " lastsession colonne de clients, ce qui est probablement va être une commune de la requête. Est-ce une bonne idée ou dois-je garder la base de données strictement normalisée?

Merci pour votre temps

43voto

Tom Crowe Points 296

Certains plus de réponses à vos questions:

1) Vous êtes un peu sur la cible pour quelqu'un qui s'approche d'un problème comme celui-ci pour la première fois. Je pense que les pointeurs de les autres sur cette question jusqu'à présent assez bien le couvrir. Good job!!!

2 & 3) L'impact sur les performances, vous prendrez en va en grande partie dépendre de l'avoir et de l'optimisation de l'index droit pour vos requêtes / procédures et, plus important encore, le volume des documents. Sauf si vous parlez plus d'un million d'enregistrements dans les tables principales vous semblez être sur la bonne voie pour avoir suffisamment mainstream de la conception que de la performance ne sera pas un problème raisonnables de matériel.

Cela dit, et cela se rapporte à votre question 3, avec le début vous avez sans doute vous ne devrait pas vraiment être trop inquiet au sujet de la performance ou de l'hyper-sensibilité à la normalisation de l'orthodoxie ici. C'est un serveur de rapports que vous créez, pas une opération en fonction de l'application en arrière-plan, ce qui aura un profil différent à l'égard de l'importance de la performance ou de la normalisation. Une base de données de la sauvegarde d'un live de l'inscription et de la programmation de l'application est d'être conscient de requêtes qui prennent quelques secondes pour renvoyer les données. Pas seulement un rapport à la fonction de serveur d'avoir plus de tolérance pour la complexité et la longueur des requêtes, mais les stratégies pour améliorer les performances sont très différentes.

Par exemple, dans une transaction application en fonction de votre environnement d'amélioration de la performance options peuvent inclure de refactoring vos procédures stockées et des structures de table au énième degré, ou l'élaboration d'une stratégie de mise en cache pour les petites quantités de couramment données demandées. Dans un environnement de création de rapports vous pouvez certainement le faire, mais vous pouvez avoir encore plus d'impact sur la performance par l'introduction d'un mécanisme instantané où un processus planifié s'exécute et magasins de rapports préconfigurés et à vos utilisateurs un accès instantané à des données sans stress sur votre db de niveau par demande.

Tout cela est un travail de longue haleine coup de gueule pour illustrer le fait que ce que les principes de conception et des astuces qui vous emploient peuvent varier étant donné le rôle de la db que vous êtes en train de créer. J'espère que c'est utile.

14voto

Reverend Gonzo Points 15504

Vous avez la bonne idée. Vous pouvez cependant le nettoyer et supprimer certaines des tables de mappage (has *).

Ce que vous pouvez faire est dans la table Departments, ajoutez CityId et DivisionId.

A part ça, je pense que tout va bien ...

6voto

Larry Lustig Points 28706

Pas de. Il semble que vous êtes en train de concevoir un bon niveau de détail.

Je pense que les Pays et les Entreprises sont vraiment de la même entité, dans votre conception, comme le sont les Villes et les Divisions. Je voudrais me débarrasser du Pays et les Villes, les tables (et Cities_Has_Departments) et, si nécessaire, ajouter un indicateur booléen IsPublicSector à la table Sociétés (ou un CompanyType colonne s'il y a plus de choix que de simplement le Secteur Privé / Secteur Public).

Aussi, je pense qu'il y a une erreur dans l'usage de la les Ministères de la table. Il ressemble à de la les Ministères de la table, qui sert de référence pour les différents types de ministères que chaque client division peut avoir. Si oui, il doit être appelé DepartmentTypes. Mais vos clients (qui sont, je suppose, participants) n'appartiennent pas à un service de TYPE, ils appartiennent à une réelle département instance dans une entreprise. Comme il est maintenant, vous savez qu'un client appartient à un département RH quelque part, mais pas n'importe lequel!

En d'autres termes, les Clients devraient être lié à la table que vous appelez Divisions_Has_Departments (mais que je voudrais appeler tout simplement Départements). Si c'est le cas, alors vous devez réduire Villes en Divisions, comme discuté ci-dessus si vous souhaitez utiliser la norme de l'intégrité référentielle de la base de données.

6voto

Jacob G Points 2666

Les seuls changements que j'aimerais faire:
1 - Changer de type VARCHAR NVARCHAR, si vous peut-être aller internationale, vous pouvez unicode.

2 - Changez votre int id de Guid (de type uniqueidentifier) si possible (c'est peut-être juste ma préférence personnelle). En supposant que vous arrivez au point où vous avez de multiples environnements (dev/test/mise en scène/prod), vous pouvez migrer les données de l'un à l'autre. Ont GUID Id rend ce beaucoup plus facile.

3 - Trois couches pour votre Entreprise -> Division -> Ministère de la structure peut-être pas assez. Maintenant, c'est peut-être trop de génie, mais on pourrait généraliser cette hiérarchie telle que vous pouvez en charge la n-niveaux de profondeur. Cela permettra d'effectuer certaines de vos requêtes plus complexes, de sorte que ne peut pas être une valeur de l'échange. De plus, il se pourrait que tout client qui a plus de couches peut être facilement "stuffable" dans ce modèle.

4 - Vous avez également un Statut dans la Table des Clients qui est un VARCHAR et n'a pas de lien vers les Statuts de la table. Je m'attends à un peu plus de clarté il y a à ce que le Statut de Client représente.

5voto

jrheard Points 41

En passant, il est intéressant de noter que si vous générez déjà des fichiers CSV et que vous voulez les charger dans une base de données mySQL, LOAD DATA LOCAL INFILE est votre meilleur ami: http://dev.mysql.com/doc/refman/5.1/ fr / load-data.html . Mysqlimport est également intéressant à regarder, et est un outil de ligne de commande qui est essentiellement un bon emballage autour de l'infile de données de charge.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X