2015-04-14 1 views
0

J'ai une table existante qui est trop grande pour être traitée. J'ai essayé de le diviser en deux tables, et toujours pas satisfait.comment diviser cette table de base de données existante pour réduire la redondance

Voici le look de table comme, (package_id est une clé étrangère à la table d'emballage),

child_company title_category title_level revision start_date package_id 
--------------------------------------------------------------------------- 
    c1    manager   senior  0  2015/1/1 120 
    c1    manager   senior  1  2014/7/1 119 
    c1    architect  senior  0  2014/7/1 70 

    c2    architect  junior  0  2015/3/1 70 

    c3    manager   senior  0  2015/1/1 120 
    c3    manager   senior  1  2014/7/1 119 

    c4    manager   senior  0  2015/2/1 122 
    c4    manager   senior  1  2014/2/1 102 
    c4    manager   senior  2  2013/7/1 101 

    c5    manager   senior  0  2015/1/1 120 
    c5    manager   senior  1  2014/7/1 119 

Le problème avec ce tableau est que, de nombreuses entreprises d'enfants ont des informations de salaire similaires et leur histoire. (L'historique est indiqué par revision, revision = 0 indique l'information salariale actuelle.). Par exemple, c1, c3, et c5 ont tous deux la même rémunération pour les cadres supérieurs.

Quelle est la meilleure façon de fractionner ce tableau pour réduire la redondance?

J'ai essayé de le diviser comme ce

child_company title_category title_level group_id 
-------------------------------------------------------- 
    c1    manager   senior  0 
    c1    architect  senior  1 
    c2    architect  junior  2 
    c3    manager   senior  0 
    c4    manager   senior  3 
    c5    manager   senior  0 

Et

id  group_id start_date package_id 
1  0  2015/1/1 120 
2  0  2014/7/1 119 
3  1  2014/7/1 70 
4  2  2015/3/1 70 
5  3  2015/2/1 122 
6  3  2014/2/1 102 
7  3  2013/7/1 101 

meilleures solutions? Merci

+0

Quelle est la taille de cette table? Quels sont les goulots d'étranglement que vous rencontrez? Il est difficile d'imaginer qu'une telle table soit si grande que la décomposer en différentes tables soit la bonne solution. Généralement, les bases de données relationnelles offrent d'autres méthodes pour gérer des tables plus grandes. –

+0

Quelles sont les relations de chaque colonne? Il semble que vous puissiez déplacer Title (title_category et title_level) dans sa propre table, mais je ne connais pas assez la structure pour vous aider. – druidicwyrm

+0

Eh bien, c'est juste un exemple, la vraie table a environ un demi-milliard d'enregistrements et plus de colonnes. –

Répondre

0

Voici un modèle que j'ai développé il y a environ huit ans en utilisant ce que j'appelle Version Normal Form (vnf). La première table est la table d'entités principale qui contient des données statiques, inchangées ou des données susceptibles de changer, mais vous ne suivez pas les modifications. La deuxième table contient chaque version, une nouvelle version étant entrée chaque fois que les données sous-jacentes changent.

create table Static(
    ID int not null primary key auto increment, 
    Company varchar(8) not null, 
    Title varchar(32) not null, 
    Level varchar(16) not null, 
    Created date not null default SysDate 
); 
create table Versions(
    ID int not null references Static(ID), 
    Effective date default SysDate, 
    PackageID int references Package(ID), 
    constraint PK_Versions primary key(ID, Effective) 
}; 

Pour représenter les données que vous montrer (en utilisant le plus ancien start_date pour simuler une date de création raisonnable):

Static 
ID Company Title  Level Created 
1 C1  Manager Senior 2014/7/1 
2 C1  Architect Senior 2014/7/1 
3 C2  Architect Junior 2015/3/1 
4 C3  Manager Senior 2014/7/1 
5 C4  Manager Senior 2013/7/1 
6 C5  Manager Senior 2014/7/1 

Versions 
ID Effective PackageID 
1 2015/1/1  120 
1 2014/7/1  119 
2 2014/7/1   70 
3 2015/3/1   70 
4 2015/1/1  120 
4 2014/7/1  119 
5 2015/2/1  122 
5 2014/2/1  102 
5 2013/7/1  101 
6 2015/1/1  120 
6 2014/7/1  119 

La clé de ce facile à utiliser pour les développeurs d'applications est vue. Tout d'abord, la vue pour afficher uniquement les données actuelles. La version actuelle est la version avec la date d'entrée en vigueur la plus récente:

create view Current as 
    select s.Company as child_company, s.Title as title_category, 
      s.Level as title_level, v.Effective as start_date 
      v.PackageID as package_id 
    from Static s 
    join Versions v 
     on v.ID = s.ID 
     and v.Effective =(
      select Max(Effective) 
      from Versions 
      where ID = v.ID); 

L'autre vue est une vue de l'historique. Il montre toutes les versions, passées et actuelles:

create view History as 
    select s.Company as child_company, s.Title as title_category, 
      s.Level as title_level, v.Effective as start_date 
      v.PackageID as package_id 
    from Static s 
    join Versions v 
     on v.ID = s.ID; 

Notez que c'est la même requête, juste sans les quatre dernières lignes.

La vue Historique a un déclencheur instead of qui ne fait rien, le rendant ainsi en lecture seule. La vue Actuelle comporte des déclencheurs instead of qui gèrent la structure sous-jacente. En particulier, le déclencheur update exécute une insertion d'une nouvelle version au lieu d'une mise à jour réelle.

Cela semble un peu compliqué, mais parmi les avantages sont

  • il utilise la normalisation, que les développeurs connaissent déjà.
  • les versions sont indépendantes les unes des autres - c'est-à-dire lorsqu'une nouvelle version est insérée, aucune des autres versions ne doit être modifiée de quelque façon que ce soit.
  • Si une modification est prévue à l'avenir, vous pouvez continuer et entrer la modification avec le paramètre Effective à cette date future.La version actuelle reste à jour jusqu'à ce que le moment où la version planifiée devient la nouvelle version actuelle.
  • il faut une modification mineure pour obtenir un accès bi-temporel complet aux données. Il ne semble pas que ce soit ce dont vous avez besoin, mais vous ne le savez jamais.

Remarque: pour utiliser la fonctionnalité "version future", ajoutez simplement and Effective <= Sysdate à la sous-requête de la vue en cours.