这更像是一个理论问题,我认为最好的方法是从一个例子开始。
假设我有一个评级系统。每个用户都可以对任何项目进行一次评级,每个项目只能被任何用户评价一次。我想提供每个用户评级的历史记录(他评价的所有项目,评级,时间等)。
我解决这个问题的方法是找一个像这样的表:
rating_id | user_id | item_id | rating | date
此表存储每个评级和一些其他所需数据。在这种情况下,如果有10k个用户和10k个项目,那么表格将是一个非常长的表格,除此之外,我还需要使用一些JOIN来查找用户的名字和他评价的项目的名称。所以我猜这需要很多时间。
我是在正确的道路上还是有更好的解决方案来解决我的问题?
答案 0 :(得分:2)
您好TGM ,
基本上有很多方法可以对数据库进行建模,并且通常不能将它们都声明为最佳方法。任何数据库的最佳设计取决于使用它的上下文。 然而,一些原则似乎比其他原则更多地达成一致。基本上,了解良好数据库设计的最佳方法是检查流行应用程序中使用的设计。更多关于此的内容。
在你失去兴趣之前,让我提出一个共同的模式:
CREATE TABLE items (
item_id INTEGER NOT NULL,
name VARCHAR NOT NULL,
description VARCHAR NOT NULL,
CONSTRAINT items_pk PRIMARY KEY (item_id)
);
CREATE TABLE users (
user_id INTEGER NOT NULL,
name VARCHAR NOT NULL,
username VARCHAR NOT NULL,
password VARCHAR NOT NULL,
email VARCHAR NOT NULL,
CONSTRAINT users_pk PRIMARY KEY (user_id)
);
CREATE TABLE ratings (
item_id INTEGER NOT NULL,
user_id INTEGER NOT NULL,
rating_id INTEGER NOT NULL,
timestamp TIMESTAMP NOT NULL,
CONSTRAINT ratings_pk PRIMARY KEY (item_id, user_id)
);
ALTER TABLE ratings ADD CONSTRAINT items_ratings_fk
FOREIGN KEY (item_id)
REFERENCES items (item_id)
ON DELETE NO ACTION
ON UPDATE NO ACTION
NOT DEFERRABLE;
ALTER TABLE ratings ADD CONSTRAINT users_ratings_fk
FOREIGN KEY (user_id)
REFERENCES users (user_id)
ON DELETE NO ACTION
ON UPDATE NO ACTION
NOT DEFERRABLE;
在这个模型中我使用了三个表。重要的元素是在评级表中,两个外键是表的主键,因为正是这对键确保用户只能对项目进行一次评级。您当然可以将ratings_id添加到主键集,尽管它不会对您在问题中提到的表约束产生太大影响。
足够我的设计。让我们来看看你应该做些什么。
不要盲目地依赖别人的意见,而应该投入一些时间,亲自了解哪些数据库设计常用于评级系统。
这是你应该做的:
安装数据库建模工具。我个人更喜欢SQL Power Architect,这是一个开源解决方案,使您能够对最常用的数据库进行逆向工程和转发数据库模型。该工具也非常适合玩数据库模型。上面示例中的架构使用SQL Power Architect。
如果您更喜欢其他解决方案,可以在databaseanswers找到一长串替代工具。
在网络上搜索开源评级软件,并在开发服务器上安装这些软件。如果您懒得这样做,请查看以下备选方案:Rating System,Open Rating或PHP Stars。
将SQL Power Architect连接到不同的数据库,并使用逆向工程师检查和比较不同的解决方案。
如果您按照这些步骤操作,您很快就会获得有关如何为自己的评级应用程序设置/建模数据库的一些想法。
祝你的项目好运。
答案 1 :(得分:0)
该表只包含与每个用户评价的项目数相同的行数。那将是多少?就个人而言,我不会评价10,000件物品。我可能会评分20或30或100.旧评级可能没用,所以您可以删除其中一些。 (三年的洗发水评级通常不常用;洗发水配方一直在变化。)
如果您需要显示用户名或项目名称,则需要加入用户表和项目表。使用id号始终需要连接才能获得有用的数据。
从这些方面来说,一切都应该没问题。
create table ratings (
user_id integer not null, -- references users (user_id), not shown
item_id integer not null, -- references items (item_id), not shown
primary key (user_id, item_id),
rating integer not null check (rating between 1 and 5) -- ?
date_rated date not null default current_date
);
create index on ratings (date_rated);
您的下一步可能是partitioning。