Domanda

Sto realizzando una webapp in questo momento e sto cercando di orientarmi nella progettazione del database.

Ho un modello utente (nome utente (che è la chiave primaria), password, email, sito Web) Ho un modello di iscrizione (id, titolo, contenuto, commenti, commentCount)

Un utente può commentare una voce una sola volta. Qual è il modo migliore e più efficiente per farlo?

Al momento, sto pensando a un'altra tabella con nome utente (dal modello utente) e ID voce (dal modello voce)

   **username    id**
    Sonic        4
    Sonic        5
    Knuckles     2
    Sonic        6
    Amy          15
    Sonic        20
    Knuckles     5
    Amy          4

Quindi, per elencare i commenti per la voce 4, cerca id = 4.

Nota a margine: Invece di archiviare un commento, sarebbe meglio calcolare il conteggio dei commenti dal database ogni volta che è necessario?

È stato utile?

Soluzione

Il tuo design è sostanzialmente solido. La tua terza tabella dovrebbe essere denominata come UsersEntriesComments, con i campi UserName, EntryID e Comment. In questa tabella, avresti una chiave primaria composta composta dai campi UserName e EntryID; questo imporrebbe la regola che ogni utente può commentare ogni voce una sola volta. La tabella avrebbe anche vincoli di chiave esterna tali che UserName deve essere nella tabella Users e EntryID deve essere nella tabella Entries (il campo ID, in particolare).

Puoi aggiungere un campo ID alla tabella Users, ma molti programmatori (incluso me stesso) sostengono l'uso di " natural " chiavi ove possibile. Poiché i nomi utente devono essere univoci nel sistema, questa è una chiave primaria perfettamente valida (e facilmente leggibile).

Aggiorna : rileggi la tua domanda. Non sono necessari i campi Commenti o Commenti nella tabella Voci. I commenti verrebbero correttamente memorizzati nella tabella UsersEntriesComments e i conteggi verrebbero calcolati dinamicamente nelle tue query (risparmiando il problema di aggiornare questo valore tu stesso).

Aggiornamento 2 : James Black fa un buon punto a favore di non utilizzando UserName come chiave primaria e aggiungendo invece una chiave primaria artificiale alla tabella (UserID o alcuni di questi). Se si utilizza UserName come chiave primaria, consentire a un utente di modificare il proprio nome utente è più difficile, poiché è necessario modificare anche il nome utente in tutte le tabelle correlate.

Altri suggerimenti

Cosa intendi esattamente con

entry model(id, title, content, **comments**, commentCount)

(enfasi sulla mia)? Dal momento che sembra che tu abbia più commenti per entità, dovrebbero essere archiviati in una tabella separata:

comments(id, entry_id, content, user_id)

entry_id e user_id sono chiavi esterne delle rispettive tabelle. Ora devi solo creare un indice univoco su ( entry_id , user_id ) per assicurarti che l'utente possa aggiungere un solo commento per entità.

Inoltre, potresti voler creare una chiave primaria surrogata (numerica, generata tramite sequenza / identità) per la tabella degli utenti invece di impostare il nome utente come PK.

Ecco la mia raccomandazione per il tuo modello di dati:

UTENTI tabella

  • USER_ID (pk, int)
  • USER_NAME
  • PASSWORD
  • EMAIL
  • sito web

ENTRY tabella

  • ENTRY_ID (pk, int)
  • ENTRY_TITLE
  • CONTENUTO

ENTRY_COMMENTS tabella

  • ENTRY_ID (pk, fk)
  • USER_ID (pk, fk)
  • COMMENTO

Questa configurazione consente a un ENTRY di avere più di 0 commenti. Quando viene aggiunto un commento, la chiave primaria è una chiave composita di ENTRY_ID e USER_ID significa che la coppia può esistere solo una volta nella tabella (IE: 1, 1 vinto ' consenti di aggiungere nuovamente 1, 1).

Non archiviare i conteggi in una tabella: utilizzare una VISTA per questo in modo che il numero possa essere generato in base ai dati esistenti al momento dell'esecuzione.

  1. Non userei il nome utente come ID principale. Vorrei fare un ID numerico con autoincrement
  2. Vorrei usare quel nuovo ID nella tabella delle relazioni con una chiave univoca sui 2 campi

Anche se non è nella domanda, potresti voler avere un ID utente che è la chiave primaria, altrimenti sarà difficile se l'utente è autorizzato a cambiare il suo nome utente o far sapere a certe persone che non puoi cambiare il tuo nome utente.

Rendi la tabella unita un vincolo univoco su userid e entryid. In questo modo il database impone che vi sia un solo commento / voce / utente.

Sarebbe utile se si specifica un database, tra l'altro.

Sembra che tu voglia garantire che l'insieme di commenti sia univoco rispetto a nome utente X post_id . Puoi farlo usando un vincolo univoco o se il tuo sistema di database non lo supporta esplicitamente, con un indice che fa lo stesso. Ecco alcuni SQL che lo esprimono:

CREATE TABLE users (
    username VARCHAR(10) PRIMARY KEY,
    -- any other data ...
);

CREATE TABLE posts (
    post_id INTEGER PRIMARY KEY,
    -- any other data ...
);

CREATE TABLE comments (
    username VARCHAR(10) REFERENCES users(username),
    post_id INTEGER REFERENCES posts(post_id),
    -- any other data ...
    UNIQUE (username, post_id) -- Here's the important bit!
);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top