我有一个由int
主键和text
列组成的表,主要充当“读取”角色。目前只有大约 40,000 行,但随着时间的推移,我预计每年会增加 500,000 行。这是在一个每天可能有 10 个活跃用户的系统上,所以影响非常小。
使用 MyISAM,表小于 4MB。使用 InnoDB,它超过 7MB。
如果磁盘空间是一个问题,那么 MyISAM 真的那么不值得信任,以至于我应该使用 InnoDB 而不是 MyISAM 吗?
背景:
每次修改列时,我都需要更新第二个表中的关联列(具有相同名称)。这是我第一次尝试使用触发器。
代码:
这是我正在尝试做的一个简化示例,它的工作很好,但效率低下:
DROP TRIGGER IF EXISTS update_second_table;
DELIMITER //
CREATE TRIGGER update_second_table
BEFORE UPDATE ON first_table
FOR EACH ROW
BEGIN
/* putting IF statements on one line so it's easier to see what's happening */
IF NOT(OLD.firstname <=> NEW.firstname) THEN UPDATE second_table SET firstname = CURRENT_TIMESTAMP WHERE id = OLD.id; END IF;
IF NOT(OLD.middlename <=> NEW.middlename) THEN UPDATE second_table SET middlename = CURRENT_TIMESTAMP WHERE id = OLD.id; END IF;
IF NOT(OLD.lastname <=> NEW.lastname) THEN UPDATE second_table SET lastname = CURRENT_TIMESTAMP WHERE id = OLD.id; END IF;
IF NOT(OLD.nickname <=> NEW.nickname) THEN UPDATE second_table SET nickname = CURRENT_TIMESTAMP WHERE id = OLD.id; END IF;
IF NOT(OLD.dob <=> NEW.dob) THEN UPDATE second_table SET dob = CURRENT_TIMESTAMP WHERE id = OLD.id; END IF;
IF NOT(OLD.email <=> NEW.email) THEN UPDATE second_table SET email = CURRENT_TIMESTAMP WHERE id = OLD.id; END IF;
IF NOT(OLD.address <=> NEW.address) THEN UPDATE second_table SET address = CURRENT_TIMESTAMP WHERE id = OLD.id; END IF;
IF NOT(OLD.city <=> NEW.city) THEN UPDATE second_table SET city = CURRENT_TIMESTAMP WHERE id = OLD.id; END IF;
IF NOT(OLD.state <=> NEW.state) THEN UPDATE second_table SET state = CURRENT_TIMESTAMP WHERE id = OLD.id; END IF;
IF NOT(OLD.zip <=> NEW.zip) THEN UPDATE second_table SET zip = CURRENT_TIMESTAMP WHERE id = OLD.id; END IF;
IF NOT(OLD.phone <=> NEW.phone) THEN UPDATE second_table SET phone = CURRENT_TIMESTAMP WHERE id = OLD.id; END IF;
END;
//
DELIMITER;
问题:
如您所见,根据 `first_table` 中更新的列数,`second_table` 的同一行上最多可以有 11 个更新语句。
问题:
有没有办法将更新语句合并为一个?
我在 MySQL 中提出查询时遇到问题。
假设我们有一个记录用户操作的表。
我想知道什么“角色”(即医生、会计师、文员)在日志文件中有条目。
这是架构:
CREATE TABLE `test1_users` (
`id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(45) NOT NULL,
`role` VARCHAR(45) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE = InnoDB;
CREATE TABLE `test1_log` (
`id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` INTEGER UNSIGNED NOT NULL,
PRIMARY KEY (`id`)
) ENGINE = InnoDB;
和测试数据:
INSERT INTO `test1_users` VALUES
(1, 'Franklin', 'Doctor'),
(2, 'Sally', 'Doctor'),
(3, 'Linus', 'Accountant'),
(4, 'Patty', 'Clerk'),
(5, 'Marcie', 'Accountant');
INSERT INTO `test1_log` VALUES
(1, 1),
(2, 1),
(3, 2),
(4, 1),
(5, 3),
(6, 3);
如果我想查看某个用户登录了多少次,这非常简单。
SELECT u.name, COUNT(*) AS total
FROM test1_log l
LEFT JOIN test1_users u ON u.id = l.user_id
GROUP BY user_id;
查询产生以下内容:
+----------+-------+
| name | total |
+----------+-------+
| Franklin | 3 |
| Sally | 1 |
| Linus | 2 |
+----------+-------+
但是,如果我想查看记录了多少不同的“角色”,我将如何构建查询?不是每个角色被记录了多少次,只是记录了所有角色的列表。
具体来说,记录了多少个不同的医生?我不在乎每个记录了多少次。
我正在寻找的此类查询会产生以下输出:
+------------+-------+
| role | total |
+------------+-------+
| Doctor | 2 |
| Accountant | 1 |
| Clerk | 0 |
+------------+-------+
两位医生都有记录,但只有一名会计师,没有文员。
这是我最接近的:
SELECT role, COUNT(l.id) AS total FROM test1_users u
LEFT JOIN test1_log l ON u.id = l.user_id
GROUP BY role;
但这只给我日志条目的数量,我需要进入日志的角色数量。
想法?
谢谢。