Because I've never designed a database, I wanted to make sure that the design I'm using, while simple, follows general idiomatic design patterns.
Essentially, a friend is making a discord bot that allows you to submit photos and have others rate them. Putting the obvious trolling opportunities aside, here are the data fields that are needed:
- Discord ID (unique ID for every person using discord)
- List of URLs (each URL is tied to a certain discord member)
- List of Votes (each vote has a score, the voter ID, and the URL)
What I don't particularly like about this design is that it maintains two scores: a running total that will be divided by the total number of votes of that user, and each vote in particular.
My questions are:
- Is this design proper?
- Using this design, how can I ensure that each person can only vote for each url once?
https://dbdesigner.net output:
CREATE TABLE "Members" (
"id" serial NOT NULL,
"discord_id" bigint NOT NULL,
"total_score" bigint NOT NULL,
"total_votes" bigint NOT NULL,
CONSTRAINT Members_pk PRIMARY KEY ("id")
) WITH (
OIDS=FALSE
);
CREATE TABLE "Images" (
"id" serial NOT NULL,
"url" TEXT(64) NOT NULL,
"member_id" bigint NOT NULL,
CONSTRAINT Images_pk PRIMARY KEY ("id")
) WITH (
OIDS=FALSE
);
CREATE TABLE "Votes" (
"id" serial NOT NULL,
"voter_id" serial NOT NULL,
"target_id" serial NOT NULL,
"score" serial NOT NULL,
"image_id" serial NOT NULL,
CONSTRAINT Votes_pk PRIMARY KEY ("id")
) WITH (
OIDS=FALSE
);
ALTER TABLE "Images" ADD CONSTRAINT "Images_fk0" FOREIGN KEY ("member_id") REFERENCES "Members"("discord_id");
ALTER TABLE "Votes" ADD CONSTRAINT "Votes_fk0" FOREIGN KEY ("voter_id") REFERENCES "Members"("discord_id");
ALTER TABLE "Votes" ADD CONSTRAINT "Votes_fk1" FOREIGN KEY ("target_id") REFERENCES "Members"("discord_id");
ALTER TABLE "Votes" ADD CONSTRAINT "Votes_fk2" FOREIGN KEY ("image_id") REFERENCES "Images"("id");
