您應該使用MySQL觸發器代替PHP代碼,並且您必須將相關user_id
存儲到diskusage
表中。
我使用InnoDB
引擎,因爲CONSTRAINT
。您也可以使用MyISAM
,但您應該刪除CONSTRAINT
。
REMARK
我會用InnoDB
因爲交易和(更重要的位置)行鎖定。
表結構(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;
這就是所有,與上表diskusage
一些觸發器在一起。
INSERT觸發器
-- ----------------------------
-- 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 ;
UPDATE觸發器
-- ----------------------------
-- 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 ;
DELETE TRIGGER
-- ----------------------------
-- 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 ;
所以,如果我理解正確的話,無論我使用觸發器還是通過PHP運行查詢,InnoDB基本上都不會遇到擴展問題(至少就這個特定的UPDATE查詢而言)?那是對的嗎? – TheDude