Index: t3lib/config_default.php
===================================================================
--- t3lib/config_default.php	(Revision 5911)
+++ t3lib/config_default.php	(Arbeitskopie)
@@ -123,19 +123,22 @@
 				'cache_hash' => array(
 					'backend' => 't3lib_cache_backend_DbBackend',
 					'options' => array(
-						'cacheTable' => 'cache_hash'
+						'cacheTable' => 'cache_hash',
+						'tagsTable' => 'cache_hash_tags',
 					)
 				),
 				'cache_pages' => array(
 					'backend' => 't3lib_cache_backend_DbBackend',
 					'options' => array(
-						'cacheTable' => 'cache_pages'
+						'cacheTable' => 'cache_pages',
+						'tagsTable' => 'cache_pages_tags',
 					)
 				),
 				'cache_pagesection' => array(
 					'backend' => 't3lib_cache_backend_DbBackend',
 					'options' => array(
-						'cacheTable' => 'cache_pagesection'
+						'cacheTable' => 'cache_pagesection',
+						'tagsTable' => 'cache_pagesection_tags',
 					)
 				)
 				/*
Index: t3lib/stddb/tables.sql
===================================================================
--- t3lib/stddb/tables.sql	(Revision 5911)
+++ t3lib/stddb/tables.sql	(Arbeitskopie)
@@ -124,16 +124,27 @@
 #
 CREATE TABLE cache_hash (
   id int(11) unsigned NOT NULL auto_increment,
-  identifier varchar(250) DEFAULT '' NOT NULL,
+  identifier varchar(128) DEFAULT '' NOT NULL,
   crdate int(11) unsigned DEFAULT '0' NOT NULL,
   content mediumtext,
-  tags mediumtext,
   lifetime int(11) unsigned DEFAULT '0' NOT NULL,
   PRIMARY KEY (id),
   KEY cache_id (identifier)
 ) ENGINE=InnoDB;
 
 #
+# Table structure for table 'cache_hash_tags'
+#
+CREATE TABLE cache_hash_tags (
+  id int(11) unsigned NOT NULL auto_increment,
+  identifier varchar(128) DEFAULT '' NOT NULL,
+  tag varchar(128) DEFAULT '' NOT NULL,
+  PRIMARY KEY (id),
+  KEY cache_id (identifier),
+  KEY cache_tag (tag)
+) ENGINE=InnoDB;
+
+#
 # Table structure for table 'cache_imagesizes'
 #
 CREATE TABLE cache_imagesizes (
Index: t3lib/cache/backend/class.t3lib_cache_backend_dbbackend.php
===================================================================
--- t3lib/cache/backend/class.t3lib_cache_backend_dbbackend.php	(Revision 5911)
+++ t3lib/cache/backend/class.t3lib_cache_backend_dbbackend.php	(Arbeitskopie)
@@ -33,6 +33,7 @@
 class t3lib_cache_backend_DbBackend extends t3lib_cache_backend_AbstractBackend {
 
 	protected $cacheTable;
+	protected $tagsTable;
 
 	/**
 	 * Saves data in a cache file.
@@ -73,10 +74,19 @@
 				'identifier' => $entryIdentifier,
 				'crdate'     => $GLOBALS['EXEC_TIME'],
 				'content'    => $data,
-				'tags'       => implode(',', $tags),
 				'lifetime'   => $lifetime
 			)
 		);
+
+		foreach ($tags as $tag) {
+			$GLOBALS['TYPO3_DB']->exec_INSERTquery(
+				$this->tagsTable,
+				array(
+					'identifier' => $entryIdentifier,
+					'tag'        => $tag,
+				)
+			);
+		}
 	}
 
 	/**
@@ -138,6 +148,11 @@
 	public function remove($entryIdentifier) {
 		$entryRemoved = false;
 
+		$GLOBALS['TYPO3_DB']->exec_DELETEquery(
+			$this->tagsTable,
+			'identifier = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr($entryIdentifier, $this->tagsTable)
+		);
+
 		$res = $GLOBALS['TYPO3_DB']->exec_DELETEquery(
 			$this->cacheTable,
 			'identifier = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr($entryIdentifier, $this->cacheTable)
@@ -161,9 +176,12 @@
 		$cacheEntryIdentifiers = array();
 
 		$cacheEntryIdentifierRows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
-			'identifier',
-			$this->cacheTable,
-			$this->getListQueryForTag($tag) . ' AND (crdate + lifetime >= ' . $GLOBALS['EXEC_TIME'] . ' OR lifetime = 0)'
+			$this->cacheTable . '.identifier',
+			$this->cacheTable . ', ' . $this->tagsTable,
+			$this->getQueryForTag() .
+				' AND ' . $this->cacheTable . '.identifier = ' . $this->tagsTable . '.identifier' .
+				' AND (crdate + lifetime >= ' . $GLOBALS['EXEC_TIME'] . ' OR lifetime = 0)',
+			$this->cacheTable . '.identifier'
 		);
 
 		foreach ($cacheEntryIdentifierRows as $cacheEntryIdentifierRow) {
@@ -186,14 +204,17 @@
 		$whereClause  = array();
 
 		foreach ($tags as $tag) {
-			$whereClause[] = $this->getListQueryForTag($tag);
+			$whereClause[] = $this->getQueryForTag($tag);
 		}
+
+		$whereClause[] = $this->cacheTable . '.identifier = ' . $this->tagsTable . '.identifier';
 		$whereClause[] = '(crdate + lifetime >= ' . $GLOBALS['EXEC_TIME'] . ' OR lifetime = 0)';
 
 		$cacheEntryIdentifierRows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
-			'identifier',
-			$this->cacheTable,
-			implode(' AND ', $whereClause)
+			$this->cacheTable . 'identifier',
+			$this->cacheTable . ', ' . $this->tagsTable,
+			implode(' AND ', $whereClause),
+			$this->cacheTable . '.identifier'
 		);
 
 		foreach ($cacheEntryIdentifierRows as $cacheEntryIdentifierRow) {
@@ -211,6 +232,7 @@
 	 */
 	public function flush() {
 		$GLOBALS['TYPO3_DB']->sql_query('TRUNCATE ' . $this->cacheTable);
+		$GLOBALS['TYPO3_DB']->sql_query('TRUNCATE ' . $this->tagsTable);
 	}
 
 	/**
@@ -220,10 +242,10 @@
 	 * @return void
 	 */
 	public function flushByTag($tag) {
-		$GLOBALS['TYPO3_DB']->exec_DELETEquery(
-			$this->cacheTable,
-			$this->getListQueryForTag($tag)
-		);
+		// @todo: DELETE FROM cacheTable, tagsTable USING cacheTable INNER JOIN tagsTable... would be nice - but TYPO3_DB does not support it
+		foreach ($this->findIdentifiersByTag($tag) as $entryIdentifier) {
+			$this->remove($entryIdentifier);
+		}
 	}
 
 	/**
@@ -233,16 +255,10 @@
 	 * @return void
 	 */
 	public function flushByTags(array $tags) {
-		$listQueryConditions = array();
-		foreach ($tags as $tag) {
-			$listQueryConditions[$tag] = $this->getListQueryForTag($tag);
+		// @todo: DELETE FROM cacheTable, tagsTable USING cacheTable INNER JOIN tagsTable... would be nice - but TYPO3_DB does not support it
+		foreach ($this->findIdentifiersByTags($tags) as $entryIdentifier) {
+			$this->remove($entryIdentifier);
 		}
-
-		$listQuery = implode(' OR ', $listQueryConditions);
-		$GLOBALS['TYPO3_DB']->exec_DELETEquery(
-			$this->cacheTable,
-			$listQuery
-		);
 	}
 
 	/**
@@ -252,10 +268,16 @@
 	 * @author Ingo Renner <ingo@typo3.org>
 	 */
 	public function collectGarbage() {
-		$GLOBALS['TYPO3_DB']->exec_DELETEquery(
-			$this->cacheTable,
+		// @todo: DELETE FROM cacheTable, tagsTable USING cacheTable INNER JOIN tagsTable... would be nice - but TYPO3_DB does not support it
+		// Alternative here: Add lifetime to tagsTable as well...
+		$cacheEntryIdentifierRows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
+			'identifier',
 			'crdate + lifetime < ' . $GLOBALS['EXEC_TIME'] . ' AND lifetime > 0'
 		);
+
+		foreach ($cacheEntryIdentifierRows as $cacheEntryIdentifierRow) {
+			$this->remove($cacheEntryIdentifierRow['identifier']);
+		}
 	}
 
 	/**
@@ -313,6 +335,25 @@
 	}
 
 	/**
+	 * Sets the table where cache tags are stored.
+	 *
+	 * @param	string		$tagsTabls: Name of the table
+	 * @return	void
+	 */
+	public function setTagsTable($tagsTable) {
+		$this->tagsTable = $tagsTable;
+	}
+
+	/**
+	 * Gets the table where cache tags are store.
+	 *
+	 * @return	string		Name of the table storing tags
+	 */
+	public function getTagsTable() {
+		return $this->tagsTable;
+	}
+
+	/**
 	 * Gets the query to be used for selecting entries by a tag. The asterisk ("*")
 	 * is allowed as a wildcard at the beginning and the end of a tag.
 	 *
@@ -320,8 +361,18 @@
 	 * @return string the query to be used for selecting entries
 	 * @author Oliver Hader <oliver@typo3.org>
 	 */
-	protected function getListQueryForTag($tag) {
-		return str_replace('*', '%', $GLOBALS['TYPO3_DB']->listQuery('tags', $tag, $this->cacheTable));
+	protected function getQueryForTag($tag) {
+		if (strpos($tag, '*') === false) {
+			$query = $this->tagsTable . 'tag = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr($tag, $this->tagsTable);
+		} else {
+			$patternForLike = $GLOBALS['TYPO3_DB']->escapeStrForLike(
+				$GLOBALS['TYPO3_DB']->quoteStr($tag, $this->tagsTable),
+				$this->tagsTable
+			);
+			$query = $this->tagsTable . 'tag LIKE \'' . $patternForLike . '\'';
+		}
+
+		return $query;
 	}
 }
 
Index: typo3/sysext/cms/ext_tables.sql
===================================================================
--- typo3/sysext/cms/ext_tables.sql	(Revision 5911)
+++ typo3/sysext/cms/ext_tables.sql	(Arbeitskopie)
@@ -8,10 +8,9 @@
 #
 CREATE TABLE cache_pages (
   id int(11) unsigned NOT NULL auto_increment,
-  identifier varchar(250) DEFAULT '' NOT NULL,
+  identifier varchar(128) DEFAULT '' NOT NULL,
   crdate int(11) unsigned DEFAULT '0' NOT NULL,
   content mediumtext,
-  tags mediumtext,
   lifetime int(11) unsigned DEFAULT '0' NOT NULL,
   PRIMARY KEY (id),
   KEY cache_id (identifier)
@@ -19,14 +18,26 @@
 
 
 #
+# Table structure for table 'cache_pages_tags'
+#
+CREATE TABLE cache_pages_tags (
+  id int(11) unsigned NOT NULL auto_increment,
+  identifier varchar(128) DEFAULT '' NOT NULL,
+  tag varchar(128) DEFAULT '' NOT NULL,
+  PRIMARY KEY (id),
+  KEY cache_id (identifier),
+  KEY cache_tag (tag)
+) ENGINE=InnoDB;
+
+
+#
 # Table structure for table 'cache_pagesection'
 #
 CREATE TABLE cache_pagesection (
   id int(11) unsigned NOT NULL auto_increment,
-  identifier varchar(250) DEFAULT '' NOT NULL,
+  identifier varchar(128) DEFAULT '' NOT NULL,
   crdate int(11) unsigned DEFAULT '0' NOT NULL,
   content mediumtext,
-  tags mediumtext,
   lifetime int(11) unsigned DEFAULT '0' NOT NULL,
   PRIMARY KEY (id),
   KEY cache_id (identifier)
@@ -34,6 +45,19 @@
 
 
 #
+# Table structure for table 'cache_pagesection_tags'
+#
+CREATE TABLE cache_pagesection_tags (
+  id int(11) unsigned NOT NULL auto_increment,
+  identifier varchar(128) DEFAULT '' NOT NULL,
+  tag varchar(128) DEFAULT '' NOT NULL,
+  PRIMARY KEY (id),
+  KEY cache_id (identifier),
+  KEY cache_tag (tag)
+) ENGINE=InnoDB;
+
+
+#
 # Table structure for table 'cache_typo3temp_log'
 #
 CREATE TABLE cache_typo3temp_log (
