2010-09-17 15 views
6

Estoy escribiendo algunos códigos para encontrar detalles duplicados de clientes en una base de datos. Estaré usando la distancia Levenshtein.Cómo almacenar relaciones bidireccionales

Sin embargo, no estoy seguro de cómo almacenar las relaciones. Utilizo bases de datos todo el tiempo, pero nunca me he encontrado con esta situación y me pregunto si alguien podría señalarme en la dirección correcta.

Lo que me confunde es cómo almacenar la naturaleza bidireccional de la relación.

he empezado a poner algunos ejemplos a continuación, pero se pregunta si hay una mejor práctica para el almacenamiento de este tipo de datos,

Datos de ejemplo

DNI, dirección

001, 5 Main Street
002, 5 Main St.
003, 5 Main Str
004, 6 High Street
005, 7 bajo la calle
006, 7 bajo St

Sugerencia 1

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

No contento con este enfoque, ya que tipo de infiere una relación unidireccional entre cust omer_id1 a customer_id2. A menos que, por supuesto, incluya todas las relaciones en ambos sentidos, pero eso duplicaría la cantidad de tiempo de procesamiento y el tamaño de las tablas.

por ejemplo, tendría que incluir: 002, 001, 0,74

sugerencia 2

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

Respuesta

6

Lo que tenemos aquí es un gráfico en el que cada nodo tiene una relación (editar distancia) con cada otro nodo. Esto no está dentro del rango normal de los modelos de datos. Tampoco es una característica permanente de su base de datos (suponiendo que resuelva los procesos comerciales que condujeron a la duplicación de datos) por lo que no vale la pena preocuparse por la solución que mejor se ajusta a la teoría relacional. Lo que necesitamos es una solución práctica.

Piense en ello como una matriz. Si buscamos el procesamiento óptimo, no ejecutaremos los puntajes duplicados. Entonces puntuamos la dirección 1 contra todas las demás direcciones, puntuamos la dirección 2 contra todas las demás direcciones excepto la dirección 1, puntuamos la dirección 3 contra todas las demás direcciones, excepto las direcciones 1 y 2, etc. Y con lo que terminamos es un poco como una tabla de la liga de fútbol:

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

Estos datos se pueden almacenar mejor en la sugerencia 1, una mesa de ID1, ID2, SCORE. Aunque necesitamos pivotar los datos para que la salida se vea así :)

En una tabla de clasificación adecuada, hay dos conjuntos de puntajes, En casa y Ausente, por lo que la tabla es simétrica. Pero eso no se aplica aquí, ya que la distancia de edición para 1 > 2 es la misma que 2 > 1. Sin embargo, haría que la consulta de los resultados fuera más directa si el conjunto de resultados incluyera los puntajes espejados. Es decir, para registros (1,5,76), (2,5,72), etc. generamos registros (5,1,76), (5,2,72). Esto podría hacerse al final del proceso de puntuación.

  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  - 

Por supuesto, esto es principalmente una cosa de presentación, por lo que sólo hay que hacer para fines de visualización, por ejemplo exportar los datos a una hoja de cálculo. Todavía podemos obtener todas las puntuaciones de, digamos, Dirección 5 de una forma legible sin miiroring las puntuaciones mediante una instrucción 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

Gracias APC. Esa matriz tiene sentido y ayuda a visualizarla. Esa declaración SQL es realmente también. Gracias. – alj

1

Como siempre depende de lo que quieras hacer con los datos una vez que lo hayas calculado.

Suponiendo que sea simplemente para identificar o localizar duplicados, entonces su sugerencia 1 es la que usaría, es decir, una segunda tabla que simplemente almacena los pares y las fortalezas. Mi única sugerencia es hacer que las fortalezas sean un entero escalado en lugar de un decimal.

+0

Necesito presentar la información a las personas que la mantienen para que puedan revisarla. Entonces, en ese sentido, mi primera sugerencia sería suficiente, supongo. Pero quería saber si existía una forma "estándar" de almacenar dicha información para poder tener la flexibilidad de producirla en varios formatos dependiendo de lo que quisieran (¡ya que sin duda volverán diciendo que quieren que se haga de otra manera!) Además ... es una buena oportunidad para mejorar mi comprensión del esquema de la base de datos. – alj

+0

... y gracias Richard. – alj

+0

Es la forma en que siempre lo he hecho. A veces, la solución más simple simplemente funciona y no necesitamos buscar nada más complejo. La primera solución funcionará y será lo suficientemente eficiente y producirá los resultados que necesita. –

6

La manera de tratar con relación simétrica en un sistema relacional es el siguiente:

  • elegir una forma canónica en la que se almacenan los pares simétricos, por ejemplo customer_id1 < customer_id2.
  • definir una vista SYMM_TBL como seleccionar ID1, ID2, ... de ... UNIÓN seleccione id2 como id1, id1 como ID2, ... DE ...

sistemas decente no usted debe castigar de el área de rendimiento al consultar esta vista.

Cuestiones relacionadas