我正在使用PHP和MySQL编写基于Web的测验应用程序。我不想特别向你介绍它的细节,所以这就是(我认为)你需要知道的。
问题都是多项选择,可以存储在一个包含几列的简单表中:
用户可以通过创建用户名和密码进行注册,然后尝试从类别中提问。
问题在于我写的问题是不止一次尝试过的。但是,用户需要获得有关其进度的详细反馈。对问题的第一次尝试至关重要,并有助于用户的整体'问题第一次回答'得分。因此,我需要跟踪问题的尝试次数。
由于应用程序设计灵活,我希望能够支持数百个用户尝试数千个问题。因此,尝试将此信息集成到用户表或问题表中似乎是不可能的。我想解决此问题的方法是在注册时为每个用户创建一个新表,其中包含各种列。
所以我想我想问的是,以这种方式组织数据库是否明智。是否有更好的方法而不是为每个用户创建一个新表?如果说有500个用户和2000个问题会对性能造成多大影响?
感谢。
答案 0 :(得分:5)
您不想要为每个用户创建一个新表。而是修改您的数据库结构。
通常情况下,你有一个问题表,一个选项表(可能有一个布尔列来指示它是否是正确答案),一个用户表,一个关于用户的连接表和用于存储用户响应的选项。示例模式:
CREATE TABLE `options` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`question_id` int(10) unsigned NOT NULL,
`text` varchar(255) NOT NULL,
`correct` tinyint(1) NOT NULL,
PRIMARY KEY (`id`),
KEY `question_id` (`question_id`)
) TYPE=InnoDB;
CREATE TABLE `options_users` (
`option_id` int(10) unsigned NOT NULL,
`user_id` int(10) unsigned NOT NULL,
`created` timestamp NOT NULL,
KEY `option_id` (`option_id`),
KEY `user_id` (`user_id`)
) TYPE=InnoDB;
CREATE TABLE `questions` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`question` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`,`question`)
) TYPE=InnoDB;
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(60) NOT NULL,
`password` char(40) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) TYPE=InnoDB;
ALTER TABLE `options`
ADD CONSTRAINT `options_ibfk_1` FOREIGN KEY (`question_id`) REFERENCES `questions` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `options_users`
ADD CONSTRAINT `options_users_ibfk_2` FOREIGN KEY (`option_id`) REFERENCES `options` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `options_users_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
这会将问题选项与用户对选项的回复联系起来。我还在created
表格中添加了options_users
列,以便您查看用户何时回答问题并跟踪他们的进度。