none
Come strutturare il db RRS feed

  • Domanda

  • Buongiorno a tutti,
    vorrei da parte vostra un consiglio su come strutturare le tabelle del mio db sql.
    Ho realizzato un piccolo sito web ecommerce in MVC con database sql e tra le varie tabelle ha quella relativa ai prodotti.
    Ho una tabella "Prodotti" con tutte le informazioni sui prodotti e un'altra tabella "Prezziprodotto" che contengono i vari prezzi di ciascun prodotto.

    Ecco le tabelle:
    Prodotti (ID, Nome, Descrizione, ...)
    Prezziprodotto (ID, Idprodotto, Nomevariante, Valorevariante, Importo, Pezzi)

    La tabella dei prezzi contiene oltre al prezzo anche informazioni sulle varianti prodotti (peso, taglia, ecc..)

    Un esempio di alcuni dati:
    Tabella Prodotti
    1 - Felpa in pile - bla bla, ...

    Tabella Prezziprodotto
    1 - 1 - Taglia - M - 10,00 - 5
    2 - 1 - Taglia - L - 10,00 - 5
    3 - 1 - Colore - Blu - 15,00 - 5

    Volendo unire due righe (magari l'utente acquista la felpa scegliendo sia la taglia che il colore),
    come posso unire le due righe? Come stabilisco il prezzo corretto?

    giovedì 23 gennaio 2020 12:23

Risposte

  • Ciao Piero,

    il mio consiglio è quello di separare le entità Taglie e Colori, aggiungere una tabella di "associazione" Prodotti-Taglie-Colori ed infine la tabella che contiene i prezzi dei prodotti con il riferimento della tabella di "associazione".

    Per maggior chiarezza ho riportato i due esempi, la struttura attuale può essere creata con questo script:

    USE [tempdb];
    GO
    
    DROP TABLE IF EXISTS dbo.Prodotti;
    GO
    
    CREATE TABLE dbo.Prodotti
    (
      ID INTEGER IDENTITY(1, 1) NOT NULL PRIMARY KEY
      ,Nome NVARCHAR(64)
      ,Descrizione NVARCHAR(128)
    );
    GO
    
    DROP TABLE IF EXISTS dbo.PrezziProdotto;
    GO
    
    CREATE TABLE dbo.PrezziProdotto
    (
      ID INTEGER IDENTITY(1, 1) NOT NULL PRIMARY KEY
      ,IDProdotto INTEGER NULL
      ,NomeVariante NVARCHAR(64)
      ,ValoreVariante NVARCHAR(32)
      ,Importo DECIMAL(12, 6)
      ,Pezzi DECIMAL(12, 3)
    );
    GO
    
    INSERT INTO dbo.Prodotti
    (Nome, Descrizione) VALUES ('Felpa in pile', 'bla bla');
    GO
    
    INSERT INTO dbo.PrezziProdotto
    (IDProdotto, NomeVariante, ValoreVariante, Importo, Pezzi)
    VALUES
    (1, 'Taglia', 'M', 10.00, 5)
    ,(1, 'Taglia', 'L', 10.00, 5)
    ,(1, 'Colore', 'Blu', 15.00, 5)
    GO
    
    SELECT * FROM dbo.Prodotti;
    SELECT * FROM dbo.PrezziProdotto;
    GO

    In sintesi, la chiave della tabella dbo.PrezziProdotto descrive direttamente anche attributi che non "derivano" dalla chiave come la Taglia ed il Colore, da qui il problema che hai esposto..


    Potresti valutare una struttura di questo tipo:

    USE [tempdb];
    GO
    
    DROP TABLE IF EXISTS dbo.ATaglieColori;
    DROP TABLE IF EXISTS dbo.Taglie;
    DROP TABLE IF EXISTS dbo.Colori;
    DROP TABLE IF EXISTS dbo.Prodotti;
    DROP TABLE IF EXISTS dbo.PrezziProdotto;
    GO
    
    CREATE TABLE dbo.Taglie
    (
      ID INTEGER IDENTITY(1, 1) NOT NULL PRIMARY KEY
      ,Codice NVARCHAR(64)
      ,Descrizione NVARCHAR(128)
    );
    GO
    
    INSERT INTO dbo.Taglie
    (Codice, Descrizione) VALUES
    ('M', 'Medium')
    ,('L', 'Large')
    ,('S', 'Small')
    ,('U', 'Unique');
    GO
    
    CREATE TABLE dbo.Colori
    (
      ID INTEGER IDENTITY(1, 1) NOT NULL PRIMARY KEY
      ,Codice NVARCHAR(64)
      ,Descrizione NVARCHAR(128)
    );
    GO
    
    INSERT INTO dbo.Colori
    (Codice, Descrizione) VALUES
    ('B', 'Blu')
    ,('V', 'Verde');
    GO
    
    CREATE TABLE dbo.ATaglieColori
    (
      ID INTEGER IDENTITY(1, 1) NOT NULL PRIMARY KEY
      ,IDProdotti INTEGER NOT NULL
      ,IDTaglie INTEGER NOT NULL
      ,IDColori INTEGER NOT NULL
    );
    GO
    
    CREATE TABLE dbo.Prodotti
    (
      ID INTEGER IDENTITY(1, 1) NOT NULL PRIMARY KEY
      ,Nome NVARCHAR(64)
      ,Descrizione NVARCHAR(128)
    );
    GO
    
    INSERT INTO dbo.Prodotti
    (Nome, Descrizione) VALUES ('Felpa in pile', 'bla bla');
    GO
    
    ALTER TABLE dbo.ATaglieColori ADD CONSTRAINT
      FK_Prodotti FOREIGN KEY (IDProdotti) REFERENCES dbo.Prodotti(ID);
    
    ALTER TABLE dbo.ATaglieColori ADD CONSTRAINT
      FK_Taglie FOREIGN KEY (IDTaglie) REFERENCES dbo.Taglie(ID);
    
    ALTER TABLE dbo.ATaglieColori ADD CONSTRAINT
      FK_Colori FOREIGN KEY (IDColori) REFERENCES dbo.Colori(ID);
    
    INSERT INTO dbo.ATaglieColori
    (IDProdotti, IDTaglie, IDColori) VALUES
    (1, 1, 1)
    ,(1, 2, 2);
    GO
    
    CREATE TABLE dbo.PrezziProdotto
    (
      ID INTEGER IDENTITY(1, 1) NOT NULL PRIMARY KEY
      ,IDATaglieColori INTEGER NULL
      ,Importo DECIMAL(12, 6)
      ,Pezzi DECIMAL(12, 3)
    );
    GO
    
    INSERT INTO dbo.PrezziProdotto
    (IDATaglieColori, Importo, Pezzi)
    VALUES
    (1, 10.00, 5.00)
    ,(2, 15.00, 5.00);
    GO
    
    SELECT * FROM dbo.Prodotti;
    SELECT * FROM dbo.Taglie;
    SELECT * FROM dbo.Colori;
    SELECT * FROM dbo.ATaglieColori;
    SELECT * FROM dbo.PrezziProdotto;
    GO

    La tabella di "associazione" dbo.ATaglieColori conterrà tutte le combinazioni che desideri vendere per Prodotto/Taglia/Colore. La tabella dbo.PrezziProdotto conterrà il riferimento alla tabella di associazione e non al prodotto direttamente.

    Non ti consiglio di aggiungere gli attributi Taglie e Colore nella tabella Prodotti per evitare il prodotto cartesiano nell'anagrafica Prodotti.

    Se desideri gestire le giacenze, le cose si complicano :) idem per gli sconti per quantità :)

    Spero possa essere d'aiuto.

    Ciao!

    Sergio Govoni

    Microsoft Data Platform MVP | MVP Profile | English Blog | Twitter | LinkedIn

    sabato 25 gennaio 2020 15:50
    Moderatore