Yii2-数据库分表, id 统一生成方法


数据库做分表之后,没法使用简单的 auto_increment  id 来做 primary key,为了维持 id 在多个物理分表上的全局唯一,我们需要一种替代 auto_increment 方式的统一  id 生成方法。 所有的 id 都统一从这里生成,确保不同分表的 id 是全局唯一的。只要保证了不同物理分表的 id 是全局唯一的,我们就能很容易的在不同分表之间迁移数据,而不同担心 id 冲突。

这里我们采用 存储过程来为所有的表统一生成  id ,结构如下:


$sequence_table_fields = array(
    	'generator'   => 'VARCHAR(32) NOT NULL PRIMARY KEY', # id 生成器名称
    	'id' => 'BIGINT(32) UNSIGNED NOT NULL DEFAULT 0', # 生成器对应的 id
);

$this->createTable('{{sequence}}', $sequence_table_fields, 'ENGINE=InnoDB DEFAULT CHARSET=utf8');

// 为 article_title表 生成 id
$this->insert('{{sequence}}', array('generator' => 'article_title', 'id' => 0));

// 为 article_content表 生成 id
$this->insert('{{sequence}}', array('generator' => 'article_content', 'id' => 0));

// 存储过程,用于生成 id
$this->execute("
    CREATE PROCEDURE `p_sequence_id_gen`(generatorName varchar(32))
	BEGIN
	START TRANSACTION;
	UPDATE `sequence` SET `id` = LAST_INSERT_ID(`id` + 1) WHERE `generator` = generatorName;
	SELECT LAST_INSERT_ID();
	COMMIT;
    END
");

存储过程的调用,直接用于生成表id

class StoreProcedureHelper {

	private static function call_p_sequence_id_gen($generatorName){
		$command = Yii::app()->db->createCommand('call p_sequence_id_gen("'.$generatorName.'")');
		return $command->queryScalar();
	}

	public static function generateArtitleTitleId(){
		return self::call_p_sequence_id_gen('article_title');
	}

	public static function generateArtitleContentId(){
		return self::call_p_sequence_id_gen('article_content');
	}

}




你可能感兴趣的:(Yii2)