mysql创建多张表结构一样的表(分表时用)

本文介绍如何使用存储过程创建多张表,并通过SQL语句批量创建表格,包括创建16张表的具体实现及注意事项,特别强调了第二种方式便于数据迁移和扩容的优势。
[size=medium][b][color=darkred]一、存储过程创建多张表[/color][/b][/size]

[color=darkblue][b]1.利用存储过程,动态创建多张表:
创建16张表,从score_stream_00到score_stream_15[/b][/color]
DELIMITER $$

CREATE
PROCEDURE `score`.`p`()
BEGIN

DECLARE i INT;
DECLARE table_name VARCHAR(20);
DECLARE table_pre VARCHAR(20);
DECLARE sql_text VARCHAR(2000);
SET i=1;
SET table_name='';
SET table_pre='score_stream_';
SET sql_text='';
WHILE i<16 DO
IF i<10 THEN SET table_name=CONCAT(table_pre,'0',i);
ELSE SET table_name=CONCAT(table_pre,i);
END IF;

SET sql_text=CONCAT('CREATE TABLE ', table_name, '(
id VARCHAR(32) NOT NULL COMMENT \'主键\',
user_id VARCHAR(32) NOT NULL COMMENT \'用户ID\',
direction VARCHAR(8) NOT NULL COMMENT \'收支方向 收入-IN 支出-OUT\',
operate_score INT(11) NOT NULL COMMENT \'操作的积分数\',
operator VARCHAR(32) NOT NULL COMMENT \'操作人:如果是系统,则为system\',
operate_time DATETIME NOT NULL COMMENT \'操作时间,首次生成积分流水的操作时间,用来排序显示\',
score_status INT(4) NOT NULL',
score_rule_id VARCHAR(32) DEFAULT NULL COMMENT \'积分规则ID\',
member_level INT(4) DEFAULT NULL COMMENT \'会员等级1:普通会员,2:VIP会员\',
score_type INT(4) NOT NULL COMMENT \'获取积分的类型,和score_task表中的score_type一个含义\',
product_id VARCHAR(32) DEFAULT NULL COMMENT \'产品ID\',
remark VARCHAR(256) DEFAULT NULL COMMENT \'积分流水的备注(用来给内部人看的)\',
operate_source INT(4) DEFAULT NULL COMMENT \'操作来源:1:系统操作触发,2:人工操作触发\',
gmt_modify DATETIME NOT NULL COMMENT \'表改修时间\',
gmt_create DATETIME NOT NULL COMMENT \'表创建时间\',
PRIMARY KEY (id),
KEY idx_user_id (user_id),
KEY idx_direction (direction),
KEY idx_operate_time (operate_time),
KEY idx_score_status (score_status)
) ENGINE=INNODB DEFAULT CHARSET=utf8' );

SELECT sql_text;
SET @sql_text=sql_text;
PREPARE stmt FROM @sql_text;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET i=i+1;
END WHILE;

END$$

DELIMITER ;

[color=darkblue]
[b]2.执行存储过程,创建表[/b][/color]
CALL p();


[b][color=darkblue]二、利用sql语句创建多张表
创建16张表:[/color][/b]
CREATE TABLE `usermng_daily_earning_0000` (
`id` VARCHAR(24) NOT NULL COMMENT '主键 15位时间戳+3位随机数+userId后两位+4位表示所在表',
`user_id` VARCHAR(22) NOT NULL COMMENT '用户ID(根据userId来分表)',
`occur_date` INT(8) NOT NULL COMMENT '收益发生日期',
`ta_id` VARCHAR(22) DEFAULT NULL COMMENT '交易模式',
`product_id` VARCHAR(20) NOT NULL COMMENT '产品ID',
`product_name` VARCHAR(50) NOT NULL COMMENT '产品名称',
`order_id` VARCHAR(20) DEFAULT NULL COMMENT '订单ID',
`assets_id` VARCHAR(22) NOT NULL COMMENT'资产ID',
`earning` DECIMAL(16,2) NOT NULL COMMENT '产生的收益',
`modify_time` DATETIME NOT NULL COMMENT '表修改时间',
`create_time` DATETIME NOT NULL COMMENT '表创建时间',
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`) USING BTREE,
KEY `IDX_occur_date` (`occur_date`) USING BTREE,
KEY `IDX_create_time` (`create_time`) USING BTREE
) ENGINE=INNODB DEFAULT CHARSET=utf8;

CREATE TABLE `usermng_daily_earning_0008` LIKE usermng_daily_earning_0000;
CREATE TABLE `usermng_daily_earning_0016` LIKE usermng_daily_earning_0000;
CREATE TABLE `usermng_daily_earning_0024` LIKE usermng_daily_earning_0000;
CREATE TABLE `usermng_daily_earning_0032` LIKE usermng_daily_earning_0000;
CREATE TABLE `usermng_daily_earning_0040` LIKE usermng_daily_earning_0000;
CREATE TABLE `usermng_daily_earning_0048` LIKE usermng_daily_earning_0000;
CREATE TABLE `usermng_daily_earning_0056` LIKE usermng_daily_earning_0000;
CREATE TABLE `usermng_daily_earning_0064` LIKE usermng_daily_earning_0000;
CREATE TABLE `usermng_daily_earning_0072` LIKE usermng_daily_earning_0000;
CREATE TABLE `usermng_daily_earning_0080` LIKE usermng_daily_earning_0000;
CREATE TABLE `usermng_daily_earning_0088` LIKE usermng_daily_earning_0000;
CREATE TABLE `usermng_daily_earning_0096` LIKE usermng_daily_earning_0000;
CREATE TABLE `usermng_daily_earning_0104` LIKE usermng_daily_earning_0000;
CREATE TABLE `usermng_daily_earning_0112` LIKE usermng_daily_earning_0000;
CREATE TABLE `usermng_daily_earning_0120` LIKE usermng_daily_earning_0000;


[color=red][b]注意:额外说一句,第二种表命名的方式更加便于以后数据迁移和扩容[/b][/color]
### 使用Python批量更新MySQL中大规模数据的性能优化方案 在处理大规模数据,例如100张每张包含3亿条数据,使用Python进行批量更新操作需要特别注意性能优化。以下是几种关键的优化策略和最佳实践: #### 1. 使用批量插入或更新语句 在Python中,可以使用`executemany()`方法来执行批量SQL语句。相比逐条执行SQL语句,这种方法能显著减少数据库连接的开销并提升性能。示例如下: ```python import mysql.connector # 建立数据库连接 conn = mysql.connector.connect(host="localhost", user="root", password="password", database="test_db") cursor = conn.cursor() # 准备批量更新的数据 data_to_update = [(new_value, id) for id, new_value in enumerate(range(1, 1001))] # 执行批量更新 update_query = "UPDATE large_table SET column_name = %s WHERE id = %s" cursor.executemany(update_query, data_to_update) # 提交事务 conn.commit() ``` 这种方法通过减少网络往返次数来提高效率[^4]。 #### 2. 启用事务控制 默认情况下,每次SQL语句执行后都会自动提交事务。对于大规模数据更新,频繁的事务提交会导致性能下降。可以通过显式控制事务来优化性能: ```python try: cursor.execute("START TRANSACTION") # 执行批量更新 cursor.executemany(update_query, data_to_update) cursor.execute("COMMIT") except Exception as e: cursor.execute("ROLLBACK") print(f"Error occurred: {e}") ``` 通过这种方式,所有更新操作可以在一个事务内完成,从而减少日志写入和锁定间[^1]。 #### 3. 利用分区和索引优化 如果的数据量非常大,建议对进行分区,并确保更新字段上有适当的索引。分区能够将数据分布在多个物理存储上,减少单次查询或更新的扫描范围。此外,索引可以加速WHERE条件的匹配过程。 - **分区示例**:可以基于日期、ID范围等字段创建分区[^2]。 - **索引示例**:为频繁用于WHERE条件的字段(如`id`)添加索引。 #### 4. 分批处理数据 一次性加载和更新数十亿条数据可能导致内存溢出或数据库崩溃。分批处理数据是一种常见的解决方案。例如,可以按批次读取和更新数据: ```python batch_size = 10000 for i in range(0, len(data_to_update), batch_size): batch_data = data_to_update[i:i + batch_size] cursor.executemany(update_query, batch_data) conn.commit() ``` 这种方法不仅可以降低内存消耗,还能减少锁间[^3]。 #### 5. 数据库水平扩展与分布式架构 当单机MySQL无法满足需求,可以考虑采用分布式数据库架构。例如,将数据分布到多台服务器上,使用分库分表的方式减轻单个节点的压力。MaxCompute和DataWorks等工具也可以用于大数据场景下的任务调度和管理[^3]。 #### 6. 避免锁和死锁 在大规模更新过程中,长间的锁可能会导致系统性能下降甚至死锁。可以通过以下方式避免: - 使用`LOW_PRIORITY`关键字降低更新优先级。 - 尽量缩短事务持续间。 - 确保更新逻辑不会导致循环依赖。 --- ### 注意事项 - 在执行大规模数据更新前,建议先在测试环境中验证性能和正确性。 - 如果数据量过大且更新频率较高,可以考虑引入消息队列(如Kafka)作为中间层,异步处理更新请求。 - 定期监控数据库性能指标(如CPU、I/O、锁等待间等),及调整优化策略。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值