diff --git a/sql_refacor0120/auto_add_mysql_partition.sh b/sql_refacor0120/auto_add_mysql_partition.sh new file mode 100644 index 0000000..08aba70 --- /dev/null +++ b/sql_refacor0120/auto_add_mysql_partition.sh @@ -0,0 +1,59 @@ +#!/bin/bash +# ============================================================================== +# MySQL 分区表自动扩展脚本(按月分区) +# 适用表:t_stock_daily_trade(已按 trade_date 按月分区) +# 执行时机:每月最后一天凌晨2点(确保下一个月分区已创建) +# ============================================================================== + +# -------------------------- 配置区(用户需根据实际情况修改) -------------------------- +DB_HOST="localhost" +DB_PORT="3306" +DB_USER="root" +DB_PASS="your_password" +DB_NAME="a_stock_db" +TARGET_TABLE="t_stock_daily_trade" # 目标分区表 +# ---------------------------------------------------------------------------------- + +# 日志函数 +log() { + echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" >> /var/log/auto_add_mysql_partition.log +} + +# 1. 计算下一个月的关键日期(如当前12月,下一个月是次年1月) +# 下一个月的1号(用于分区边界:VALUES LESS THAN (TO_DAYS('下下月1号'))) +next_month_first_day=$(date -d "$(date +%Y-%m-01) +1 month" +%Y-%m-01) +# 下下月的1号(分区边界:小于下下月1号,即包含整个下一个月) +next_next_month_first_day=$(date -d "$next_month_first_day +1 month" +%Y-%m-01) +# 分区名(格式:p202501) +partition_name="p$(date -d "$next_month_first_day" +%Y%m)" + +log "INFO: 开始检查MySQL分区!下一个月:$next_month_first_day,分区名:$partition_name,边界:$next_next_month_first_day" + +# 2. 检查分区是否已存在 +check_sql="SELECT COUNT(*) FROM INFORMATION_SCHEMA.PARTITIONS + WHERE TABLE_SCHEMA = '$DB_NAME' + AND TABLE_NAME = '$TARGET_TABLE' + AND PARTITION_NAME = '$partition_name';" + +# 执行查询并获取结果(过滤掉表头和空行) +partition_count=$(mysql -h$DB_HOST -P$DB_PORT -u$DB_USER -p$DB_PASS -D$DB_NAME -N -s -e "$check_sql") + +if [ "$partition_count" -eq 1 ]; then + log "INFO: 分区已存在!无需创建,分区名:$partition_name" + exit 0 +fi + +# 3. 创建新分区 +add_partition_sql="ALTER TABLE $TARGET_TABLE + ADD PARTITION ( + PARTITION $partition_name + VALUES LESS THAN (TO_DAYS('$next_next_month_first_day')) + COMMENT '$(date -d "$next_month_first_day" +%Y年%m月)数据' + );" + +if mysql -h$DB_HOST -P$DB_PORT -u$DB_USER -p$DB_PASS -D$DB_NAME -e "$add_partition_sql"; then + log "SUCCESS: 分区创建完成!分区名:$partition_name,边界:$next_next_month_first_day" +else + log "ERROR: 分区创建失败!SQL:$add_partition_sql" + exit 1 +fi \ No newline at end of file diff --git a/sql_refacor0120/t_industry_index.sql b/sql_refacor0120/t_industry_index.sql new file mode 100644 index 0000000..b23023c --- /dev/null +++ b/sql_refacor0120/t_industry_index.sql @@ -0,0 +1,22 @@ +-- 行业指数表:存储东财二级行业指数基础信息及每日成交数据 +CREATE TABLE `t_industry_index` ( + `industry_index_code` VARCHAR(20) NOT NULL COMMENT '行业指数代码(如802089.EI)', + `industry_index_name` VARCHAR(50) NOT NULL COMMENT '行业指数名称(如“银行”)', + `component_count` INT NULL COMMENT '成份个数(行业包含个股数量)', + `trade_date` DATE NOT NULL COMMENT '交易日期', + `open_price` DECIMAL(10,2) NULL COMMENT '开盘价(指数点位)', + `close_price` DECIMAL(10,2) NOT NULL COMMENT '收盘价(指数点位)', + `volume` BIGINT NULL COMMENT '成交量(指数成交总量)', + `turnover` DECIMAL(20,2) NULL COMMENT '成交额(单位:万元)', + `total_market_cap` DECIMAL(20,2) NULL COMMENT '总市值(单位:万元)', + `free_circulation_cap` DECIMAL(20,2) NULL COMMENT '自由流通市值(单位:万元)', + `price_change_rate` DECIMAL(6,4) NULL COMMENT '涨跌幅(百分比,如1.2937=1.2937%)', + `pe_ttm` DECIMAL(10,2) NULL COMMENT '市盈率PE(TTM)', + `pe_ttm_median` DECIMAL(10,2) NULL COMMENT '市盈率PE(TTM)中位值', + `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '数据创建时间(自动填充)', + `update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '数据更新时间(自动更新)', + -- 复合主键:确保“指数代码+日期”唯一 + PRIMARY KEY (`industry_index_code`, `trade_date`), + -- 索引:优化按日期查询所有行业指数的场景 + INDEX `idx_t_industry_index_trade_date` (`trade_date`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='东财二级行业指数每日数据'; \ No newline at end of file diff --git a/sql_refacor0120/t_stock_basic.sql b/sql_refacor0120/t_stock_basic.sql new file mode 100644 index 0000000..cfe503a --- /dev/null +++ b/sql_refacor0120/t_stock_basic.sql @@ -0,0 +1,21 @@ +-- 个股基础信息表:存储个股静态信息(低频变更) +CREATE TABLE `t_stock_basic` ( + `stock_code` VARCHAR(20) NOT NULL COMMENT '证券代码(如000061.SZ、600000.SH)', + `stock_name` VARCHAR(50) NOT NULL COMMENT '证券名称(如“农 产 品”)', + `listing_date` DATE NULL COMMENT '首发上市日期', + `listing_days` INT NULL COMMENT '上市天数(冗余存储,提升查询效率)', + `is_st` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否为ST股票(1=是,0=否)', + `is_star_st` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否为*ST股票(1=是,0=否)', + `industry_index_code` VARCHAR(20) NOT NULL COMMENT '所属行业指数代码(关联t_industry_index)', + `industry_index_name` VARCHAR(50) NOT NULL COMMENT '所属行业指数名称(冗余存储,减少关联查询)', + `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '数据创建时间', + `update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '数据更新时间', + -- 主键:证券代码唯一 + PRIMARY KEY (`stock_code`), + -- 外键:关联行业指数表,确保行业代码有效性(禁止删除/修改主表已关联的行业代码) + FOREIGN KEY (`industry_index_code`) + REFERENCES `t_industry_index` (`industry_index_code`) + ON UPDATE RESTRICT ON DELETE RESTRICT, + -- 索引:优化按行业筛选个股的场景 + INDEX `idx_t_stock_basic_industry` (`industry_index_code`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='A股个股基础信息'; \ No newline at end of file diff --git a/sql_refacor0120/t_stock_daily_trade.sql b/sql_refacor0120/t_stock_daily_trade.sql new file mode 100644 index 0000000..bc44410 --- /dev/null +++ b/sql_refacor0120/t_stock_daily_trade.sql @@ -0,0 +1,34 @@ +-- 个股每日交易数据表:大表,按“交易日期”按月分区(MySQL原生分区) +CREATE TABLE `t_stock_daily_trade` ( + `stock_code` VARCHAR(20) NOT NULL COMMENT '证券代码(关联t_stock_basic)', + `trade_date` DATE NOT NULL COMMENT '交易日期', + `open_price` DECIMAL(10,2) NULL COMMENT '开盘价(单位:元)', + `close_price` DECIMAL(10,2) NOT NULL COMMENT '收盘价(单位:元)', + `high_price` DECIMAL(10,2) NULL COMMENT '最高价(单位:元)', + `low_price` DECIMAL(10,2) NULL COMMENT '最低价(单位:元)', + `price_change_rate` DECIMAL(6,4) NULL COMMENT '当日涨跌幅(百分比)', + `volume` BIGINT NULL COMMENT '成交量(单位:股)', + `turnover` DECIMAL(20,2) NULL COMMENT '成交额(单位:万元)', + `free_circulation_cap` DECIMAL(20,2) NULL COMMENT '自由流通市值(单位:万元)', + `is_limit_up` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否涨停(1=是,0=否)', + `is_limit_down` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否跌停(1=是,0=否)', + `momentum_10d` DECIMAL(6,4) NULL COMMENT '10日动量(涨跌幅)', + `momentum_20d` DECIMAL(6,4) NULL COMMENT '20日动量(涨跌幅)', + `momentum_60d` DECIMAL(6,4) NULL COMMENT '60日动量(涨跌幅)', + `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '数据创建时间', + -- 复合主键:确保“个股代码+日期”唯一 + PRIMARY KEY (`stock_code`, `trade_date`), + -- 外键:关联个股基础表,确保个股代码有效性 + FOREIGN KEY (`stock_code`) + REFERENCES `t_stock_basic` (`stock_code`) + ON UPDATE RESTRICT ON DELETE RESTRICT, + -- 索引:优化按日期查询所有个股交易数据的场景 + INDEX `idx_t_stock_daily_trade_date` (`trade_date`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 +-- 按“交易日期”按月分区(示例:2024年12月-2025年3月,后续可扩展) +PARTITION BY RANGE (TO_DAYS(`trade_date`)) ( + PARTITION `p202412` VALUES LESS THAN (TO_DAYS('2025-01-01')) COMMENT '2024年12月数据', + PARTITION `p202501` VALUES LESS THAN (TO_DAYS('2025-02-01')) COMMENT '2025年1月数据', + PARTITION `p202502` VALUES LESS THAN (TO_DAYS('2025-03-01')) COMMENT '2025年2月数据', + PARTITION `p202503` VALUES LESS THAN (TO_DAYS('2025-04-01')) COMMENT '2025年3月数据' +) COMMENT='A股个股每日交易数据(按月分区)'; \ No newline at end of file diff --git a/sql_refacor0120/t_stock_high_low_status.sql b/sql_refacor0120/t_stock_high_low_status.sql new file mode 100644 index 0000000..dda7f5c --- /dev/null +++ b/sql_refacor0120/t_stock_high_low_status.sql @@ -0,0 +1,23 @@ +-- 个股新高新低状态表:存储300天新高新低信息 +CREATE TABLE `t_stock_high_low_status` ( + `stock_code` VARCHAR(20) NOT NULL COMMENT '证券代码(关联t_stock_basic)', + `trade_date` DATE NOT NULL COMMENT '交易日期', + `is_new_high` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否创阶段新高(1=是,0=否)', + `new_high_date` DATE NULL COMMENT '区间最高价日(创新高时填充)', + `is_new_low` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否创阶段新低(1=是,0=否)', + `new_low_date` DATE NULL COMMENT '区间最低价日(创新低时填充)', + `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '数据创建时间', + -- 复合主键:确保“个股代码+日期”唯一 + PRIMARY KEY (`stock_code`, `trade_date`), + -- 外键1:关联个股基础表 + FOREIGN KEY (`stock_code`) + REFERENCES `t_stock_basic` (`stock_code`) + ON UPDATE RESTRICT ON DELETE RESTRICT, + -- 外键2:关联个股交易表,确保“个股+日期”的交易数据存在 + FOREIGN KEY (`stock_code`, `trade_date`) + REFERENCES `t_stock_daily_trade` (`stock_code`, `trade_date`) + ON UPDATE RESTRICT ON DELETE RESTRICT, + -- 索引:优化“查询某日所有新高/新低个股”的场景 + INDEX `idx_t_stock_high_low_high` (`is_new_high`, `trade_date`), + INDEX `idx_t_stock_high_low_low` (`is_new_low`, `trade_date`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='A股个股300天新高新低状态'; \ No newline at end of file diff --git a/sql_refacor0120/东财二级行业指数每日成交情况_20241202.xlsx b/sql_refacor0120/东财二级行业指数每日成交情况_20241202.xlsx new file mode 100644 index 0000000..db16fc2 Binary files /dev/null and b/sql_refacor0120/东财二级行业指数每日成交情况_20241202.xlsx differ diff --git a/sql_refacor0120/创300天新高新低_20241202.xlsx b/sql_refacor0120/创300天新高新低_20241202.xlsx new file mode 100644 index 0000000..a475ff5 Binary files /dev/null and b/sql_refacor0120/创300天新高新低_20241202.xlsx differ diff --git a/sql_refacor0120/动量原始股(全部A股)_20241202.xlsx b/sql_refacor0120/动量原始股(全部A股)_20241202.xlsx new file mode 100644 index 0000000..650f2eb Binary files /dev/null and b/sql_refacor0120/动量原始股(全部A股)_20241202.xlsx differ diff --git a/sql_refacor0120/执行顺序及分表.ini b/sql_refacor0120/执行顺序及分表.ini new file mode 100644 index 0000000..246ed64 --- /dev/null +++ b/sql_refacor0120/执行顺序及分表.ini @@ -0,0 +1,13 @@ +执行顺序:需按以下顺序执行建表语句,避免外键依赖报错: +t_industry_index → t_stock_basic → t_stock_daily_trade(及子表)→ t_stock_high_low_status + +分表扩展: +MySQL:新增月份分区时,执行 ALTER TABLE t_stock_daily_trade ADD PARTITION (...),示例: + + +ALTER TABLE t_stock_daily_trade ADD PARTITION ( + PARTITION `p202504` VALUES LESS THAN (TO_DAYS('2025-05-01')) COMMENT '2025年4月数据' +); + + +----------- diff --git a/sql_refacor0120/数据导入定时任务.ini b/sql_refacor0120/数据导入定时任务.ini new file mode 100644 index 0000000..57375c5 --- /dev/null +++ b/sql_refacor0120/数据导入定时任务.ini @@ -0,0 +1,13 @@ +# -------------------------- 数据导入定时任务(每日执行) -------------------------- +# MySQL:每日凌晨3点导入前一天的交易数据(假设CSV文件每日凌晨2点生成) +0 3 * * * /opt/stock_scripts/load_data_mysql.sh >> /var/log/stock_data_import.log 2>&1 + +# PostgreSQL:每日凌晨3点10分导入(错开MySQL执行时间,避免数据库压力) +10 3 * * * /opt/stock_scripts/copy_data_pg.sh >> /var/log/stock_data_import_pg.log 2>&1 + +# -------------------------- 分表扩展定时任务(每月执行) -------------------------- +# MySQL:每月最后一天凌晨2点创建下一个月分区 +0 2 L * * /opt/stock_scripts/auto_add_mysql_partition.sh >> /var/log/auto_add_mysql_partition.log 2>&1 + +# PostgreSQL:每月最后一天凌晨2点10分创建下一个月子表 +10 2 L * * /opt/stock_scripts/auto_add_pg_subtable.sh >> /var/log/auto_add_pg_subtable.log 2>&1 \ No newline at end of file