问题
I’m using a host which only supports MyISAM tables engines for MySQL. I’m trying to create a CMS using php and MySQL, however, I’m having issues working out how to create relationships between the tables. For example, one of the features within this system is being able to assign tags to an article/blogpost, similar to how stack overflow has tags on their questions.
My question is, as I cannot change my tables to use InnoDB, how can I form a relationship between the two tables? I am unable to use foreign keys as they are not supported in MyISAM, or at least not enforced.
So far, all I've found when searching is keeping track of it through PHP by ensuring that I update multiple tables at a time, but there must be a way of doing this on the MySQL side.
Below are examples of the Article and Tag tables.
+---------------------------+ +---------------------------+
| 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 |
+---------------------------+
I’ve found loads of related questions on this site, but most of them InnoDB, which I cannot do as my host does not support it.
I've found a solution (kind of). I've added another table called ArticleTags
+---------------------------+
| ArticleTags |
+---------------------------+
| articleID int(11) |
| tagID int(11) |
+---------------------------+
This query returns the correct result, but I'm not sure if it's a bit of a hack, or if there is a better way to do it.
SELECT `tagString`
FROM `Tags`
WHERE id
IN (
SELECT `tagID`
FROM `ArticleTags`
WHERE `articleID` = :id
)
ORDER BY `Tags`.`tagString`
Can someone tell me if this this right?
回答1:
Try TRIGGERs:
- Enforcing Foreign Keys Programmatically in MySQL
- Emulating Cascading Operations From InnoDB to MyISAM Tables
Example MyIsam with Foreign-Key:
Create parent table:
CREATE TABLE myisam_parent
(
mparent_id INT NOT NULL,
PRIMARY KEY (mparent_id)
) ENGINE=MYISAM;
Create child table:
CREATE TABLE myisam_child
(
mparent_id INT NOT NULL,
mchild_id INT NOT NULL,
PRIMARY KEY (mparent_id, mchild_id)
) ENGINE = MYISAM;
Create trigger (with 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 ;
Test case:
Try insert (create 3 lines in myisam_parent and 6 lines in myisam_child):
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);
Try insert:
INSERT INTO myisam_child VALUES (7, 1);
Returns this error:
ERROR 1062 (23000): Duplicate entry 'Foreign Key Constraint Violated!' for key 'PRIMARY'
Note:
This example is for INSERT, for "triggers" with DELETE and UPDATE read link (at the beginning the question)
来源:https://stackoverflow.com/questions/23985617/myisam-engine-table-relations-mysql