una tabla según mostrar llenar listas lista dinamica desplegables desplegable dependientes datos con como database-design

database design - tabla - ¿Por qué almacenaría una lista delimitada en una columna de texto SQL?



php lista desplegable dinamica (11)

¿Sabía mi predecesor algo que yo no sabía, o estoy en lo correcto al decir "WTF? !!" cuando miro este esquema?

No, tu predecesor no. Sí, tiene usted razón. Ver nota al final, sin embargo.

Parece que es terriblemente ineficiente y difícil de mantener así, y hace que correr informes sea más difícil porque los datos que necesito podrían estar contenidos en campos de texto O podría estar en una de una docena de tablas que tienen información similar y se usan en diferentes partes de la aplicación.

Es terriblemente ineficiente. Ver nota al final, sin embargo.

Una columna siempre debe ser un atributo indivisible de la fila. Veo dos copias de tres (tal vez cuatro) atributos en esta columna que has mostrado:

2x #ABC-12345 Widget, Black: $24.99 /4x #ABC-12344 Widget, Blue: $23.50

  • quanity (2x / 4x).
  • código (# ABC-12345 / # ABC-12344).
  • descripción (Widget, Black: / Widget, Blue :) [puede ser descripción y atributos de color].
  • precio ($ 24.99 / $ 23.50).

Esto habría sido mejor diseñado como:

StockItems Code char(10) primary key Desc varchar(50) Transaction TxnId something primary key : : : TransactionPart TxnId something / TxnSeq int / primary key Quantity integer Code char(10) foreign key StockItems(Code) Price float

NOTA:

Es posible que esto se haya hecho para preservar la información histórica frente a los valores cambiantes en otras partes de la base de datos. Por ejemplo, si la descripción de un artículo en stock cambia o el artículo se elimina.

Sin embargo, esa no es la forma correcta de manejarlo. En ese caso, las restricciones de clave externa habrían impedido que el código del elemento se elimine y los procesos deberían haberse implementado para evitar que la descripción se actualice (como la versión de los códigos de stock).

Por supuesto, si nunca va a buscar en ninguno de los elementos dentro de esa columna, esto es perfectamente válido, aunque imprudente en términos de posibles funcionalidades futuras para buscar en ellos.

Tal vez lo único que haya buscado en esta tabla sea el código del cliente, entonces un campo de texto de formato libre es adecuado.

Todavía no lo haría de esa manera, pero se puede hacer un argumento de YAGNI de que sería mejor cambiar el esquema de DB en el futuro, siempre y cuando se necesite agregar esa funcionalidad de búsqueda.

Tengo que mantener una aplicación que tiene muchas columnas que son del tipo de datos de texto, con múltiples valores insertados en ellas delimitadas con comas, barras diagonales o, a veces, incluso el carácter de la tubería (|). Estoy tratando de descubrir por qué en la Tierra querrías hacer esto alguna vez.

Por ejemplo, una tabla de órdenes tiene una columna llamada detalles que contiene información como:

2x #ABC-12345 Widget, Black: $24.99 /4x #ABC-12344 Widget, Blue: $23.50

donde / separa los artículos de línea; hay un código de VBScript que lee el valor de un conjunto de registros y lo analiza en un bucle For para mostrar usando algo así como (y esto es exactamente lo que lee el código, nombres de variables y todo) arydtls = split(rstmp("details"), "/") . Este método se repite en todo el código para varias tablas.

Me parece que sería 100 veces mejor (sin mencionar que es más fácil trabajar con) tener los detalles en una tabla separada y volver a enlazarlos (curiosamente, para Órdenes hace esto, pero los datos no lo hacen). siempre coincide con el campo de texto de detalles porque la tabla OrderDetail se actualiza en código, el campo de detalles se trata como de solo lectura en la aplicación).

¿Sabía mi predecesor algo que yo no sabía, o estoy en lo correcto al decir "WTF? !!" cuando miro este esquema? Parece que es terriblemente ineficiente y difícil de mantener así, y hace que correr informes sea más difícil porque los datos que necesito podrían estar contenidos en campos de texto O podría estar en una de una docena de tablas que tienen información similar y se usan en diferentes partes de la aplicación.


¿Tu predecesor tuvo quizás algunas otras ideas y esto quedó sin terminar?

Puedo decirte que esto es muy malo para el rendimiento

¿Cómo crearías una consulta que devolverá quién compró un widget azul? Tendrás que escanear toda la tabla y luego analizar esa información, si hubiera otra tabla y esto se normalizó, entonces esto sería mucho mejor en cuanto a rendimiento


En sistemas operativos como Universo, los datos de UniData se almacenan en archivos delimitados por algo así como

Char (254) = separa propiedades Char (253) = separa múltiples valores en una propiedad Char (252) = separa valores sub sub y así sucesivamente

Escandaloso no es así :-) Cuando hablo con ex colegas que aún trabajan con DataBasic y preguntan qué DB uso, la primera pregunta que hacen es "¿Maneja varios valores, está bien?"

En un RDBMS, tendríamos una tabla de pedidos y una tabla OrderLine. El PK en OrderLine probablemente sea algo así como OrderNumber, LineNumber.

En UniData, etc., lo que harían es tener una propiedad en el pedido llamada "Líneas" que contendría una lista de claves para el archivo OrderLine, la clave compuesta generalmente separada por un asterisco.

  • 1234 * 1
  • 1234 * 2
  • 1234 * 3
  • etc

Luego, cuando cargan su pedido en la memoria del archivo, tienen una lista de claves que necesitan para cargar OrderLines del archivo OrderLine. Tenga en cuenta que estos son archivos y no tablas :-)

Me parece que alguien con experiencia en esta forma antigua de almacenar datos ha tratado de usar una base de datos relacional, no la ha entendido para nada, y luego ha intentado que funcione como UniData.

Saco de ellos :-)


He visto una base de datos en un determinado software empresarial que tiene esto en miles de lugares. Es bastante terrible, tanto desde una perspectiva de mantenimiento como desde una perspectiva de rendimiento. Las razones citadas son en general:

  • es "más simple" porque no requiere uniones
  • es más rápido porque no requiere uniones
  • no satura la base de datos con muchas tablas

Ahora, el primer punto es probablemente cierto, pero solo es "más simple" hasta que quieras consultar en contra de él. Ahora estás jodido. Entonces yo diría que eso fue efectivamente refutado. El segundo punto es nuevamente cierto, siempre y cuando no estés preguntando en contra de eso. Tan pronto como tenga que leer toda la tabla, analizar los datos, luego filtrar las filas en su aplicación, perderá. El último es siempre cierto, pero ¿a quién le importa si la base de datos está "desordenada"? ¡Para eso es! Los RDBMS decentes le permitirán poner sus tablas en múltiples esquemas de todos modos, que son algo así como espacios de nombres y ayudan a combatir el desorden. Una buena convención de nombres ayuda también (pero si usa verrugas húngaras, entonces ayúdele $ deity).

En resumen, es una mala idea. Espero que puedas arreglarlo, pero lo más probable es que tengas que lidiar con él en sus términos originales ...


Los dos escenarios más probables son:

  • Su predecesor fue incompetente / no entendió la normalización
  • Su predecesor se encontró con algunos problemas de rendimiento con la estructura normalizada y descubrió que este método era una mejora

Dado que la normalización a menudo puede ser muy costosa en lo que respecta a las operaciones de consulta, a veces podemos obtener mejoras de rendimiento al eliminar una unión costosa y realizar las manipulaciones en el lado de la aplicación frente a una sola fila.

No existe una regla absoluta para el diseño de la base de datos que diga que "almacenar valores delimitados en una sola fila es mejor para este escenario". Se trata de probar contra sus conjuntos de datos específicos y sus patrones de uso y hacer mejoras cuando sea necesario.

En mi experiencia, no es muy común que este patrón sea una mejora sobre la normalización ... eso es bastante atípico.

Editar: Una tercera posibilidad es que tener n-values ​​por fila sea un cambio con respecto al esquema original, y en lugar de agregar una nueva tabla, su predecesor redimensionó la columna. Eso no es necesariamente diferente de la opción "incompetente" :) pero a veces hay presiones políticas involucradas en los cambios al esquema db ...


No puedo decir lo que tu predecesor estaba pensando. Como dijo Rex M, a veces las presiones políticas resultan en implementaciones extrañas.

Una gran cantidad de personas que rellenan una lista de artículos en un solo valor en las tablas intentan evitar las restricciones de la primera forma normal (estilo antiguo). El inconveniente es que las consultas deben realizarse programáticamente en la aplicación en lugar de utilizar un simple citerion en una cláusula WHERE.

Hace unos 10 años, Oracle agregó la capacidad de poner una tabla dentro de un valor. Aproximadamente al mismo tiempo, Date redefinió 1NF para que todas las relaciones estén automáticamente en 1NF. Esto incluye problemas que contienen otras relaciones. Sin esa característica, el diseño más simple y poderoso es dividir el ítem repetido en un valor separado, con una fila para cada ítem.

(Ejemplo: una lista de cursos en los que está inscrito un alumno)

En muchos casos, la causa principal es la ignorancia o terquedad de los diseñadores. Nuevamente, no sé a qué restricciones se enfrentó su predecesor. No lo imites a menos que tengas que hacerlo.


Parece una WTF para mí. No es coherente con la forma en que se implementan otras tablas, y definitivamente no es eficiente. Y cuando mira el esquema sin conocer los datos, sería fácil malinterpretar el sentido de una columna.

Sin embargo, puede haber una razón de por qué el desarrollador anterior ha hecho esto, ¿podría darnos más información, como en la lógica de negocios? Gracias


Simplemente, o tenía una razón o no, sin preguntar si era imposible saberlo. Si asumes que él no era una idea total y algo de algunas posibles razones, entonces tal vez sea una de las siguientes.

Si los datos fueron solo para información y "nunca van a cambiar" como escuchas a menudo, puede haber sido una victoria rápida simplemente lanzar una cadena de visualización directamente al campo. Después de todo, simplemente reemplazar las tuberías con pestañas y barras con BR para colocarlo en la pantalla es increíblemente fácil. Si el código se escribió extremadamente rápido, esta podría haber sido la opción más fácil.

Una nueva característica desde SQL 2005 es el tipo de datos XML. Un uso importante de esto es que puede almacenar e indexar un número desconocido de valores contra un registro en particular. Puede que te importe el color de una cosa, las dimensiones de otra, el peso de otra cosa. Es posible que no pueda generar una lista definitiva de estas cosas y un método genérico verdaderamente normalizado para almacenar esta información puede ser demasiado lento o demasiado complicado para el sistema. Esto puede haber sido un trabajo para intentar obtener una funcionalidad similar.

La clave aquí es que la mayoría de las cosas se hacen por una razón. Lo has visto de la manera correcta al tratar de descubrir esta razón. Puede cruzarse con él un día y pensar "¡Oh, sí!". Solo mirar algo desde su propia perspectiva a menudo puede llevar a que no se pueda ver la madera en el escenario de los árboles.


Una razón posible, de alguna manera válida, podría ser que la estructura de datos no es fija , los atributos de detalle son muy diferentes con las instancias de orden.

No es fácil trabajar con atributos dinámicos en una estructura estática como la impuesta por una base de datos. Una estructura XML, por ejemplo, es más adecuada para este tipo de escenario, pero con la inherente verbosidad de xml, el enfoque ''csv like'' podría haber sido una alternativa más atractiva.


WTF realmente. Nunca almacene tales cosas en el DB.


por qué harías algo como eso?

Hace unas décadas atrás, mi esposa trabajó en el sistema Pick, que incluía una base de datos y un BASIC y tal. La base de datos y el lenguaje de Pick funcionó bien al poner arrays en los campos de la base de datos (no estoy seguro si debería llamarlos columnas). Entonces, había un ambiente donde esto tenía perfecto sentido.

No sé si Pick todavía está por aquí, pero no he oído hablar de él en mucho tiempo. Es posible que esta tabla sea una base de datos de Pick traducida (mal) en una base de datos basada en SQL, y es posible que quien la escribió sea un desarrollador anterior de Pick que no haya aprendido a usar una base de datos relacional en ese momento.

La última vez que me encontré con una base de datos como esa, pregunté. Resultó que fue diseñado por un antiguo desarrollador de Pick.

Yo no llamaría competente a este diseño, a menos que fuera realmente un campo ignorable de escritura, pero bien podría ser que el diseñador no fuera estúpido.