2010-08-09 12 views
5

Estoy trabajando bajo el esquema de refactorización de la base de datos (SQL Server 2008) y reúno los argumentos para cambiar las columnas NCHAR(1) (que guardan los valores Y|N) a BIT. Todos entienden que esto es necesario y no sé por qué ocurre, pero este cambio afecta a la base de datos de producción por lo que se requieren argumentos de peso. La tabla mantiene el catálogo de direcciones (hasta 1 m de registros).NCHAR (1) vs BIT

Primer argumento que encontré - cada nchar fields toma 2 bytes, cada 8 bit fields - 1 byte (8 siguientes - 1 byte adicional).

¿Qué sigue? Tal vez algunos problemas de rendimiento de índices?

+0

¡Se pregunta por qué el diseñador original decidió que unicode era necesario para almacenar solo 'N' e 'Y'!Sospecho que las comparaciones probablemente serán más rápidas en los campos de bit que en los campos 'nchar', pero no lo sé con certeza. –

+6

Obviamente, la ventaja de 'NCHAR (1)' es que puede expandirlo [cuando sea necesario] (http://thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx) - para contener * otros * valores booleanos. ;-) –

+0

@Dean Harding: LOL. Una vez tuve un [PHB] (http://en.wikipedia.org/wiki/Pointy-haired_Boss) insistir en que podríamos poner un 2 en un campo de bit ya que solo tenía un dígito. –

Respuesta

4

Un campo de bit ayuda a su lógica aplicando automáticamente lo que actualmente es una regla comercial implícita (es decir, esta columna solo puede contener 'Y' o 'N'). Si aplica esa regla mediante programación, puede ahorrar al eliminar esa sobrecarga. La indexación de una columna de bit en sí misma tiene poco valor debido a la baja cardinalidad, pero podría ser útil como parte de un índice compuesto.

Consulte también:

10

Yo dudaría en proporcionar cualquier argumento para dicho cambio a menos que tenga una buena razón para hacer ese cambio. es decir, debe equilibrar el costo de un cambio con lo que personalmente haría/preferiría, frente al costo de implementarlo y los beneficios.

¿Ha comprobado si el uso de nchar (1) está perjudicando el rendimiento o está cayendo en la trampa de la optimización prematura? Usted solo está hablando de 1 millón de registros aquí.

Por el menor costo de almacenamiento/IO que cree que está incurriendo, considere el total de horas hombre para cambiar, volver a probar y actualizar el sistema * tarifa por hora frente al costo de simplemente comprar un disco más rápido. Sospecho que el disco será mucho más económico, además de beneficiar a todos los aspectos del sistema.

+0

+1 - Tener que modificar todos los procesos almacenados y tal para tener en cuenta la nueva lógica probablemente costaría MUCHO más que el espacio extra que se utiliza. – JNK

+1

+1, no es el fin del mundo y si no está roto, no lo arregles todavía. El desarrollador original podría haber tenido en mente opciones de ternarios, como M por tal vez. –

+0

De acuerdo. Y no puede indexar un campo BIT en SQL Server. Es probable que sus índices compuestos no le estén haciendo ningún bien, ya que solo hay dos valores en su campo NCHAR, pero si lo están, se encontrará con un mundo de dolor que lo cambiará. – mattmc3

6

Una razón común para encontrar NCHAR (1) en lugar de bit es que Oracle no admite un tipo de bit. Si tuviera un desarrollador capacitado en Oracle u Oracle, o una base de datos que solía ejecutar en Oracle, verá esto mucho. En Sql Server, realmente no hay necesidad de esto.

Sin embargo, he encontrado que la mayoría de los lugares en los que tengo un campo de bits (o NCHAR (1) en Oracle) lo que realmente quiero es una fecha y hora que indica no tanto el valor de la bandera, pero exactamente cuando se hizo verdad. Este no es siempre el caso, pero cuando pienso en el código anterior que he escrito, supongo que 4 de cada 5 veces utilicé un campo de bit que debería haber usado una fecha y hora.

+0

¿Y hacer comparaciones de fecha y hora en sus consultas donde podría haber estado haciendo comparaciones de bits? Prefiero usar tanto datetime como bit. datetime para saber cuándo se convirtió en verdadero (o falso) y el campo de bit para las consultas. – Jeroen

+2

@Jeroen - Corrección primero, rendimiento en segundo lugar. Pero la mayoría de las veces estoy comprobando que no es NULO de todos modos, y eso es casi tan rápido como un poco de verificación. –

+0

@Joel: punto interesante. Gracias – Jeroen

1

¿El campo se usa ampliamente en las consultas Where fld = 'Y'?

Si es así, consideraría hacer una prueba para ver si el cambio a bit afecta el rendimiento o no.

Cambiarlo ahora simplemente porque debería ser un campo de bits ya que está almacenando valores booleanos en una tabla de 1m + registros tampoco me parece una buena idea y me gustaría ir con la respuesta de @ Andrew.

3

Cree el campo de bits, agregue una columna calculada que emula el nchar para (1) ahora.

Lo que no debe utilizar nchar:

  • Y vs vs y algunos unicode Y
  • de arriba de la comprobación de S o N
  • no nativa "verdadero" o "falso" (por ejemplo, no va a asignar directamente a .net booleano)
  • Y y N son inglés. Ja/Nein, Oui/Non etc

No debe indexar esto de modo que se reduce a un almacenamiento y uso eficiente. bit es

  • menor
  • tipo de datos de seguridad (por ejemplo, sin verificación de necesario)
  • mapas a clientes que significan directamente
  • independiente de la región

Dicho esto, utilizamos un smalldatetime "WhenInactive" campo como un sustituto del campo "IsActive". NULL = activo.

2

Si está utilizando LINQ2SQL o Entity Framework una columna BIT se traducirá en una bool, pero NCHAR(1) se traducirá en una string.

1

uso de bits:

  • lógico representación/expresividad de intenciones - ya que los estados booleanos no siempre son expresables constantemente como Yes or No, lo que significaría entonces que le sea necesario ser inconsistente en bits de modelado, o no intuitivo, por ej. True/False (T/F), On/Off (?O/F), Open/Closed(O/C) etc.

  • integridad referencial - bit no anulable puede limitarse a solamente 0 or 1. A menos que agregue restricciones, su *char(1) podría ser Y, N, X o .

  • Bits can be packed, por lo que podría tener un almacenamiento más pequeño.

  • Re: Rendimiento: la indexación de las columnas de bits (o CHAR de pocos estados) suele ser un desperdicio, a menos que haya una alta selectividad de 0 o 1 en los datos. En este caso, una buena idea sería filtered index en el valor selectivo.

(migrado desde deleted answer here)

0

tenía unas cuantas ocasiones en las que queríamos un campo de bits, pero no podía saber con certeza que nunca habría la necesidad de un tercer o cuarto valor en ese campo. Por lo tanto, lo estructuramos como un campo de cadena que contiene Y o N. Por supuesto, solo lo hicimos en situaciones muy únicas.