A Q & A website that allow user to ask question and put several tags to that question.
Database tables:
tag
1 2 3 4 5 6 7
+--------------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+-------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | title | varchar(30) | NO || NULL || | description | varchar(100)| NO || NULL || +--------------+-------------+------+-----+---------+----------------+
tag_rel
1 2 3 4 5 6 7
+--------------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+-------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | tag_id | varchar(30) | NO || NULL || | question_id | varchar(100)| NO || NULL || +--------------+-------------+------+-----+---------+----------------+
question
1 2 3 4 5 6
+--------------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+-------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | description | varchar(100)| NO || NULL || +--------------+-------------+------+-----+---------+----------------+
Now want to get those tags related to a tag with ID 100, the query could be
1 2 3 4 5 6 7 8 9 10 11
SELECT tag.* FROM tag INNERJOIN tag_rel ON tag.id = tag_rel.tag_id WHERE tag.id <>100 AND tag_rel.question_id IN ( SELECT tag_rel.question_id FROM tag INNERJOIN tag_rel ON tag.id = tag_rel.tag_id WHERE tag.id =100 )
Now want to construct this query in Zend Frameword 2
In your model table, says ./module/Application/src/Application/Model/TagTable.php
$select ->join( 'tag_rel', 'tag.id = tag_rel.tag_id', array( ) ) ->where(array('tag.id <> ?' => $id)) ->where->in('tag_rel.question_id', $subselect) ; // uncomment the next line to see your query // echo $select->getSqlString(); });
// don't use DISTINCT in sql due to performance issue // Get unique records $distincted_result = array(); foreach ($result_setas$rowset) { if (!in_array($rowset, $distincted_result)) { $distincted_result[] = $rowset; } } return$distincted_result; } ... }
The performance may be sux, in order to solve this, just index tag_rel.tag_id and tag_rel.question_id.
1 2
mysql >ALTERTABLE `tag_rel` ADD INDEX (`tag_id`); mysql >ALTERTABLE `tag_rel` ADD INDEX (`question_id`);