2011-04-04 22 views
43

¿Qué tipo de columna se debe usar para almacenar datos serializados en un db mysql? Sé que puede usar varbinary, blob, text. ¿Qué se considera el mejor y por qué?¿Qué tipo de columna se debe usar para almacenar datos serializados en un db mysql?

Editar: Entiendo que no es "bueno" para almacenar datos serializados. Sin embargo, necesito hacerlo en este caso. Por favor solo confía en mí en esto y concéntrate en la pregunta si tienes una respuesta. ¡Gracias!

+0

No se usan datos serializados. –

+3

Supongo que normalmente no debería usarlo. Este es un caso especial en el que realmente tiene sentido. – djburdick

Respuesta

56

Respondiendo: parece que el texto está obsoleto en muchos DBMS, así que mejor usar un blob o un varchar con un límite alto (y con blob no tendréis problemas de codificación, lo cual es una gran molestia varchar y texto).

También como se indica en this thread at the MySQL forums, los discos duros son más baratos que el software, por lo que es mejor que primero diseñe su software y lo haga funcionar, y solo entonces si el espacio se convierte en un problema, es posible que desee optimizar ese aspecto. Por lo tanto, no intente sobreimperimentar el tamaño de su columna demasiado pronto, mejor configure el tamaño más grande al principio (además, esto evitará problemas de seguridad).

Acerca de los diversos comentarios: Demasiado fanatismo SQL aquí. A pesar de que soy muy aficionado a SQL y modelos relacionales, también tienen sus dificultades.

Almacenamiento de datos serializados en la base de datos tal como está (tales como el almacenamiento de JSON o datos XML con formato) tiene algunas ventajas:

  • Usted puede tener un formato más flexible para sus datos: añadir y eliminar campos en la mosca, cambiando la especificación de los campos sobre la marcha, etc.
  • Menor desajuste de impedancia con el modelo de objetos: almacena y recupera los datos tal como están en su programa, en comparación con recuperar los datos y luego tener que procesarlo y convertirlo entre las estructuras de los objetos de tu programa y las estructuras de tu base de datos relacional.

Y hay muchas más otras ventajas, así que por favor no fanboyismo: las bases de datos relacionales son una gran herramienta, pero no vamos a compartir las otras herramientas que podemos obtener.Más herramientas, mejor.

En cuanto a un ejemplo concreto de uso, tiendo a agregar un campo JSON en mi base de datos para almacenar parámetros extra de un registro donde las columnas (propiedades) de los datos JSON nunca serán SELECCIONADAS individualmente, pero solo usadas cuando el registro correcto ya está seleccionado. En este caso, aún puedo discriminar mis registros con las columnas relacionales, y cuando se selecciona el registro correcto, puedo usar los parámetros adicionales para el propósito que desee.

Así que mi consejo para conservar lo mejor de ambos (velocidad, serializabilidad y flexibilidad estructural), basta con usar algunas columnas relacionales estándar para servir como claves únicas para discriminar entre las filas, y luego usar una columna blob/varchar donde sus datos seriados serán insertados. Por lo general, solo se requieren dos/tres columnas para una clave única, por lo tanto, esto no será una sobrecarga importante.

Además, usted puede estar interesado por PostgreSQL que ahora tiene un tipo de datos JSON, y PostSQL project para procesar directamente los campos JSON como columnas relacionales.

+6

Siempre hay un caso de uso para algo, por lo que es mejor evitar respuestas como NO HACER ESO. Digo esto porque acabo de leer un hilo donde alguien aconseja no almacenar datos JSON en una base de datos relacional. Sin embargo, como señaló, si los datos no van a seleccionarse alguna vez y desea flexibilidad sobre los datos almacenados, no veo ningún error al almacenar cadena JSON en la base de datos. +1 para señalar el caso ... ¡Buena respuesta! –

-1

A menos que los datos serializados no tengan otro uso que no sean guardarlos y restaurarlos desde la base de datos, probablemente no desee hacerlo de esa manera.

Normalmente, los datos serializados tienen varios campos que deben almacenarse en la base de datos como columnas separadas. Es común que cada elemento de datos serializados sea una columna separada. Algunas de esas columnas serían naturalmente campos clave. Es posible que se agreguen otras columnas además de los datos para indicar la fecha + hora de la inserción, el usuario responsable, etc., etc.

+2

Hola, Wally. Gracias, este es un caso especial. Entiendo que normalmente no deberías serializar datos. Si puede responder el mejor tipo de columna para datos serializados, sería agradable. – djburdick

10

¿Cuánto planea almacenar? Consulte las especificaciones para string types at the MySQL docs y su sizes. La clave aquí es que no le importa indexar esta columna, pero tampoco desea que se desborde y se trunque, ya que entonces JSON no se puede leer.

  • TINYTEXT L < 2^8
  • TEXTO L < 2^16
  • MEDIUMTEXT L < 2^24
  • LONGTEXT L < 2^32

Donde L es la longitud en el carácter

Simplemente normal El texto debe ser suficiente, pero aumente si almacena más. Aunque, en ese caso, es posible que no desee almacenarlo en el db.

+2

Entiendo las restricciones de longitud. Me preocupan más las ventajas y desventajas de almacenamiento de blog frente a texto. – djburdick

7

LONGTEXT

tiendas Wordpress datos serializados en su mesa postmeta como LONGTEXT. Encuentro que la base de datos de Wordpress es un buen lugar para investigar los tipos de datos para las columnas.

+12

Wordpress debe usarse como un ejemplo de mala codificación, malas prácticas, elecciones terribles. En todo caso, Wordpress es un ejemplo de ** cómo no diseñar su aplicación ** – Mjh

10

Los límites de longitud que @Twisted Pear mentions son buenas razones.

Ten en cuenta también que TEXT y su calaña tienen un conjunto de caracteres asociado con ellos, mientras que BLOB tipos de datos no lo hacen. Si solo está almacenando bytes de datos sin procesar, también podría usar BLOB en lugar de TEXT.

Tenga en cuenta que aún puede almacenar datos de texto en un BLOB, simplemente no puede hacer ninguna operación de SQL que tenga en cuenta el conjunto de caracteres; es solo bytes a SQL. Pero eso probablemente no sea un problema en su caso, ya que se trata de datos serializados con estructura desconocida para SQL de todos modos. Todo lo que necesita hacer es almacenar bytes y buscar bytes. La interpretación de los bytes depende de su aplicación.

También he tenido problemas usando LONGBLOB o LONGTEXT usando ciertas bibliotecas cliente (por ejemplo, PHP) porque el cliente intenta asignar un búfer tan grande como el tipo de datos más grande posible, sin saber qué tan grande será el contenido en una fila determinada hasta que sea recuperado Esto causó que PHP estallara en llamas mientras trataba de asignar un buffer de 4GB. No sé qué cliente está usando o si sufre el mismo comportamiento.

La solución alternativa: use MEDIUMBLOB o simplemente BLOB, siempre que esos tipos sean suficientes para almacenar sus datos serializados.


En cuanto a la gente que le dice que no lo hiciera, no voy a decir que (a pesar del hecho de que soy un defensor de SQL). Es cierto que no puede usar expresiones SQL para realizar operaciones en elementos individuales dentro de los datos serializados, pero ese no es su propósito. Lo que gana al poner esos datos en la base de datos incluye:

  • Asociar datos serializados con otros datos más relacionales.
  • Posibilidad de almacenar y recuperar datos serializados de acuerdo con el alcance de la transacción, COMMIT, ROLLBACK.
  • almacenar todos sus datos relacionales y no relacionales en un solo lugar, para que sea más fácil para replicar a los esclavos, una copia de seguridad y restauración, etc.
-3

he encontrado:

varchar(5000) 

sea el mejor equilibrio de tamaño/velocidad para nosotros. Además, funciona con los datos de serialización de rieles 3 (varbinary) estaba lanzando errores serializar intermitentemente.

+1

¿es la mejor respuesta? @djburdick cualquier forma flexible para esto? ¿Qué tal el conjunto de fechas de la tienda (clave: 1 - 31, valor: precio de la fecha)? –

+1

Considere la alineación de página. 4096 u 8192 podría ser mejor. – EnabrenTane

+0

Me gustaría ver más razones en esta respuesta. ¿Qué tipo de perfil mostró eso? – GameDeveloper

1

que podría llegar tarde a la fiesta, pero la documentación acerca de los estados php.net objeto serializado lo siguiente:

Tenga en cuenta que esta es una cadena binaria que puede incluir bytes nulos, y debe almacenarse y manejarse como tal. Por ejemplo, la salida serialize() generalmente se debe almacenar en un campo BLOB en una base de datos, en lugar de un campo CHAR o TEXT.

Fuente: http://php.net/manual/en/function.serialize.php

Espero que ayude!

Cuestiones relacionadas