Dudas con atributos a los campos de una tabla

Iniciado por Pazador, 29 Noviembre 2009, 04:25 AM

0 Miembros y 3 Visitantes están viendo este tema.

Pazador

hola a todos, resulta que quiero saber para que fucking demonios sirve el maldito NOT NULL?? como su nombre lo dice "no nulo" se supone que no deberia aceptar campos vacio.. pero lo hace, se puede agregar campos vacios a una tabla, o mejor dicho, no agregar nada a ese campo, pero si a los demas sin problemas, alguien que me explique entonces para que sirve?? porque de adorno no luce bien  :xD

create table tablita(
id int NOT NULL,
nombre varchar(50) NOT NULL,
.........
);


y tambien decirles que a veces (miento!! esto lo hago siempre!!  :xD) yo suelo insertar datos en formato de fecha, numericos o string a determinados campos de una tabla, y por defecto a TODO lo llamo varchar no uso date, int (int solo uso para el id) u otros atributos porque hasta ahora todo trabaja bien sin problemas  :xD, pero mi pregunta es... hay alguna diferencia o punto en contra con la forma que estoy trabajando?? se que voy contra las reglas pero quiero oir criticas constructivas.. o mejor aun.. que me quiten la venda de los ojos  :D
saludos y no sean tan severos conmigo  :laugh:
La vida es un juego
Mario Bross

Toxico

supongo que es mysql o sqlserver.

NOT NULL, como su nombre lo dice, que el campo no admite valores nulos, no los campos vacios en un ejemplo:

INSERT INTO (id,nombre) tablita
VALUES (1,NULL)

Dara error, mientras que

INSERT INTO(id,nombre) tablita
VALUES(1,'')

Sera aceptado ya que son valores diferentes.

Sobre los tipos de datos, es mejor trabajar con los tipos de datos para cada cosa para eso estan, en performance hacer una busqueda por un campo de tipo numerico es mas rapido que uno tipo varchar, y para fechas te evitaras las odiosas conversiones trabajando con el tipo de datos date.

atte.
Miguel Angel
solo el principio....


^Tifa^

#2
Citarhola a todos, resulta que quiero saber para que fucking demonios sirve el maldito NOT NULL??

Para no acceptar valores desconocidos o nulos, el Ansi SQL trabaja con la teoria de logica ternaria en los motores de base de datos (verdadero, falso, desconocido)  ;)

Citarcomo su nombre lo dice "no nulo" se supone que no deberia aceptar campos vacio.. pero lo hace, se puede agregar campos vacios a una tabla, o mejor dicho, no agregar nada a ese campo, pero si a los demas sin problemas, alguien que me explique entonces para que sirve?

Lo hace siempre y cuando tengas en dicho campo donde insertas el NULL un auto_increment o una secuencia (y das uso de esta secuencia en el INSERT) o similar, de lo contrario no te acceptara insertar NULL ni null en dicho campo donde exclusivamente especificaste NOT NULL.

Citary tambien decirles que a veces (miento!! esto lo hago siempre!!  :xD) yo suelo insertar datos en formato de fecha, numericos o string a determinados campos de una tabla, y por defecto a TODO lo llamo varchar no uso date, int (int solo uso para el id) u otros atributos porque hasta ahora todo trabaja bien sin problemas

Enserio? existe una diferencia, de acorde a la estructura de datos primitivos cuando creas una tabla con campos varchar estas reservando espacio en memoria para recibir datos caracteres (Que obviamente al hacer un INSERT "890888-999" el lo ve como un caracter esta entre comillas, lo mismo pasa con datos fechas) y aunque esto ocupe 1 byte en memoria por la reserva del dato varchar + los bytes que ocupen de espacio tus datos insertados en memoria cache, que me dices cuando te soliciten o peticionen condiciones donde debas sumar, sacar potencia, restar, dividir, etc... 2 campos (digamos de ejemplo sueldo) de 2 tablas? o que te soliciten buscar el ultimo dia del mes tal? no podras dar uso exclusivo de esas funciones especiales en los motores para obtener a gran rapidez lo que buscas (A no ser que empiezes encima a convertir pasandole un casting a cada campo) y oye... porque forzar la lectura del motor con:

* Verificar primero los permisos del usuario en las tablas
* convertir los campos encerrados en el Casting a la estructura de dato indicada por ti
* realizar la suma, resta, division, potenciacion, loquesea en dicho datos
* retornar dicho valor
* convertir dicho valor a varchar para finalmente mostrartelo....

No seria mas efectivo tener un campo digamos DECIMAL que no redondea cifras para el salario y hagas una suma de 2 salarios por ejemplo y tu motor solamente haga :

* Verificar primero los permisos del usuario en las tablas
* realizar la suma, resta, division loquesea de dicho datos
* retornar dicho valor

Vez la diferencia?

Esto sin agregarte, que el tipo de dato varchar no es muy efectivo, es un tipo de dato de reserva 'dinamica' en el motor. Al decir dinamica, me refiero a que puedes declarar un campo asi:

nombre varchar(30)

Y cada vez que insertes un registro a nombre, solamente ocupara en ram el espacio exacto del nombre insertado, si tu nombre solo tenia 10 caracteres pos nada... se inserta 10 caracteres se corta el espacio para los 20 sobrantes, si insertas en un segundo intento otro dato de 18 caracteres nada se llenan 18 bytes y se cortan los restantes... y asi sucesivamente, y esto a la larga causa fallas en transacciones masivas (Varchar es muy dispuesto a corromperse no tiene mucha atomicidad) por ser precisamente dinamico y no tener una constante fija de tipos de datos en su reserva. Por eso siempre uso char en vez de varchar, aunque aveces opto demasiado por la rapidez y me voy por bynary.

No quiero alargar mucho el tema, solo te he expuesto una introducion basica porque el tema de tu pregunta puede tornarse extenso. No te recomiendo por normalizacion de base de datos que declares campos que accepten NULL, el motor reserva espacio para una tabla y varios campos con sus respectivos tipos de datos, insertar valores NULL en estos como NULL no pertenece a ningun tipo de dato real existente el motor en una consulta de lectura pierde unos milisegundos deteniendose en cada valor NULL encontrado porque el sabe que se ha reservado espacio para X tipo de datos y al no encontrar ese tipo de dato sino NULL el tiene que guardar esto en el Buffer antes de moverlo a la Cache de memoria. No uses campos NULL, declara los campos acorde a los valores a guardar no le indiques al motor que todo es un caracter, aveces hay tipos de datos que ocupan mas espacio de disco pero que responden mas rapido a lectura que los caracteres (Recuerda que el CPU trabaja a nivel binario)

Suerte con eso.

Toxico

Cita de: ^TiFa^ en 29 Noviembre 2009, 07:20 AM
(Varchar es muy dispuesto a corromperse no tiene mucha atomicidad)

Bajo que condiciones sucede eso?, me refiero al corromperse.

atte
Miguel Angel
solo el principio....


^Tifa^

Por ponerte ejemplos sencillos, asume que haces lo siguiente y por desgracia sufres un corte electrico a mitad del proceso o sencillamente pierdes conexión a la red o similar, falla de disco etc :

* Transacciones masivas entre un esclavo y un maestro (espejo)
* Transaciones en clusteres
* Transferencia de datos de una DB a otra
* Restaurancion de un backup de mas de 50GB

- Son solo ejemplos basicos, cosas que pueden hacer que un o mas tablas se corrompan de alguna u otra forma. Que aunque influye tambien en parte en esto el motor de almacenamiento (como los no transaccionales en MySQL) hago incapie en que no es la causa del todo. (He visto tablas corromperse en motores transaccionales como InnoDB a causa de un programador web que asigno como indice campos varchar) mientras mas consistentes sean los datos, por cuestion de rendimiento y optimizacion al menos yo, me inclino mas en campos caracteres por char aunque me ocupe mas espacio en disco, son mas improbables a corromperse incluso en tablas Myisam (Que suelen corromperse con frecuencia) .

Aunque sera cuestion de gustos, he conocido DBA Seniors en Oracle que les he preguntado cosas tan simples como, sabes la diferencia entra un char y un varchar2? y me han respondido cosas tipo: que no son acaso lo mismo.... y he tenido que exponerle que no y el porque.

Yo me he tornado un poco maniatica con la optimizacion de los motores de DB, no digo que varchar sea mediocre o malo, porque ejerce su funcion decentemente aunque tenga sus riesgos, las unicas veces que opto por varchar es si son campos de una tabla que no sean muy importantes o tenga que economizar espacio en el disco, o similar. De lo contrario, intento que todos los tipos de datos sean lo mas consistentes posibles, asi se evita la gente muchos problemas futuros.

Toxico

Cita de: ^TiFa^ en 29 Noviembre 2009, 19:59 PM
Por ponerte ejemplos sencillos, asume que haces lo siguiente y por desgracia sufres un corte electrico a mitad del proceso o sencillamente pierdes conexión a la red o similar, falla de disco etc :

* Transacciones masivas entre un esclavo y un maestro (espejo)
* Transaciones en clusteres
* Transferencia de datos de una DB a otra
* Restaurancion de un backup de mas de 50GB

- Son solo ejemplos basicos, cosas que pueden hacer que un o mas tablas se corrompan de alguna u otra forma. Que aunque influye tambien en parte en esto el motor de almacenamiento (como los no transaccionales en MySQL) hago incapie en que no es la causa del todo. (He visto tablas corromperse en motores transaccionales como InnoDB a causa de un programador web que asigno como indice campos varchar) mientras mas consistentes sean los datos, por cuestion de rendimiento y optimizacion al menos yo, me inclino mas en campos caracteres por char aunque me ocupe mas espacio en disco, son mas improbables a corromperse incluso en tablas Myisam (Que suelen corromperse con frecuencia) .

Aunque sera cuestion de gustos, he conocido DBA Seniors en Oracle que les he preguntado cosas tan simples como, sabes la diferencia entra un char y un varchar2? y me han respondido cosas tipo: que no son acaso lo mismo.... y he tenido que exponerle que no y el porque.

Yo me he tornado un poco maniatica con la optimizacion de los motores de DB, no digo que varchar sea mediocre o malo, porque ejerce su funcion decentemente aunque tenga sus riesgos, las unicas veces que opto por varchar es si son campos de una tabla que no sean muy importantes o tenga que economizar espacio en el disco, o similar. De lo contrario, intento que todos los tipos de datos sean lo mas consistentes posibles, asi se evita la gente muchos problemas futuros.


Se que no es mi hilo, pero necesito que me aclares algo, tu mencionas que se corrompe toda la tabla(eso es lo probable y logico) debido a una falla determinada (corte de electricidad o caida de red en tu ejemplo )lo que no me parece logico es que sea mas probable que se corrompan determinados campos solo por tener el tipo de datos varchar lo cual me parece incorrecto, por que las unicas veces donde los campos de tipo caracter estan propensos a ser truncados(corruptos) es cuando haces migraciones de distintos motores(por los tipos de intercalacion que poseen los tablas o por caracteres validos en un motor y en el otro no) ejem. sybase a sqlserver o viceversa. pero esto es indistinto ya que es aplicable tanto para campos char y varchar.

Como nota adicional de suceder un error(sea cual sea la naturaleza)  para el tipo de transacciones del ejemplo se corrompen las tablas haciendolas inclusive inoperativas, en el caso de quedar operativa al ser error transaccional se trunca la insercion de registros ya que la ATOMICIDAD que mencionas se aplica a las transacciones mas no a un tipo de dato en particular, por lo cual la expresion "(Varchar es muy dispuesto a corromperse no tiene mucha atomicidad)" me queda bastante confusa hasta me aventuraria a decir incorrecta y quisiera saber a que hacer referencia; todos los dias se aprende algo nuevo dicen quizas me he perdido de algo...

atte.
Miguel Angel
solo el principio....


^Tifa^

#6
CitarSe que no es mi hilo, pero necesito que me aclares algo, tu mencionas que se corrompe toda la tabla(eso es lo probable y logico) debido a una falla determinada (corte de electricidad o caida de red en tu ejemplo

No del todo, si hablamos de una tabla en un motor transaccional (InnoDB por ejemplo) los cambios aplicados no se escriben automaticamente a disco como ocurre en motores transaccionales. Al permanecer en buffer y cache hasta recibir la instruccion commit son menos propensos a errores que los motores no transaccionales. (Si solo hacemos referencia al tipo de motor, mas no al tipo de datos de los campos dentro de dicho motor) hay una falla de red con una transaccion en motores InnoDB? pos nada cuando se restaure seguira donde se detuvo.

Citarlo que no me parece logico es que sea mas probable que se corrompan determinados campos solo por tener el tipo de datos varchar lo cual me parece incorrecto

No te imaginas las veces que he podido restaurar tablas Myisam (cuando repair table no funciona) solamente con hacer alter table y cambiar campos varchar corruptos a char.... y las veces que he visto tablas en InnoDB corromperse por tener indices varchar.

Referencia de MySQL:

CitarSi usted tiene un problema con tablas que contengan filas de longitud dinámica y está utilizando únicamente columnas VARCHAR (no columnas BLOB ni TEXT), puede intentar cambiar todas las columnas VARCHAR a CHAR con ALTER TABLE. Esto fuerza a MySQL a utilizar filas de tamaño fijo. Las filas de tamaño fijo ocupan un poco más de espacio, pero son mucho más tolerantes a la corrupción.
El código de filas dinámicas actual ha sido utilizado en MySQL AB durante muchos años con muy pocos problemas, pero las filas de longitud dinámica son, por naturaleza, más propensas a errores, así que podría ser una buena idea intentar esta estrategia y ver si ayuda.

Fuente:  http://dev.mysql.com/doc/refman/5.0/es/crashing.html

Esta bien que te guste Varchar, pero por rendimiento y consistencia y evitarte problemas futuros al menos yo optaria por Char (y casi siempre lo hago).

Citarpor que las unicas veces donde los campos de tipo caracter estan propensos a ser truncados(corruptos) es cuando haces migraciones de distintos motores(por los tipos de intercalacion que poseen los tablas o por caracteres validos en un motor y en el otro no) ejem. sybase a sqlserver o viceversa. pero esto es indistinto ya que es aplicable tanto para campos char y varchar.

Esto es bastante logico, si migro data de un motor a otro distinto es mas que obvio lo expuesto anteriormente, por la referencia ya expuestas por ti. Pero hacia referencia yo a Varchar vs Char.

Citarpor lo cual la expresion "(Varchar es muy dispuesto a corromperse no tiene mucha atomicidad)" me queda bastante confusa hasta me aventuraria a decir incorrecta

Aunque hacia referencia a los registros guardados bajo cierto tipo de datos (ya que no tiene mucha logica tener un campo con cierto tipo de dato definido y jamas insertarle datos) conclui diciendo que el tipo de dato varchar no era atomico (pero hacia referencia a su manera de manejar los registros guardados en el, mas no al tipo de dato en si porque el tipo de dato sin nada guardado no tiene mucha logica de critica) Siento mucho que por alguna u otra razon este punto se haya malinterpretado.

Toxico

Cita de: ^TiFa^ en 29 Noviembre 2009, 22:55 PM

Referencia de MySQL:

CitarSi usted tiene un problema con tablas que contengan filas de longitud dinámica y está utilizando únicamente columnas VARCHAR (no columnas BLOB ni TEXT), puede intentar cambiar todas las columnas VARCHAR a CHAR con ALTER TABLE. Esto fuerza a MySQL a utilizar filas de tamaño fijo. Las filas de tamaño fijo ocupan un poco más de espacio, pero son mucho más tolerantes a la corrupción.
El código de filas dinámicas actual ha sido utilizado en MySQL AB durante muchos años con muy pocos problemas, pero las filas de longitud dinámica son, por naturaleza, más propensas a errores, así que podría ser una buena idea intentar esta estrategia y ver si ayuda.

Fuente:  http://dev.mysql.com/doc/refman/5.0/es/crashing.html

Esta bien que te guste Varchar, pero por rendimiento y consistencia y evitarte problemas futuros al menos yo optaria por Char (y casi siempre lo hago).


No es que me guste, yo las utilizo no por gustos sino por necesidad.

Gracias por la referencia aclaraste mi duda sobre la corrupcion por el tipo de campo(no menciona el motivo de la corrupcion una pena), aunque trabajo con sql server y sybase debo asumir que la referencia dada por mysql es aplicable tambien a estos motores o si en estos se presentan( hasta el momento no se me han presentado ni en desarrollo, ni en deployment ni en produccion) o no hasta que no encuentre referencia que la sustente o la refute, igual no me queda claro esto

Citar(Varchar es muy dispuesto a corromperse no tiene mucha atomicidad)

atte.
Miguel Angel
solo el principio....


^Tifa^

#8
Pegue la referencia de MySQL porque asumo que siempre sera mas creible el respaldo de lo que diga una empresa que desarrolle y produzca un motor de BD que lo que diga yo  :xD 

CitarGracias por la referencia aclaraste mi duda sobre la corrupcion por el tipo de campo(no menciona el motivo de la corrupcion una pena)

El motivo de la corrupcion (aunque esto es una percepcion personal propia) para mi, creo que ocurre por el hecho de que al tipo de dato varchar ser de longitud variable cuando por alguna razon no termina una transaccion realizada sobre este campo, y estamos trabajando en un motor no transaccional (por ejemplo) como todo se escribe a disco automaticamente (por el autocommit) si dicho campo de longitud variable no se completo la transaccion  y  como no esta definido en ninguna parte que se autocomplete con espacios a la derecha (como ocurriria con el tipo de datos CHAR) entonces nada... queda corrupto escrito en el datafile la informacion ya que ni completo su longitud establecida ni completo la informacion que se estaba introduciendo durante la transaccion, y eso pues corrompe la data de la tabla en cuestion.  (aunque repito esto es una referencia personal mia, no digo que sea real)


Citarlo cual la expresion "(Varchar es muy dispuesto a corromperse no tiene mucha atomicidad)" me queda bastante confusa hasta me aventuraria a decir incorrecta

Aunque hacia referencia a los registros guardados bajo cierto tipo de datos (ya que no tiene mucha logica tener un campo con cierto tipo de dato definido y jamas insertarle datos) conclui diciendo que un campo con el tipo de dato varchar no era atomico (pero hacia referencia a su manera de manejar los registros guardados en el, mas no al tipo de dato en si porque el tipo de dato sin nada guardado no tiene mucha logica de critica) Siento mucho si por alguna u otra razon este punto se haya malinterpretado.

Toxico

Cita de: ^TiFa^ en 29 Noviembre 2009, 23:58 PM
Pegue la referencia de MySQL porque asumo que siempre sera mas creible el respaldo de lo que diga una empresa que desarrolle y produzca un motor de BD que lo que diga yo  :xD 

CitarGracias por la referencia aclaraste mi duda sobre la corrupcion por el tipo de campo(no menciona el motivo de la corrupcion una pena)

El motivo de la corrupcion (aunque esto es una percepcion personal propia) para mi, creo que ocurre por el hecho de que al tipo de dato varchar ser de longitud variable cuando por alguna razon no termina una transaccion realizada sobre este campo, y estamos trabajando en un motor no transaccional (por ejemplo) como todo se escribe a disco automaticamente (por el autocommit) si dicho campo de longitud variable no se completo la transaccion y como el tipo de dato es de longitud variable no esta definido en ninguna parte que se autocomplete con espacios a la derecha (como ocurriria con el tipo de datos CHAR) entonces nada... queda corrupto escrito en el datafile la informacion, y eso pues corrompe la data de la tabla en cuestion.


Generalmente tengo que creer cuando la documentacion es oficial  :xD, sino todo se basa en "experiencias" tanto la tuya como la mia.

Para la suposicion que mencionas de la corrupcion para el campo varchar no es dable, ya que la ATOMICIDAD de una transaccion garantiza que los datos se guarden de manera correcta o no se guarden y no por partes como seria lo que supones, en caso de suceder es un problema de la transaccion mas no del tipo de dato, si un motor de base de datos no puede manejar eso es un desastre transaccionalmente hablando..

Citar
Citar
lo cual la expresion "(Varchar es muy dispuesto a corromperse no tiene mucha atomicidad)" me queda bastante confusa hasta me aventuraria a decir incorrecta
Aunque hacia referencia a los registros guardados bajo cierto tipo de datos (ya que no tiene mucha logica tener un campo con cierto tipo de dato definido y jamas insertarle datos) conclui diciendo que un campo con el tipo de dato varchar no era atomico (pero hacia referencia a su manera de manejar los registros guardados en el, mas no al tipo de dato en si porque el tipo de dato sin nada guardado no tiene mucha logica de critica) Siento mucho si por alguna u otra razon este punto se haya malinterpretado.

Obvio ya que la expresion en el contexto es incorrecta.  ;)

atte.
Miguel Angel
solo el principio....