Question

Je vais avoir du mal à comprendre exactement comment placer les bonnes limites pour quand et où utiliser les tables recherche dans une base de données. La plupart des sources que j'ai regardé dire que je ne pourrai jamais avoir trop mais, à un moment donné, il semble que la base de données serait divisée en autant de morceaux que, alors qu'il peut être efficace, il n'est plus facile à gérer. Voici un exemple de ce que jeté ensemble, je travaille avec:

Le mot Let j'ai une table appelée employés:

ID  LName   FName   Gender  Position
1   Doe     John    Male    Manager
2   Doe     Jane    Female  Sales
3   Smith   John    Male    Sales

Faire semblant un instant que les données est plus complexe et contient des centaines de lignes. La chose la plus évidente, je vois que pourrait être déplacé à une table de consultation serait position. Je pourrais créer une table appelée positions et coller les clés étrangères de la table Positions dans la table Employés dans la colonne de position.

ID  Position
1   Manager
2   Sales

Mais jusqu'où puis-je continuer à briser les informations en plus petites tables de consultation avant qu'il ne devienne impossible à gérer? Je pourrais créer une table de genre et un 1 correspondent à Male et 2 correspondent à des femmes dans une table de recherche distincte. Je pourrais même mettre LNames et fnames dans les tables. Toutes les entrées « John » sont remplacés par une clé étrangère de 1 qui pointe vers la table FName qui dit un ID de 1 correspond à John. Si vous descendez ce trou de lapin trop loin comme ça, cependant, votre table Employés est alors réduit à un gâchis de clés étrangères:

ID  LName   FName   Gender  Position
1   1       1       1       1
2   1       2       2       2
3   2       1       1       2

Bien que cela pourrait ou non être plus efficace pour un serveur à traiter, cela est certainement illisible pour une personne normale qui peut essayer de le maintenir et le rend plus difficile pour un développeur d'applications en essayant d'y accéder. Donc, ma vraie question est de savoir jusqu'où est trop loin? Y at-il des « meilleures pratiques » pour ce genre de chose ou un bon ensemble de directives quelque part? Je ne peux trouver aucune information en ligne qui cloue vraiment un bon ensemble de lignes directrices utilisables pour cette question que je vais avoir. la conception de base de données est vieux chapeau pour moi, mais la conception de base de données bien est très nouveau donc trop de réponses techniques peuvent être sur ma tête. Toute aide serait appréciée!

Était-ce utile?

La solution

Mais jusqu'où puis-je continuer à briser les informations en plus petites tables de référence avant qu'il ne devienne impossible à gérer? Je pourrais créer un genre table et possède un 1 correspondent à un mâle et 2 correspondent à des femmes en une table de consultation séparée.

Vous mélangez deux questions différentes. Une question est l'utilisation d'une table « de recherche »; l'autre est l'utilisation des clés de substitution (numéros d'identification).

Commencez par ce tableau.

ID  LName   FName   Gender  Position
1   Doe     John    Male    Manager
2   Doe     Jane    Female  Sales
3   Smith   John    Male    Sales

Vous pouvez créer une table « de recherche » pour des postes comme celui-ci.

create table positions (
  pos_name varchar(10) primary key
);

insert into positions
select distinct position 
from employees;

alter table employees
add constraint emp_fk1
foreign key (position) 
  references positions (pos_name);

Votre apparence de table originale exactement comme il l'a fait avant de créer la table « de recherche ». Et la table des employés exige pas joint supplémentaire pour obtenir des données utiles, lisibles par l'homme hors de lui.

En utilisant une table « de recherche » se résume à ceci: Votre besoin d'application sur le contrôle des valeurs d'entrée qu'une référence clé étrangère fournit? Si oui, alors vous pouvez toujours utiliser une table « de recherche ». (Peu importe s'il utilise une clé de substitution.)

Dans certains cas, vous serez en mesure de remplir complètement cette table au moment de la conception. Dans d'autres cas, les utilisateurs doivent être en mesure d'ajouter des lignes à cette table à exécution. (Et vous aurez probablement besoin d'inclure des processus administratifs pour examiner de nouvelles données.) Genre, qui a fait une norme ISO , peut être complètement peuplé au moment de la conception. Les noms de rue pour les commandes de produits internationaux en ligne ont probablement à ajouter au moment de l'exécution.

Autres conseils

Dans votre table Employés, je voudrais seulement avoir une recherche pour « Position », car un nombre limité de données qui peuvent se développer.

  • Le genre est auto décrit (par exemple M ou F), limité à 2 valeurs, et peut être appliquée avec une contrainte CHECK. Vous n'ajouter de nouveaux Genders (en ignorant Bollocks politiquement correct)
  • Le premier nom « John » ne fait pas partie d'un nombre limité, ensemble de données restreint: l'ensemble potentiel des données est massive au point de manière efficace sans limite donc il ne devrait pas être une recherche

Si vous souhaitez ajouter une nouvelle position vous suffit d'ajouter une ligne à la table de consultation. Cela supprime également qui est un point de normalisation

En outre, une fois que vous avez un million d'employés, alors il est plus efficace de tinyint stocké PositionID que varchar.

Nous allons ajouter une nouvelle colonne « monnaie salaire ». J'utilise une table de correspondance ici avec une clé de CHF, GBP, EUR, USD etc: Je ne voudrais pas utiliser une clé de substitution. Cela pourrait se limiter à une contrainte CHECK comme le genre, mais il est un ensemble limité de données extensible encore comme position. Je donne cet exemple à cause de j'utiliser la clé naturelle même si elle apparaît dans un million de lignes de données des employés en dépit d'être char (3) plutôt que tinyint

Donc, pour résumer, vous utilisez des tables lookup

  1. où vous avez fini, mais les données de réglage extensibles dans une colonne
  2. où est auto n'est pas la description

La réponse est « ça dépend ». Pas très satisfaisant, mais il y a beaucoup d'influences poussée et de traction la conception. Si vous avez des programmeurs d'applications de concevoir la base de données d'une structure comme vous décrivez fonctionne pour eux parce que le ORM cache la complexité. Vous serez tirer vos cheveux lorsque vous écrivez des rapports et devez joindre des tables de dix pour obtenir une adresse.

Conception pour l'utilisation, l'utilisation prévue et l'utilisation future probable. C'est là votre connaissance du processus d'affaires entre en jeu. Si vous concevez une base de données pour une entreprise vétérinaire, il y a des hypothèses raisonnables au sujet de la taille, l'utilisation et les directions dans les fonctionnalités qui seront tout à fait différent d'un démarrage de haute technologie.

Pour réutiliser une citation préférée

« Un homme sage m'a dit » Normaliser jusqu'à ce que ça fait mal, jusqu'à ce que cela fonctionne dénormaliser ».

Quelque part il y a le sweet spot. Mon expérience a été que d'avoir une id clé dans plus d'une table n'est pas aussi grave crime a comme certains le pensent si vous ne changez jamais les clés primaires.

Prenez cet exemple abrégé des tables très normalisées à partir d'un système réel

CREATE TABLE PROPERTY
(ID                          NUMBER(9)           NOT NULL);

CREATE TABLE PROPERTY_TYPE
(ID                          NUMBER(9)           NOT NULL);

CREATE TABLE PROPERTY_LOCALE 
PROPERTY_ID                  NUMBER(9)           NOT NULL,
(LOCALE_ID                   NUMBER(9)           NOT NULL,  --language 
VALUE                        VARCHAR2(200)       NOT NULL);

CREATE TABLE PROPERTY_DEPENDENCY
(PROPERTY_ID                 NUMBER(9)           NOT NULL,
 PARENT_PROPERTY_ID          NUMBER(9)                   ,
 PROPERTY_TYPE_ID            NUMBER(9)           NOT NULL);

Ces tableaux mis en place une liste chaînée des propriétés individuelles et les propriétés de l'enfant parent et ils sont utilisés ici

  CREATE TABLE CASE_PROPERTY
  (ID                        NUMBER(9)           NOT NULL,
  PARENT_ID                  NUMBER(9),
  CASE_ID                    NUMBER(9)           NOT NULL,
  PROPERTY_ID                NUMBER(9),
  PROPERTY_TYPE_ID           NUMBER(9)           NOT NULL);

Cela ressemble bien: obtenir tous les cas avec un property_id dans un sélectionner

Il faut que ça une liste à choisir

 Select pl.value, pd.property_id
 from property_locale pl, property_dependency pd
 where pl.property_id = pd.property_id
 and pd.property_type_id = 2;  --example number

Maintenant, essayez de sélectionner toutes les propriétés d'une affaire si elle a property_types de 3 et 4 et 5, ou non ...

SELECT   cp2.case_id,
         (SELECT   pl.VALUE
            FROM   case_property cp, property_locale pl
           WHERE       cp.property_id = pl.property_id
                   AND CP.PROPERTY_TYPE_ID = 2
                   AND pl.locale_id = 2
                   AND cp.case_id = cp2.case_id)
            AS VALUE1,
         (SELECT   pl.VALUE
            FROM   case_property cp, property_locale pl
           WHERE       cp.property_id = pl.property_id
                   AND CP.PROPERTY_TYPE_ID = 34
                   AND pl.locale_id = 2
                   AND cp.case_id = cp2.case_id)
            AS VALUE2,
         (SELECT   pl.VALUE
            FROM   case_property cp, property_locale pl
           WHERE       cp.property_id = pl.property_id
                   AND CP.PROPERTY_TYPE_ID = 4
                   AND pl.locale_id = 2
                   AND cp.case_id = cp2.case_id)
            AS VALUE3
  FROM   case_property cp2
 WHERE   cp2.case_id = 10293  

Ce que fait mal ... même lorsque vous utilisez des moyens plus élégants de traiter cette question. Cependant, ajouter un peu de de normalisation en brisant les propriétés qu'un cas aura un seul property_id et cela pourrait être beaucoup mieux.

Pour savoir quand vous avez trop de tables ou pas assez essayez interrogation de la base de questions de l'application, un rapport et une année à l'analyse de l'année utilisera.

Licencié sous: CC-BY-SA avec attribution
Non affilié à dba.stackexchange
scroll top