2011-01-12 18 views
8

Tengo varias tablas como Buyers, Shops, Brands, Money_Collectors, e.t.c.¿Cuál es el mejor método para almacenar valores predeterminados en la base de datos?

Cada uno de ellos tiene un valor predeterminado, p. el valor predeterminado Buyer es David, el valor predeterminado Shop es Ebay, y así sucesivamente.

Me gustaría guardar esos valores predeterminados en una base de datos (para que el usuario pueda cambiarlos).

Pensé en agregar la columna is_default a cada una de las tablas, pero parece ser ineficaz porque solo una fila en cada tabla puede ser la predeterminada.

Luego pensé que lo mejor sería tener la tabla Defaults que contendría todos los valores predeterminados. Esta tabla tendrá 1 fila y N columnas, donde N es el número de los valores por defecto:

Defaults table: 

buyer  shop  brand  money_collector 
-----  ----  -----  --------------- 
David  Ebay  Dell  NULL (no default value) 

Pero, este no parece ser el mejor enfoque, porque la estructura de la tabla cambia cuando se añade un nuevo valor predeterminado.

¿Cuál sería el mejor enfoque para almacenar valores predeterminados?

+3

En primer lugar, ¿qué hace el valor predeterminado? En segundo lugar, ¿es un valor predeterminado por mesa o uno por mesa por usuario? Cuando dice (para que el usuario pueda cambiarlos) hace que parezca que CADA usuario tendría un conjunto de valores predeterminados. ¿O quiere decir que un usuario de ADMIN podría cambiar el valor predeterminado? ¿Por qué se opone a una columna is_default? ¿Cuál sería el problema con eso? –

+0

En mi caso, cada tabla almacena todos los valores posibles de un cuadro de selección. Hay un valor predeterminado en cada cuadro de selección (o nulo si no hay un valor predeterminado). No me molestan los usuarios Supongamos que solo hay un usuario (como administrador) que puede cambiar el valor predeterminado. En cuanto a la columna 'is_default': supongamos que hay 50 tiendas (seleccione el cuadro con 50 valores posibles). En este caso, para almacenar la tienda predeterminada necesita 50 campos booleanos, en lugar de 1. En otras palabras, no quiero gastar espacio. ¿No debería preocuparme por el espacio cuando guardo datos en una base de datos? –

+0

¿Cómo desea que funcione el valor predeterminado? ¿Es para la interfaz de usuario, por lo que el cuadro de selección de Tiendas está predeterminado en Ebay? ¿O es para el back-end de la base de datos, para que almacene Ebay para la tienda si el usuario no ha seleccionado una tienda? –

Respuesta

18

Solo para ser claro.

La mejor manera es con una columna en cada tabla desde la que desciende la fuente.

Y he aquí por qué ...

"¿No debería preocuparse por el espacio cuando Guardar datos en una base de datos?"

La respuesta corta es no. La respuesta más larga es de lo que debe preocuparse es el rendimiento. Centrarse en el espacio te llevará a hacer cosas muy malas.

Cosas malas que harás si el espacio es una preocupación.

  • Vas a enterrar el significado en las claves principales. es decir, llaves inteligentes.
  • Intentará almacenar múltiples valores en una columna.
  • podrás índice de demasiado poco
  • (Sin duda se podría crear una lista de 50 malas prácticas que ahorran espacio)

Supongamos que hay 50 tiendas (caja de selección con 50 valores posibles) . En este caso , para almacenar el defecto de la tienda que necesidad 50 campos booleanos,

Bueno, es UNO columna booleana. Existe en cada fila.

Déjame preguntarte esto. Si creó una tabla con 1 columna de fecha e insertó 1 fila, ¿cuánto espacio usaría en el disco?

Si dice que tiene 7 u 8 bytes, se desactiva aproximadamente 1000 veces.

La unidad más pequeña de espacio en disco es un bloque. Los bloques son de 8 kb típicos (el puede ser tan pequeño como de 2 kb del tamaño de 32kb, en general (sin peros aquí, los límites reales no son importantes))

Digamos que usted ha 8kB bloques entonces su columna 1, 1 fila la tabla toma 8Kb. Si inserta otras 999 filas, aún ocupará 8 KB. (De nuevo sin peros hay sobrecarga por bloque y por fila - es un ejemplo)

Así que en su tabla de consulta con 50 nombres de las tiendas, la probabilidad de que la adición de 50 bytes al tamaño de las fuerzas de mesa que le permite ampliar de 1 bloque a 2 es delgado o nulo y completamente irrelevante.

Por otro lado, su tabla predeterminada ciertamente ocupará al menos un bloque adicional. Pero el peor golpe al RENDIMIENTO es que su llamada para completar un menú desplegable necesitará dos viajes redondos a la base de datos, uno para obtener la lista y el otro para obtener el valor predeterminado. (sí, puede hacer esto en uno pero vaya con él)

Así que ha ahorrado exactamente cero espacio y duplicó su tráfico de red.

Ya ves lo que digo.


Otra fundamental razón para dejar de preocuparse por el espacio es estás dando claridad. piense en el desarrollador que va a contratar para ejecutar esta aplicación. Cuando se une al equipo y mira la base de datos, imagina los dos escenarios.

  1. Hay una columna booleana llamada DEFAULT_VALUE
  2. Hay una tabla sin relaciones con cualquier cosa que se nombran Default_Values ​​

se le pregunta a construir una nueva para con un desplegable de 'tienda'.

En el escenario 1, encuentra la tabla de la tienda, conecta el menú desplegable a una consulta simple de la tabla y utiliza el campo default_value para seleccionar el valor inicial.

En el escenario 2, sin algún entrenamiento, ¿cómo sabría él buscar una tabla separada? Tal vez él vería la mesa, pero para el momento en que está contratando, su modelo de datos ahora tiene cientos de tablas.

De nuevo, un poco inventado pero el punto es sobresaliente. La claridad en la base de datos está bien, vale la pena un byte por fila.


material técnico

No soy un chico de MySQL, pero en Oracle, una columna nulo al final de una fila no ocupan espacio adicional. En Oracle usaría un Varchar2 (1) y dejaría 'T' = Predeterminado y dejaría los otros nulos. Eso tendría el efecto de usar solo 1 byte de suma total, y no por fila. YMMV con MySQL, puede plantear esa pregunta por separado si no puede Google la respuesta.

Pero el momento de preocuparse es en millones de filas, no en cientos. Cualquier tabla que alimenta un menú desplegable nunca será lo suficientemente grande como para comenzar a preocuparse por los bytes adicionales.

+0

En MySQL NULL VARCHAR (n <= 255) toma un byte. TINYINT (que es un sinónimo de BOOLEAN en MySQL) funcionará igual de bien. – Mchl

+0

Estás respondiendo un comentario, no la pregunta. –

+0

Todavía es un buen consejo con respecto a la pregunta real. – Mchl

0

Usted no debe crear a una mesa con dos columnas y n filas

Defaults table: 
buyer, David 
shop, Ebay, 
brand, Dell 

De esta manera usted puede agregar nuevos valores sin tener que cambiar la estructura de tablas

+0

¿Qué tipos deberían ser las columnas? –

+0

'VARCHAR' funcionaría mejor Supongo – Mchl

+1

Pero, ¿qué pasa si algunas tablas contienen números o booleanos? –

1

Lo que si se crea un archivo XML y luego tienda que XML en la tabla en una columna XML. La columna XML contendría el XML, y el XML podría tener etiquetas de tablas y un sub nodo de valores predeterminados.

0

Usted puede crear una tabla catálogo (una especie de tabla de metadatos ) que contiene los valores por defecto como cadenas para las columnas de las tablas deseadas. Luego puede usar la función convertir para obtener el valor apropiado. A continuación se muestra una definición de tabla de muestras (se utilizó Transact-SQL):

create table dbo.cat_default_values 
(
    id_column  varchar(30) not null, 
    id_table  varchar(30) not null,  
    datatype  varchar(30) not null,  
    value   varchar(100) not null,  
    f_creation  datetime  not null, 
    usr_creation char(8)  null,  
    primary key clustered (id_column, id_table) 
)  

declare @defaultValueInt int, 
     @defaultValueVarchar varchar(30) 

select @defaultValueInt = convert(int, value) 
    from cat_default_values where id_column = "defColumInteger" and id_table = "table1" 

select defaultValueVarchar = value 
    from cat_default_values where id_column = "defColumVarchar" and id_table = "table1" 
0

Lo que usted está tratando de tienda no es la información de metadatos. En primer lugar, no voy a inventar un almacén de datos externo para almacenar estos datos. (Junto con un código adicional)

Supongo que tiene una lógica de generación de secuencia PK (bajo su control). Asignaré un número mágico x e insertaré un registro en cada tabla con _id = x como valor predeterminado. Entonces, si desea mostrarle al usuario el valor predeterminado, puede manejar su consulta de manera uniforme o puede manejar esto en la lógica de la aplicación mientras inserta. Lo bueno de esto es que tienes acceso al valor predeterminado todo el tiempo y sin escribir ninguna lógica adicional y la lógica para mantener el valor predeterminado de una tabla se puede mantener usando el mismo código (plantilla) (De las lecciones aprendidas W3c a partir de la información del esquema de modelado de XML utilizando DTD.)

Solo catch es esta lógica debe hacerse explícita, ya sea utilizando alguna documentación extensa o podría ser impuesta con fuerza mediante el uso de un disparador.

Cuestiones relacionadas