Pergunta
Eu estou fazendo um webapp agora e eu estou tentando obter minha cabeça em torno do projeto de banco de dados.
Eu tenho um modelo de usuário (username (que é chave primária), senha, email, website) Eu tenho um modelo de entrada (id, título, conteúdo, comentários, commentCount)
Um usuário só pode comentar sobre uma entrada uma vez. Qual é o melhor e mais eficiente maneira de ir sobre como fazer isso?
No momento, estou pensando em outra tabela que tem nome de usuário (de modelo de usuário) e identificação de entrada (a partir do modelo de entrada)
**username id**
Sonic 4
Sonic 5
Knuckles 2
Sonic 6
Amy 15
Sonic 20
Knuckles 5
Amy 4
Assim, pois, aos comentários da lista para a entrada 4 ele procura id = 4.
Em uma nota lateral: Em vez de armazenar um commentCount, seria melhor para calcular o comentário contagem do banco de dados cada vez que quando necessário?
Solução
Seu projeto é basicamente som. Sua terceira tabela deve ser nomeado algo como UsersEntriesComments, com campos UserName, EntryID e Comentário. Nesta tabela, você teria uma chave primária composta que consiste nos campos nome de usuário e IDEntrada; isso iria impor a regra de que cada usuário pode comentar sobre cada entrada apenas uma vez. A tabela também teria restrições de chave estrangeira como esse nome de usuário deve ser na tabela de usuários, e EntryID deve estar na tabela de entradas (o campo ID, especificamente).
Você pode adicionar um campo de ID para a tabela de usuários, mas muitos programadores (eu incluído) defendem o uso de chaves "naturais" sempre que possível. Desde nomes de usuário deve ser exclusivo em seu sistema, esta é uma chave primária perfeitamente válida (e de fácil leitura).
Atualizar : basta ler a sua pergunta novamente. Você não precisa de comentários ou os campos CommentsCount na sua tabela entradas. Comentários iria ser adequadamente armazenado na tabela de UsersEntriesComments, e as contagens seria calculado dinamicamente em suas consultas (salvando-lhe a dificuldade de atualizar este valor a si mesmo).
Update 2 : James Black faz um ponto bom em favor de não com o utilizador como a chave primária e, em vez de adicionar uma chave primária artificial para a mesa (UserID ou alguns, tais). Se você usar o nome de utilizador como a chave primária, permitindo que um usuário para mudar seu nome de usuário é mais difícil, pois você tem que mudar o nome de usuário em todos os tabelas relacionadas também.
Outras dicas
O que exatamente você quer dizer com
entry model(id, title, content, **comments**, commentCount)
(ênfase minha)? Uma vez que parece que você tem vários comentários por entidade, eles devem ser armazenados em uma tabela separada:
comments(id, entry_id, content, user_id)
entry_id
e user_id
são chaves estrangeiras às respectivas tabelas. Agora você só precisa criar um índice exclusivo na (entry_id
, user_id
) para garantir usuário só pode adicionar um comentário por entidade.
Além disso, você pode querer criar um substituto (numérico, gerado via seqüência / identidade) chave primária para sua tabela de usuários em vez de fazer o nome de usuário a sua PK.
Aqui é a minha recomendação para o seu modelo de dados:
Usuários tabela
- USER_ID (pk, int)
- USER_NAME
- SENHA
- WEBSITE
ENTRADA tabela
- entry_id (pk, int)
- ENTRY_TITLE
- CONTENT
ENTRY_COMMENTS tabela
- entry_id (pk, fk)
- USER_ID (pk, fk)
- COMENTÁRIO
Esta configuração permite uma entrada para ter 0+ comentários. Quando um comentário é adicionado, a chave principal sendo uma chave composta de meios ENTRY_ID
e USER_ID
que o par só pode existir uma vez na tabela. (IE: 1, 1 não irá permitir que um, 1 a ser adicionado de novo)
Não guarde as contagens em uma tabela - usar uma exibição para que assim que o número pode ser gerado com base nos dados existentes no momento da execução
.- Eu não usaria o nome de usuário como um ID primário. Eu faria um id numérico com autoincrement
- eu usaria esse novo ID na tabela de relações com uma chave única nos 2 campos
Mesmo que não está na pergunta, você pode querer ter um ID de usuário que é a chave primária, caso contrário, será difícil se o usuário tem permissão para mudar seu nome de usuário, ou fazer certas pessoas saibam que você não pode mudar seu nome de usuário.
Faça a tabela associada tem uma restrição exclusiva sobre o ID do usuário e entryid. Dessa forma, as forças de banco de dados que não há apenas um comentário / entry / usuário.
Seria bom se você especificou um banco de dados, btw.
Parece que você quer garantia de que o conjunto de comentários é único em relação ao username
X post_id
. Você pode fazer isso usando uma restrição exclusiva, ou se o seu sistema de banco de dados não suporta que explicitamente, com um índice que faz o mesmo. Aqui estão algumas SQL expressando que:
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!
);