none
consulta tablas sql y normalización RRS feed

  • Pregunta

  • Hola tengo una duda respecto a si es una práctica obligatoria hacer una tabla para cosas que no van a tener mas de 2 o 3 filas en esa tabla, por ejemplo si tengo un atributo "tipo de pedido" en mi clase pedido, y ese tipo de pedido puede ser "presupuesto" o "remito", tiene sentido tener una tabla "tipo de pedido" para solamente tener dos valores?? o simplemente puedo establecer a "tipo de pedido" como bool y en base al valor true/false, sea remito o presupuesto. que opinan??

    Si bien por normalización, esa tabla deberia exisitir.. no se hasta que punto tiene sentido??

    miércoles, 26 de junio de 2019 17:12

Respuestas

  • Hola Artemis Spectrum:

    Una opción simple para ese comportamiento es olvidar las tablas y trabajar directamente con vistas.

    Te expongo un ejemplo

    CREATE TABLE tipoDoc
    (id          TINYINT primary key, 
     descripcion VARCHAR(25)
    );
    GO
    INSERT INTO tipoDoc
    (id, 
     descripcion
    )
    VALUES
    (1, 
     'presupuesto'
    ),
    (2, 
     'remito'
    );
    GO
    
    CREATE TABLE pedido
    (id      BIGINT IDENTITY(1, 1) PRIMARY KEY, 
     serie   VARCHAR(5), 
     cliente INT, 
     tipodoc TINYINT
    );
    GO
    ALTER TABLE pedido
    ADD CONSTRAINT fk_tipoDoc FOREIGN KEY(tipodoc) REFERENCES tipoDoc(id);
    GO
    /* con esto tenemos la tabla pedido y tipoDoc */

    Lo normal sería insertar pedidos.

    INSERT INTO PEDIDO (SERIE, CLIENTE, tipodoc)
    VALUES
    ('A',1,1),
    ('B',1,2);
    GO

    Pero vamos a crear 2 vistas diferentes.

    CREATE VIEW vW_PEDIDO
    AS
    
    SELECT PEDIDO.id, 
           PEDIDO.serie, 
           PEDIDO.cliente, 
           PEDIDO.tipodoc,
    	  TIPODOC.DESCRIPCION
    FROM PEDIDO INNER JOIN tipoDoc ON PEDIDO.tipodoc = tipodoc.id
    WHERE tipodoc = 1;
    GO
    CREATE VIEW vW_REMITO
    AS
    SELECT PEDIDO.id, 
           PEDIDO.serie, 
           PEDIDO.cliente, 
           PEDIDO.tipodoc,
    	  TIPODOC.DESCRIPCION
    FROM PEDIDO INNER JOIN tipoDoc ON PEDIDO.tipodoc = tipodoc.id
    WHERE tipodoc = 2;
    GO
    

    Si yo quiero insertar un pedido.

    INSERT INTO vW_PEDIDO (serie, cliente, tipodoc)
    values
    ('C',1,1)
    
    

    Lo inserto por su vista. 

    Si quiero un remito, lo mismo.

    Cuando hago un select de la vista, tengo los datos que requiero, y además esta normalizado.

    SELECT * FROM vW_PEDIDO

    Salida

    Las tablas siguen ahí, y a tiempo de obviar la tabla tipoDoc siempre estas.

    miércoles, 26 de junio de 2019 19:08

Todas las respuestas

  • Desde mi punto de vista, ambas opciones son validas, espero ver mas comentarios

    IIslas Master Consultant SQL Server

    miércoles, 26 de junio de 2019 17:53
  • En programacion hay muchas ocasiones que vas a ver cosas que para uno no son logicas pero es una practica recomendable seguir las reglas que exiten para las bases de datos, te voy a poner un ejemplo si tu vas a hacer una tabla genero hoy en dia pueden ser dos M(masculino) F(Femenino) solo tienen dos campos pero igual es correcto crear una tabla solo para esos dos campos. exito
    miércoles, 26 de junio de 2019 18:21
  • Hola Artemis Spectrum:

    Una opción simple para ese comportamiento es olvidar las tablas y trabajar directamente con vistas.

    Te expongo un ejemplo

    CREATE TABLE tipoDoc
    (id          TINYINT primary key, 
     descripcion VARCHAR(25)
    );
    GO
    INSERT INTO tipoDoc
    (id, 
     descripcion
    )
    VALUES
    (1, 
     'presupuesto'
    ),
    (2, 
     'remito'
    );
    GO
    
    CREATE TABLE pedido
    (id      BIGINT IDENTITY(1, 1) PRIMARY KEY, 
     serie   VARCHAR(5), 
     cliente INT, 
     tipodoc TINYINT
    );
    GO
    ALTER TABLE pedido
    ADD CONSTRAINT fk_tipoDoc FOREIGN KEY(tipodoc) REFERENCES tipoDoc(id);
    GO
    /* con esto tenemos la tabla pedido y tipoDoc */

    Lo normal sería insertar pedidos.

    INSERT INTO PEDIDO (SERIE, CLIENTE, tipodoc)
    VALUES
    ('A',1,1),
    ('B',1,2);
    GO

    Pero vamos a crear 2 vistas diferentes.

    CREATE VIEW vW_PEDIDO
    AS
    
    SELECT PEDIDO.id, 
           PEDIDO.serie, 
           PEDIDO.cliente, 
           PEDIDO.tipodoc,
    	  TIPODOC.DESCRIPCION
    FROM PEDIDO INNER JOIN tipoDoc ON PEDIDO.tipodoc = tipodoc.id
    WHERE tipodoc = 1;
    GO
    CREATE VIEW vW_REMITO
    AS
    SELECT PEDIDO.id, 
           PEDIDO.serie, 
           PEDIDO.cliente, 
           PEDIDO.tipodoc,
    	  TIPODOC.DESCRIPCION
    FROM PEDIDO INNER JOIN tipoDoc ON PEDIDO.tipodoc = tipodoc.id
    WHERE tipodoc = 2;
    GO
    

    Si yo quiero insertar un pedido.

    INSERT INTO vW_PEDIDO (serie, cliente, tipodoc)
    values
    ('C',1,1)
    
    

    Lo inserto por su vista. 

    Si quiero un remito, lo mismo.

    Cuando hago un select de la vista, tengo los datos que requiero, y además esta normalizado.

    SELECT * FROM vW_PEDIDO

    Salida

    Las tablas siguen ahí, y a tiempo de obviar la tabla tipoDoc siempre estas.

    miércoles, 26 de junio de 2019 19:08
  • Hola Artemis Spectrum:

    Una opción simple para ese comportamiento es olvidar las tablas y trabajar directamente con vistas.

    Te expongo un ejemplo

    CREATE TABLE tipoDoc
    (id          TINYINT primary key, 
     descripcion VARCHAR(25)
    );
    GO
    INSERT INTO tipoDoc
    (id, 
     descripcion
    )
    VALUES
    (1, 
     'presupuesto'
    ),
    (2, 
     'remito'
    );
    GO
    
    CREATE TABLE pedido
    (id      BIGINT IDENTITY(1, 1) PRIMARY KEY, 
     serie   VARCHAR(5), 
     cliente INT, 
     tipodoc TINYINT
    );
    GO
    ALTER TABLE pedido
    ADD CONSTRAINT fk_tipoDoc FOREIGN KEY(tipodoc) REFERENCES tipoDoc(id);
    GO
    /* con esto tenemos la tabla pedido y tipoDoc */

    Lo normal sería insertar pedidos.

    INSERT INTO PEDIDO (SERIE, CLIENTE, tipodoc)
    VALUES
    ('A',1,1),
    ('B',1,2);
    GO

    Pero vamos a crear 2 vistas diferentes.

    CREATE VIEW vW_PEDIDO
    AS
    
    SELECT PEDIDO.id, 
           PEDIDO.serie, 
           PEDIDO.cliente, 
           PEDIDO.tipodoc,
    	  TIPODOC.DESCRIPCION
    FROM PEDIDO INNER JOIN tipoDoc ON PEDIDO.tipodoc = tipodoc.id
    WHERE tipodoc = 1;
    GO
    CREATE VIEW vW_REMITO
    AS
    SELECT PEDIDO.id, 
           PEDIDO.serie, 
           PEDIDO.cliente, 
           PEDIDO.tipodoc,
    	  TIPODOC.DESCRIPCION
    FROM PEDIDO INNER JOIN tipoDoc ON PEDIDO.tipodoc = tipodoc.id
    WHERE tipodoc = 2;
    GO

    Si yo quiero insertar un pedido.

    INSERT INTO vW_PEDIDO (serie, cliente, tipodoc)
    values
    ('C',1,1)
    

    Lo inserto por su vista. 

    Si quiero un remito, lo mismo.

    Cuando hago un select de la vista, tengo los datos que requiero, y además esta normalizado.

    SELECT * FROM vW_PEDIDO

    Salida

    Las tablas siguen ahí, y a tiempo de obviar la tabla tipoDoc siempre estas.

    no comprendo bien cual seria la diferencia de insertarlo con el metodo tradicional a insertarlo a través de las vistas
    miércoles, 26 de junio de 2019 20:13
  • En la inserción, básicamente ninguna, pero en la select, si, ya no tienes que depender de la otra tabla, porque ya lo tienes en la vista. El ejemplo te quiere mostrar, que puedes hacer directamente sobre la vista, las operaciones de inserción, borrado, o actualización, como si de la tabla se tratase, pero obtienes siempre la tabla relacionada.

    Por tanto si trabajas siempre con la vista, para ti es como no tener la segunda tabla, pero teniéndola y estando los datos normalizados.

    miércoles, 26 de junio de 2019 21:01