SQL Server + design del database e campi non obbligatori

0

Sto sviluppando un'applicazione che consente a un utente di caricare un massimo di 20 foto, la via diretta è naturalmente l'aggiunta di 20 colonne alla mia tabella di database, ma se l'utente carica solo 1 immagine, le colonne rimanenti diventano ridondanti. Chiunque può consigliarmi su un modo più efficiente di progettarlo?

Grazie.

    
posta user415795 22.04.2013 - 10:23
fonte

3 risposte

9

Non dovresti mai usare più colonne per contenere più di uno dello stesso articolo. Si tratta di una cattiva progettazione del database e sarà un grave problema da usare (prova a scrivere una query che recuperi e visualizzi tutte le foto di un utente, o cancelli una foto, e vedrai cosa intendo).

Un altro problema è che potresti voler memorizzare altre informazioni su ogni foto, ad esempio quando è stata caricata e in che formato è. Invece di 20 colonne, all'improvviso potresti avere 60 o 80 colonne nella tabella. Ugh!

Invece, avere una tabella di foto che è separata dalla tabella degli utenti. Questo è collegato alla tabella utente sull'ID utente. Puoi applicare il limite di 20 foto con un vincolo di tabella o semplicemente controllando il numero di foto a livello di codice prima di consentire il caricamento.

Tabella utente :

Primary Key |       |       |
USER_ID     | FIRST | LAST  | ETC.
12345       | John  | Smith | ... Any other user-specific columns

Tabella foto :

Primary Key | Foreign Key |        |        |            |
PHOTO_ID    | USER_ID     | PHOTO  | FORMAT | DATE       | ETC.
13516       | 12345       | <data> | JPG    | 2013-05-01 | ... Other photo-specific columns

Se imposti la chiave esterna per foto a on delete cascade , le foto di un utente verranno automaticamente eliminate se elimini l'utente.

Vedi questa domanda StackOverflow per informazioni su un vincolo di tabella per limitare il numero di foto per utente.

Ottenere le foto per un utente usa una semplice query:

select * from photo
    where user_id = 12345;

Se hai bisogno di foto e informazioni utente come il nome, usa un join:

select first, last, photo from photo p
   inner join user u on p.user_id = u.user_id;

Aggiornamento: Sono d'accordo con Pieter B che, nella maggior parte dei casi, è preferibile archiviare le immagini separatamente nella struttura del file, e basta fare in modo che la tabella images memorizzi il nome del file di ogni immagine. Ciò renderà molto più semplice, per esempio, visualizzare le immagini su una pagina web. Ma avrai anche bisogno di codice aggiuntivo per assicurarti che la directory rimanga sincronizzata con la tabella: se elimini un utente, devi andare manualmente a eliminare tutte le immagini.

    
risposta data 22.04.2013 - 10:31
fonte
2

In generale, non memorizzerei le foto in formato binario in un database. Quello che vorrei fare è archiviare le foto su disco e memorizzare il percorso di quella foto nel database.

Altre risposte hanno già mostrato come creare una tabella separata, ma con i riferimenti invece dei file binari.

    
risposta data 22.04.2013 - 11:49
fonte
0

Aggiungi una tabella figlio

PhotoID int NOT NULL IDENTITY(1,1) PRIMARY KEY,
UserID int NOT NULL -- FK to User table,
Photo varbinary(max)

Cambia colonne in righe, semplicemente come per primo modulo normale

Ci sono vantaggi di storage perché ora non hai più 20 BLOB in una sola riga utente. La tua tabella utente ha un ingombro di memoria molto inferiore per le altre colonne.

E puoi consentire più di 20 foto molto facilmente se decidi di permetterne di più.

    
risposta data 22.04.2013 - 10:32
fonte

Leggi altre domande sui tag