我即将开发基于PHP / MySQL的聊天系统。数据库和网站都将在同一台服务器上运行。我希望能够同时在线支持300名用户。这显然会持续产生大量查询。因此,优化数据库设计是必须的。
我的MySQL技能是平均水平。我尽力学习优化,并做了我自己理解的一切。我还不确定它是否足够好。我希望你们可以看看它,并就如何进一步优化它提出建议。
欢迎任何有关如何减少服务器负载的其他提示。请记住,由于当地法律,所有邮件都必须保存。
CREATE TABLE IF NOT EXISTS `bans` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`userid` int(11) NOT NULL,
`ipaddress` varchar(32) NOT NULL,
`reason` text,
`bandate` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `BAN_INDEX` (`userid`,`ipaddress`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `chatboxes` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`boxname` varchar(32) NOT NULL,
`password` varchar(32) NOT NULL,
`accesslvl` tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`),
UNIQUE KEY `BOX_INDEX` (`boxname`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `ignorelist` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`userid` int(11) NOT NULL,
`blockedusr` varchar(16) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `messages` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`userid` int(11) NOT NULL,
`boxname` varchar(32) NOT NULL,
`message` text,
`receiver` varchar(16) NOT NULL,
`alert` tinyint(1) NOT NULL DEFAULT '0',
`msgdate` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(16) NOT NULL,
`password` varchar(32) NOT NULL,
`email` varchar(64) NOT NULL,
`gender` tinyint(1) NOT NULL DEFAULT '0',
`sexpref` tinyint(1) NOT NULL DEFAULT '0',
`birthdate` date DEFAULT NULL,
`regdate` datetime DEFAULT NULL,
`lastlogin` datetime DEFAULT NULL,
`warnings` tinyint(1) NOT NULL DEFAULT '0',
`accesslvl` tinyint(1) NOT NULL DEFAULT '1',
`kicks` tinyint(3) NOT NULL DEFAULT '0',
`ipaddress` varchar(32) NOT NULL,
`online` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `USER_INDEX` (`username`,`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
答案 0 :(得分:1)
虽然我不知道您选择的原因,但我建议对于在users
表中存储对用户的引用的表(bans
,ignorelist
,{{ 1}}),您应该存储用户主键messages
(创建id
字段以将这些数据存储在每个表中)而不是userid
。这将允许标准化数据。如果用户更改了他的名字,您不想返回并更新所有其他表。
此外,IP地址并不总是静态的,所以除非你只是禁止用户使用某个特定的IP地址(效率不高),并假设用户必须登录才能进行聊天,否则我会建议再次禁用{ {1}}这样您就可以在username
userid
了
要查询显示用户名作为结果集一部分的禁令,请将UNIQUE KEY
加入userid
(例如bans
)
希望这有帮助。