我正在使用仅支持MySQL的MyISAM表引擎的主机。我正在尝试使用php和MySQL创建CMS,但是,我在解决如何在表之间创建关系时遇到问题。例如,该系统中的一个功能是能够为文章/博客文章分配标签,类似于堆栈溢出在其问题上有标签的方式。
我的问题是,由于我无法更改我的表以使用InnoDB,我如何在两个表之间形成关系?我无法使用外键,因为它们在MyISAM中不受支持,或者至少没有强制执行。
到目前为止,我在搜索时发现的是通过确保一次更新多个表来通过PHP跟踪它,但必须有一种方法在MySQL端执行此操作。
以下是文章和标签表的示例。
+---------------------------+ +---------------------------+ | Article | | Tags | +---------------------------+ +---------------------------+ | articleID int(11) | | tagID int(11) | | title varchar(150) | | tagString varchar(15) | | description varchar(150) | +---------------------------+ | author varchar(30) | | content text | | created datetime | | edited datetime | +---------------------------+
我在这个网站上发现了很多相关问题,但其中大多数都是InnoDB,我作为主持人不能支持它。
我找到了解决方案(种类)。我添加了另一个名为ArticleTags的表
+---------------------------+ | ArticleTags | +---------------------------+ | articleID int(11) | | tagID int(11) | +---------------------------+
此查询返回正确的结果,但我不确定它是否有点黑客,或者是否有更好的方法。
SELECT `tagString` FROM `Tags` WHERE id IN ( SELECT `tagID` FROM `ArticleTags` WHERE `articleID` = :id ) ORDER BY `Tags`.`tagString`
有人可以告诉我这是否正确吗?
答案 0 :(得分:3)
尝试TRIGGERs:
创建父表:
CREATE TABLE myisam_parent
(
mparent_id INT NOT NULL,
PRIMARY KEY (mparent_id)
) ENGINE=MYISAM;
创建子表:
CREATE TABLE myisam_child
(
mparent_id INT NOT NULL,
mchild_id INT NOT NULL,
PRIMARY KEY (mparent_id, mchild_id)
) ENGINE = MYISAM;
创建触发器(使用DELIMITER):
DELIMITER $$
CREATE TRIGGER insert_myisam_child
BEFORE INSERT ON myisam_child
FOR EACH ROW
BEGIN
IF (SELECT COUNT(*) FROM myisam_parent WHERE mparent_id=new.mparent_id)=0 THEN
INSERT error_msg VALUES ('Foreign Key Constraint Violated!');//Custom error
END IF;
END;$$
DELIMITER ;
尝试插入(在myisam_parent
中创建3行,在myisam_child
中创建6行):
INSERT INTO myisam_parent VALUES (1), (2), (3);
INSERT INTO myisam_child VALUES (1,1), (1,2), (2,1), (2,2), (2,3), (3,1);
尝试插入:
INSERT INTO myisam_child VALUES (7, 1);
返回此错误:
ERROR 1062(23000):重复输入'违反外键约束!'关键' PRIMARY'
注意:
此示例适用于INSERT
,适用于"触发器"使用DELETE和UPDATE读取链接(在问题的开头)