2010-09-17 3 views
6

Je suis en train d'écrire du code pour trouver des détails de clients en double dans une base de données. Je vais utiliser la distance de Levenshtein.Comment stocker des relations bidirectionnelles

Cependant, je ne sais pas comment stocker les relations. J'utilise des bases de données tout le temps, mais je n'ai jamais rencontré cette situation et je me demandais si quelqu'un pouvait me diriger dans la bonne direction. Ce qui me trouble, c'est comment stocker la nature bidirectionnelle de la relation.

J'ai commencé à mettre quelques exemples ci-dessous, mais il se demande s'il y a une meilleure pratique pour stocker ce type de données,

Exemple de données

id, adresse

001, 5 Main Street
002, 5 rue Main
003, 5 Main Str
004, 6 High Street
005, 7 Basse Rue
006, 7 Low St

Suggestion 1

customer_id1, customer_id2, relationship_strength
001, 002, 0,74
001, 003, 0,77
002, 003, 0,76
005, 006, 0,77

Pas satisfait de cette approche car elle infère sorte d'une relation à sens unique entre Cust omer_id1 à customer_id2. À moins bien sûr d'inclure toutes les relations dans les deux sens, mais cela doublerait le temps de traitement et la taille des tables.

par exemple, il faudrait inclure: 002, 001, 0,74

Suggestion 2

customer_id, GROUPING_ID
001, 1
002, 1
003, 1
005, 2
006, 2

Répondre

6

Nous avons ici un graphique dans lequel chaque nœud a une relation (distance d'édition) avec tous les autres nœuds. Ce n'est pas dans la plage normale des modèles de données. Ce n'est pas non plus une caractéristique permanente de votre base de données (en supposant que vous résolvez les processus métier qui ont conduit aux données en double). Il ne vaut donc pas la peine de passer outre la solution qui convient le mieux à la théorie relationnelle. Ce dont nous avons besoin, c'est d'une solution pratique.

Pensez-y comme une matrice. Si nous optons pour le traitement optimal, nous n'effectuerons pas les doublons. Donc nous marquons l'Adresse 1 contre toutes les autres Adresses, nous notons l'Adresse 2 contre toutes les Adresses sauf l'Adresse 1, nous marquons l'Adresse 3 contre toutes les Adresses sauf les Adresses 1 et 2, etc. Et ce que nous finissons est un peu comme une table de ligue de football:

  addr 
      1 2  3 4  5 
addr 
    1  - 95 95 80 76 
    2  - - 100 75 72 
    3  - -  - 75 72 
    4  - -  - - 83 
    5  - -  - -  - 

Ces données peuvent être stockées dans le meilleur suggestion 1, une table de ID1, ID2, SCORE. Bien que nous ayons besoin de faire pivoter les données pour que la sortie ressemble à cela :)

Dans un tableau de classement approprié, il y a deux séries de scores - Domicile et Absent - donc la table est symétrique. Mais cela ne s'applique pas ici, car la distance d'édition pour 1 > 2 est la même que 2 > 1. Cependant, cela rendrait l'interrogation des résultats plus simple si l'ensemble de résultats comprenait les scores en miroir. Autrement dit, pour les enregistrements (1,5,76), (2,5,72), etc, nous générons des enregistrements (5,1,76), (5,2,72). Cela pourrait être fait à la fin du processus de notation.

  addr 
      1 2  3 4  5 
addr 
    1  - 95 95 80 76 
    2  95 - 100 75 72 
    3  95 100  - 75 72 
    4  80 75 75 - 83 
    5  76 72 72 83  - 

Bien sûr, cela est principalement une chose présentation, il ne doit être fait à des fins d'affichage, par exemple exporter les données dans une feuille de calcul. Nous pouvons encore obtenir tous les scores pour, par exemple, Adresse 5 de façon lisible sans miiroring les scores en utilisant une instruction SQL simple:

select case when id1 = 5 then id1 else id2 end as id1 
     , case when id1 = 5 then id2 else id1 end as id2 
     , score 
from your_table 
where id1 = 5 
or  id2 = 5 
/
+0

Merci APC. Cette matrice a du sens et aide à la visualiser. Cette instruction SQL est vraiment la main aussi. Merci. – alj

1

Comme toujours Cela dépend de ce que vous voulez faire avec les données une fois que vous l'avez calculé. En supposant que ce soit simplement pour identifier ou localiser des doublons, alors votre suggestion 1 est ce que j'utiliserais, c'est-à-dire une seconde table qui stocke simplement les paires et les points forts. Ma seule suggestion est de faire des forces un entier mis à l'échelle plutôt qu'un nombre décimal.

+0

Je dois présenter les données aux personnes qui les gèrent afin qu'elles puissent les vérifier. Donc, à cet égard, ma première suggestion suffirait, je suppose. Mais je voulais savoir s'il y avait une façon «standard» de stocker de telles informations afin que je puisse avoir la possibilité de les sortir dans différents formats en fonction de ce qu'ils voulaient (car ils reviendront sans doute dire qu'ils veulent le faire autrement!). Aussi ... c'est une bonne occasion d'améliorer ma compréhension du schéma de base de données. – alj

+0

... et merci Richard. – alj

+0

C'est comme ça que je l'ai toujours fait. Parfois, la solution la plus simple fonctionne et nous n'avons pas besoin de chercher quelque chose de plus complexe. La première solution fonctionnera et sera suffisamment efficace et produira les résultats dont vous avez besoin. –

6

La façon de traiter les relations symétriques dans un système relationnel est la suivante:

  • choisir une forme canonique dans laquelle les paires symétriques sont stockées, par exemple customer_id1 < customer_id2.
  • Définir un SYMM_TBL de vue que de sélectionner id1, ID2, ... de ... UNION sélectionnez ID2 comme ID1, ID1 comme ID2, ... DE ...

systèmes décents ne doivent pas vous punir la zone de performance lors de l'interrogation de cette vue.

Questions connexes