您应该使用 MySQL 触发器而不是 PHP 代码,并且您必须将相关信息存储user_id
到diskusage
表中。
我使用InnoDB
引擎是因为CONSTRAINT
. 您也可以使用MyISAM
,但您应该删除CONSTRAINT
.
评论
我会使用InnoDB
因为Transactions和(在这里更重要)Row-Locking。
表结构(InnoDB)
-- ----------------------------
-- Table structure for `users`
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`Name` VARCHAR(10) NOT NULL DEFAULT '',
`SpaceUsed` BIGINT(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for `diskusage`
-- ----------------------------
DROP TABLE IF EXISTS `diskusage`;
CREATE TABLE `diskusage` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`Filename` VARCHAR(50) NOT NULL DEFAULT '',
`Size` BIGINT(20) NOT NULL,
`user_id` INT(11) UNSIGNED DEFAULT NULL,
`Fully_Updated_File_Flag` TINYINT(4) NOT NULL,
PRIMARY KEY (`id`),
KEY `fk_diskusage_user` (`user_id`),
CONSTRAINT `fk_diskusage_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=INNODB DEFAULT CHARSET=utf8;
表结构(MyISAM)
-- ----------------------------
-- Table structure for `users`
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`Name` VARCHAR(10) NOT NULL DEFAULT '',
`SpaceUsed` BIGINT(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for `diskusage`
-- ----------------------------
DROP TABLE IF EXISTS `diskusage`;
CREATE TABLE `diskusage` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`Filename` VARCHAR(50) NOT NULL DEFAULT '',
`Size` BIGINT(20) NOT NULL,
`user_id` INT(11) UNSIGNED DEFAULT NULL,
`Fully_Updated_File_Flag` TINYINT(4) NOT NULL,
PRIMARY KEY (`id`),
KEY `fk_diskusage_user` (`user_id`),
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
就是这样,再加上 table 上的一些触发器diskusage
。
插入触发器
-- ----------------------------
-- AFTER INSERT TRIGGER for `diskusage`
-- ----------------------------
delimiter ;;
CREATE TRIGGER `diskusage_after_insert` AFTER INSERT ON `diskusage` FOR EACH ROW BEGIN
IF NEW.Fully_Updated_File_Flag = 1 THEN
UPDATE users
SET
SpaceUsed = SpaceUsed + NEW.Size
WHERE
id = NEW.user_id;
END IF;
END;
;;
delimiter ;
更新触发器
-- ----------------------------
-- AFTER UPDATE TRIGGER for `diskusage`
-- ----------------------------
delimiter ;;
CREATE TRIGGER `diskusage_after_update` AFTER UPDATE ON `diskusage` FOR EACH ROW BEGIN
-- same to DELETE TRIGGER
-- decrease SpaceUsed with OLD Size for OLD user
IF OLD.Fully_Updated_File_Flag = 1 THEN
UPDATE users
SET
SpaceUsed = SpaceUsed - OLD.Size
WHERE
id = OLD.user_id;
END IF;
-- same to INSERT TRIGGER
-- increase SpaceUsed with NEW Size for NEW user
IF NEW.Fully_Updated_File_Flag = 1 THEN
UPDATE users
SET
SpaceUsed = SpaceUsed + NEW.Size
WHERE
id = NEW.user_id;
END IF;
END;
;;
delimiter ;
删除触发器
-- ----------------------------
-- AFTER DELETE TRIGGER for `diskusage`
-- ----------------------------
delimiter ;;
CREATE TRIGGER `diskusage_after_delete` AFTER DELETE ON `diskusage` FOR EACH ROW BEGIN
IF OLD.Fully_Updated_File_Flag = 1 THEN
UPDATE users
SET
SpaceUsed = SpaceUsed - OLD.Size
WHERE
id = OLD.user_id;
END IF;
END;
;;
delimiter ;