Un diseño de base de datos. ¿Dependencia transitiva o no?

Me tomé un largo descanso (más de un año) del diseño de la base de datos y acabo de regresar. Estoy diseñando una base de datos para el sitio web que estoy creando. Estoy almacenando 2 valores booleanos en una tabla (dos columnas separadas). Me di cuenta de que si el primer valor es verdadero, el otro siempre será verdadero, pero si el primer valor es falso, el otro puede ser verdadero o falso. En lo que a mí respecta, esta no es una dependencia transitiva y no debería crear una nueva tabla, pero quiero asegurarme de que estoy haciendo todo bien. Si hubiera varios valores que se comportaran como el segundo valor booleano, ¿lo mantendría en la misma tabla? ¿Cuál es la mejor manera de almacenar este tipo de datos en una base de datos?

Agradecería que la respuesta incluyera un diagrama ER.

preguntado el 12 de junio de 12 a las 09:06

cuando tu dices 2 boolean values te refieres a dos filas? o dos campos de un registro? -

En cambio, si hay dos valores booleanos, podría usar una sola variable de "tres estados". Los dos booleanos originales serían funcionalmente dependientes de la cosa de tres estados. -

cuando digo 2 valores booleanos -me refiero a dos filas-

En lugar de crear dos filas, cree dos columnas, flag1 y flag2 -

lo siento, son columnas, me confundí porque trabajo con el banco de trabajo y todas las columnas se muestran en una fila. -.- -

4 Respuestas

Normalizado:
Creo que deberíamos distinguir dos casos:

  • longitud máxima de una secuencia de valores booleanos == 2;
  • longitud máxima de una secuencia de valores booleanos > 2;

El primer caso se puede resolver usando una sola tabla con dos campos, ya que garantiza tanto un buen rendimiento como una optimización del espacio (no se puede ahorrar más espacio que de esta manera, excepto si se ignoran las Reglas de Normalización, lo cual hice en el último de estos solución):

MyBools (id, firstBool, secondBool);


Con respecto al segundo caso, se me ocurrieron dos ideas, ninguna de las cuales me satisface.
Lo principal que podemos decir es que cuando tiene secuencias largas, una columna para cada valor booleano no es muy útil. Aquí están mis dos ideas:

  1. una sola tabla con un PK, un campo booleano y una clave externa autorreferencial:

    MyBools (id, thisBool, idNextBool);
    

    thisBool claramente contiene un valor booleano. Si thisBool es cierto que ha terminado, no necesita almacenar el siguiente valor booleano, ya que su valor coincide con el primero. Si thisBool Es falso idNextBool apunta al siguiente booleano.
    Esta solución solo permite la búsqueda hacia adelante.

  2. una sola tabla con un PK, un valor booleano y una clave externa autorreferencial:

    MyBools (id, thisBool, idNextBool);
    

    If idNextBool es nulo, ha alcanzado el primer valor de la secuencia. De lo contrario idNextBool apunta al siguiente booleano.
    Esta solución solo permite la búsqueda hacia atrás.

Como puede ver, las soluciones para el segundo caso (secuencias de más de 2 valores) son bastante inmanejables.
Es por eso que propongo una solución no normalizada.


No normalizado:
Podría tratar estos valores booleanos como bits de un campo numérico (especialmente teniendo en cuenta que un booleano de hecho está representado por un bit). Digamos que tenemos dos campos, field1 y field2, y considera que podemos ponerlos en un solo campo (llamémoslo myfield):

1) IF field1 is True THEN field2 True         myfield = 0


                                   __ True      myfield = 10
2) IF field1 is False THEN field2 /
                                  \__ False       myfield = 11

Como puede ver, puede extender esto a tantos valores booleanos como pueda caber dentro de un campo numérico (por ejemplo, en un campo numérico de 32 bits puede almacenar 32 valores booleanos, siempre que cada uno dependa de los inferiores).

Respondido el 12 de junio de 12 a las 17:06

Esto viola el principio de atomicidad y por lo tanto el 1NF. Entre otros problemas, le impide realizar consultas de manera eficiente sobre indicadores individuales (por ejemplo, a través de un índice hash en el indicador booleano, en bases de datos que lo admitan). Esto puede no ser necesariamente un problema en este caso (ya que el número de posibles combinaciones de banderas es pequeño), pero puede serlo en el caso general. - branco dimitrijevic

@BrankoDimitrijevic Estoy de acuerdo con usted sobre la normalización, pero creo que los valores booleanos son una excepción válida, ya que en realidad puede beneficiarse (en términos de espacio) al agruparlos (ya que de hecho están unidos por una relación que es la misma de formato de número módulo-2) sin perder rendimiento (en términos de tiempo). Todo lo que necesita hacer es usar máscaras de bits para acceder o filtrar valores. No me parece ineficiente, pero estoy abierto a cambiar de opinión si proporciona razones y explicaciones de por qué los valores booleanos no normalizados no son una excepción válida a las reglas de normalización. - Nadir Sampaoli

Algunos DBMS (Oracle) admiten la indexación hash, que se puede usar razonablemente en indicadores individuales. Si "fusiona" todas las banderas juntas, entonces está eliminando la opción para que el optimizador de consultas use índices en campos separados, cuando consulta en condiciones de búsqueda que involucran múltiples banderas. Además, algunas bases de datos ya almacenan banderas de manera eficiente (MS SQL Server usa un mapa de bits), por lo que no hay necesidad de "reinventar la rueda". Todo esto es válido cuando se trata de una gran cantidad de banderas, que no es el caso aquí, e incluso si fuera MySQL (que yo sepa) no es compatible con estas técnicas, por lo que tiene razón. - branco dimitrijevic

Estoy usando mySQL pero sigo pensando que debería mantenerlo normalizado. Xitcod13

@ Xitcod13 si solo tiene secuencias largas de dos valores booleanos, la solución es simple. Intenté agregar alguna solución "normalizada", pero realmente hacen que la administración sea más difícil. - Nadir Sampaoli

No es una dependencia funcional, por tanto no es una dependencia funcional transitiva.

Por definición, X -> Y si, y sólo si, cada valor de X está asociado precisamente con un valor de Y.

En su caso, cuando X es falso, Y podría ser verdadero o falso, por lo que la definición anterior no se cumple.


Sin embargo, parece una dependencia de múltiples valores.

No estoy seguro de que deba hacer nada al respecto más que agregar la restricción CHECK apropiada (el costo de complicar las cosas sería demasiado alto para las ganancias esperadas).

Respondido el 12 de junio de 12 a las 10:06

Pensé en una solución, pero no sé si es buena. Si el primer valor es falso, podría hacer otra tabla para todos los demás valores con un FK y almacenar los otros valores si el valor es verdadero, simplemente no podría generar la tabla para esos valores porque todos serán verdaderos de todos modos

Respondido el 12 de junio de 12 a las 16:06

esta solución es solo para múltiples valores booleanos, no uno ... pero me pregunto si vale la pena - Xitcod13

Tu pregunta es un poco vaga, pero lo intentaré. Primero, por lo que describe, no tiene una dependencia transitiva. La razón es que usted menciona solo dos, lo que supongo que son atributos en su tabla, cuando una dependencia transitiva necesitaría tres atributos para existir.

La dependencia transitiva existe cuando A implica B y B implica C. En otras palabras, A implica C transitivamente a través de B.

De todos modos, creo que buscar dependencias funcionales con una muestra de datos pequeña y sin contexto conduce a un diseño de base de datos deficiente. ¿Cuáles son los elementos de tu tabla?

Respondido el 12 de junio de 12 a las 10:06

Esto debe publicarse en los comentarios, no como una respuesta: sashi kant

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.