obligada > microsoft.* > microsoft.sqlserver

Pedro (09-09-2008, 16:48)
Quiero un campo en una tabla que me represente un flag o valor bool (true o
false). Cuales es la mejor alternativa? Bit? Tinyint? Char?
Gustavo Larriera (MVP) (09-09-2008, 19:16)
Por una cuestion de gusto personal, prefiero usar el tipo BIT.
Rubén Garrigós (09-09-2008, 20:14)
Hola Pedro,

Yo también te recomiendo el tipo bit por motivos técnicos. El almacenamiento
en SQL Server de los campos de tipo bit en una tabla se realiza de forma
empaquetada. Esto quiere decir que aunque tengamos 8 campos de tipo bit en la
misma tabla el espacio que nos ocupa físicamente seguirá siendo el mismo (se
consume únicamente 1 byte por cada 8 columnas de dicho tipo).

Rubén Garrigós
Solid Quality Mentors

"Pedro" wrote:
Pedro (09-09-2008, 20:22)
Cierta vez leí algo sobre que por la portabilidad o algo parecido no se
recomendaban los campos Bit.
Es cosa del pasado me imagino.

"Rubén Garrigós" <RubnGarrigs> escribió en el
mensaje news:af38
[..]
Maxi Accotto (11-09-2008, 02:00)
Hola, yo uso char(1) y pongo S o N.
Waldo (11-09-2008, 15:22)
Para mi lo mas efectivo seria usar Bit.

Segun Libros de SQL:

************************************************** ******************
Bit:
Tipo de datos entero 1, 0 ó NULL.
Observaciones
Microsoft® SQL ServerT optimiza el almacenamiento que utilizan las columnas
de tipo bit. Si hay 8 ó menos columnas de tipo bit en una tabla, las
columnas se almacenan como 1 byte. Si hay entre 9 y 16 columnas de tipo bit,
se almacenan como 2 bytes y así sucesivamente.

************************************************** ******************

Osea que si en una tabla tenes hasta 8 columnas bit, solo ocuparas 1 byte.

Pero si lo guardas como char(1) vas a usar 8 bytes.

Saludos

Waldo
Maxi Accotto (12-09-2008, 01:39)
Si es cierto, pero bit no siempre es facil de manejar desde las aplicaciones
o bien cuando necesitas ir hacia otros motores, char(1) es mas standard :)
Waldo (12-09-2008, 15:26)
Ah, eso puede ser
Gustavo Larriera (MVP) (13-09-2008, 01:01)
No comparto tu idea, querido amigo Maxi.

Usar 'S' o 'N' no es demasiado bueno. Imaginemos que la base es usada por
personas que hablen inglés por ejemplo... además de lidiar con la
sensibilidad de mayúsculas/minúsculas, además de tener que poner más
"inteligencia" en las aplicaciones para enteneder que 'S' es verdadero y 'N'
es falso.

Si no se quiere usar BIT por una cuestión de ser un tipo demasiado
propietario de SQL Server, entonces es preferible usar algún tipo integer que
es un tipo de datos disponible en cualquier sistema.

Y luego almacenar con 0 (FALSE) y un valor no-cero para TRUE (prefiero 1),
siguiendo la idea clásica de C90.
Carlos M. Calvelo (13-09-2008, 01:45)
Hola Gustavo,

On 13 sep, 01:01, Gustavo Larriera (MVP)
<GustavoLarriera> wrote:
[..]
> es un tipo de datos disponible en cualquier sistema.
> Y luego almacenar con 0 (FALSE) y un valor no-cero para TRUE (prefiero 1),
> siguiendo la idea clásica de C90.


Otras consideraciones:

Si se tienen muchas columnas de este tipo habrá que considerar el
espacio que ocupan (mejor usar BIT). Si se suelen pedir muchos
registros
a la vez habrá que considerar la eficiencia. Supongo que cuesta mas
'empaquetar' y 'desempaquetar' los BIT (que, creo, resultan en tipo
numérico (int?)), que simplemente tener INT.
(No lo sé. Solo un par de ideas, porque habría que hacer pruebas)

En cuanto al razonamiento del idioma, tambien se puede tener '0' y '1'
(char) en vez de 0 y 1 (int). O 'T' / 'F'

Y, last but no least, no se pueden definir índices con columnas tipo
BIT.

Saludos,
Carlos
Carlos M. Calvelo (13-09-2008, 02:08)
Ah!
Y crear un User defined type 'Boolean' con una restricción (rule)
y usar ese tipo consecuentemente a la hora de definir las tablas.

Por ejemplo 'Boolean' basado en char(5) y con una restricción
@value IN ('true', 'false')

Saludos,
Carlos
Gustavo Larriera (MVP) (13-09-2008, 02:45)
Hola Carlos,

"Carlos M. Calvelo" wrote:

> En cuanto al razonamiento del idioma, tambien se puede tener '0' y '1'
> (char) en vez de 0 y 1 (int). O 'T' / 'F'


Lo que me gusta de usar 0/1 por sobre '0'/'1' es que con las operaciones + y
* es muy simple simular las operaciones booleanas.

> Y, last but no least, no se pueden definir índices con columnas tipo
> BIT.


Buen punto, aunque dada la poca selectividad de las columnas de tipo
booleana, suelen participar poco en indizaciones.

En resumen, me gusta más una representación numérica para un dato booleano.
Es una preferencia personal simplemente.

> Saludos,
> Carlos


Saludos,
~gux
Gustavo Larriera (MVP) (13-09-2008, 02:56)
Hola Carlos,

"Carlos M. Calvelo" wrote:

> Ah!
> Y crear un User defined type 'Boolean' con una restricción (rule)
> y usar ese tipo consecuentemente a la hora de definir las tablas.
> Por ejemplo 'Boolean' basado en char(5) y con una restricción
> @value IN ('true', 'false')


Los UDT no me agradan demasiado debido a que no permiten definir operaciones
sobre los valores del tipo. Por ejemplo, el AND, OR y NOT. En mi humilde
opinión, los UDT son una idea sin terminar :-)

En SQL Server 2005/2008 el poder definir tipos usando .NET es una mejora en
ese sentido. De todas formas no soy tampoco de definir tipos .NET para las
columnas, aunque tal vez para variables en los procedimientos.

> Saludos,
> Carlos


Saludos,
~gux
Carlos M. Calvelo (13-09-2008, 03:04)
Hola Gustavo,

On 13 sep, 02:45, Gustavo Larriera (MVP)
<GustavoLarriera> wrote:
> Lo que me gusta de usar 0/1 por sobre '0'/'1' es que con las operaciones + y
> * es muy simple simular las operaciones booleanas.


Ten cuidado de no hacer algo como
IF campo1 + campo2 = 1
en vez de
IF campo1 + campo2 > 0
:-)

Pero... buena idea.

Saludos,
Carlos
Carlos M. Calvelo (13-09-2008, 04:34)
Hola Gustavo,

On 13 sep, 02:56, Gustavo Larriera (MVP)
<GustavoLarriera> wrote:
> Hola Carlos,
> "Carlos M. Calvelo" wrote:
> Los UDT no me agradan demasiado debido a que no permiten definir operaciones
> sobre los valores del tipo. Por ejemplo, el AND, OR y NOT. En mi humilde
> opinión, los UDT son una idea sin terminar :-)


:-)
Eso está claro. De 'tipos' no tienen nada. Son mas bien un alias de
tipos definidos por el sistema. Aun así, ofrecen la posibilidad de
especificar una restricción solo en un sitio en vez de en 100
columnas. O utilizando solo el nombre, se documenta que columnas en
distintas tablas son en realidad del mismo tipo (que tiene sentido
una comparacion de valores, por ejemplo.), aunque el tipo base sea
el mismo que en otras columnas que no tienen nada que ver.
Por ejemplo, decir que una columna es del tipo 'Temperatura' (INT)
nos dice que no tiene mucho sentido compararla con otra columna
del tipo Longitud (también INT)

> En SQL Server 2005/2008 el poder definir tipos usando .NET es una mejoraen
> ese sentido. De todas formas no soy tampoco de definir tipos .NET para las
> columnas, aunque tal vez para variables en los procedimientos.


Uff... ese ya es un tema que se las trae. Bueno... por ahí es por
donde tenían que ir los UDT. Imagínate tener tipos como XMLDoc,
BITMAP, WordDocument, TextDocument, Foto, Map, Sound, etc, etc.

Y poder definirlos tu con las mismas posibilidades (definir
operadores) y con el mismo nivel de integración en el lenguaje que
los 'system defined types'.

Por poner un ejemplo muy sencillo:
A menudo tenemos la situación de que tenemos que definir rangos.
Algo como FechaInicial y FechaFinal. En estos casos estas dos
columnas son interdependientes ( ini <= fin). O sea que no dependen
solo de la clave. Si lo piensas bien, estas dos columnas a nivel de
lo que estamos definiendo en la tabla son una unidad y convendría
tener un tipo como Periodo.

Imagínate ahora poder definir un tipo Periodo, con esos dos
componentes y, entre otras cosas, operadores como Overlaps()...

WHERE tabla1.per.Overlaps(tabla2.per)

... You get the idea!

Las propuestas de Date y Darwen son excelentes en este sentido y
siguen trabajando en el tema. Hasta con un buen modelo de herencia
de tipos.

Saludos,
Carlos

Temas Similares