2008-12-08 19 views
6

Tengo una tabla en un DB (basado en Postgres), que actúa como una superclase en la programación orientada a objetos. Tiene una columna 'tipo' que determina qué columnas adicionales deben estar presentes en la tabla (propiedades de subclase). Pero no quiero que la tabla incluya todas las columnas posibles (todas las propiedades de todos los tipos posibles).Estructura de base de datos óptima para campos adicionales entidad

Así que decidí hacer una tabla, con las columnas 'clave' y 'valor' (es decir 'nombrearchivo' = '/ archivo', o 'algún_valor' = '5'), que contienen cualquier propiedad posible del objeto, no incluido en la tabla de superclase. Y también creó una tabla relacionada para contener los valores 'clave' disponibles.

Pero existe un problema con dicha arquitectura: la columna 'valor' debe ser de un tipo de datos de cadena por defecto, para poder contener cualquier cosa. Pero no creo que la conversión hacia y desde cadenas sea una buena decisión. ¿Cuál es la mejor manera de eludir esta limitación?

Respuesta

10

El diseño que está experimentando es una variación de Entity-Attribute-Value, y viene con muchos problemas e ineficiencias. No es una buena solución para lo que estás haciendo, excepto como último recurso.

Lo que podría ser una mejor solución es lo que describe fallen888: cree una tabla de "subtipo" para cada uno de sus subtipos. Esto está bien si tienes un número finito de subtipos, que suena como lo que tienes. Luego, los atributos específicos de su subtipo pueden tener tipos de datos, y también una restricción NOT NULL, si corresponde, que es imposible si usa el diseño EAV.

Una debilidad restante del diseño de tabla de subtipos es que no se puede exigir que exista una fila en la tabla de subtipos simplemente porque la fila principal en la tabla de superclase dice que debería. Pero esa es una debilidad más leve que las introducidas por el diseño de EAV.

editar: En cuanto a su información adicional acerca de comments-to-any-entity, sí, este es un patrón bastante común. Tenga cuidado con una solución rota llamada "asociación polimórfica", que es una técnica que muchas personas usan en esta situación.

0

La única solución (al tiempo que conserva su strucure) es tener mesas separadas:

create table IntProps(...); 
create table StringProps(...); 
create table CurrencyProps(...); 

Pero no creo que esto es una buena idea ...

0

Un enfoque común es tener la tabla de clave-valor contiene múltiples columnas, una para cada tipo de datos, es decir, StringValue, DecimalValue, etc.

Solo sepa que está negociando la capacidad de consulta y el rendimiento para un esquema de base de datos que no necesita cambiar. También podría considerar mapeo ORM o una base de datos de objetos.

2

¿Qué tal esto en su lugar ... cada subtipo obtiene su propia tabla de base de datos. Y la tabla base/super solo tiene una columna varchar que contiene el nombre de la tabla DB del subtipo. A continuación, puede tener algo como esto ...

Entity 
------ 
ID 
Name 
Type 
SubTypeName (value of this column will be 'Dog') 


Dog 
--- 
VetName 
VetNumber 
etc 

Si no desea que sus (sub) los nombres de tabla como valores varchar en la tabla base, también puede simplemente tener una tabla Subtipo cuya clave primaria estará en la mesa base.

0

Puede tener una tabla de clave/valor por tipo. La tabla disponible necesitaría codificar la disponibilidad de un par de clave/tipo específico para apuntar a la tabla clave/valor tipada correctamente.

Sin embargo, parece ser una arquitectura altamente ineficiente en una base de datos relacional basada en filas.

¿Quizás debería echar un vistazo a una base de datos relacional orientada a columnas?

0

Gracias por las respuestas. Explicaré un poco más específicamente lo que necesito. Hay una necesidad de programar un blog + sitio web del foro, y he estado buscando en el WordPress DB structure.

Existe una gran necesidad de poder colocar comentarios en cualquier tipo de 'objeto', como una entrada de blog o un archivo de video adjunto. La razón de su elección es la estructura de DB anterior, que es muy fácil de escalar y satisfacer todas nuestras necesidades.

Pero eso no es tarde para cambiarlo, porque esto está en etapa de ingeniería inicial. También nuestro modelo huele ahora como una base de datos basada en jerarquía de árbol. Por ahora, aceptaré Bill Karwin's and fallen888 answers, pero ¿tal vez voy en una dirección totalmente equivocada?

0

acerca de que el usuario sea capaz de añadir un nuevo campo a la tabla:

Admiro a todas estas personas hacer comentarios.

Solía ​​estar interesado en este tipo de cosas hace unos años, pero he escrito poco código recientemente (aparte de un poco de PHP y MYSQL).

Creo que está bien si quieres continuar, puedes terminar con algo nuevo.

Lamento verter agua fría en el esquema - Admiro tus esfuerzos. Mi creencia personal es que si avanzas lo suficiente en esta dirección, terminarás con un sistema que interpreta más lenguaje natural que SQL. (Alrededor de 1970, SQL en realidad se deletreaba Sequel, y en realidad representaba el "lenguaje de consulta inglés estructurado", pero después de que lo estandarizaron en la década de 1970, creo que alguien dijo que Oracle fue la primera implementación comercial, 19079, el "inglés" obtuvo caído, porque supongo que decidieron que era solo un pequeño subconjunto de Inglés.

Me he quedado sin energía en esta área, porque no tengo un trabajo. Sin un trabajo fácil que paga las cuentas, donde puedo experimentar con estas ideas, que es un poco difícil concentrarse en esta área.

los mejores deseos para todos.

0

lo siento, escribió 19079 anterior, me refería al año 1979. Oracle consiguió su primer recurso contrato ing una base de datos para la CIA.

Cuestiones relacionadas