Browse Source

4.8学习笔记

milestone-20260401-学习笔记
chenchunxiao 5 days ago
parent
commit
3daecc6b1f
  1. 778
      陈春晓的学习笔记/陈春晓4.8学习笔记.md

778
陈春晓的学习笔记/陈春晓4.8学习笔记.md

@ -0,0 +1,778 @@
# 技术
## MySQL
---
### 一、多表查询
#### 1. 为什么要多表查询?
实际开发中,数据会分散在多张表中(为了减少冗余)。例如:
- 用户表:存用户基本信息
- 订单表:存订单信息
- 查询“张三的订单”就需要同时查两张表
#### 2. 连接查询分类
| 连接类型 | 关键字 | 说明 |
| -------- | ---------- | ------------------------- |
| 内连接 | INNER JOIN | 只返回匹配的记录 |
| 左外连接 | LEFT JOIN | 左表全部 + 右表匹配的 |
| 右外连接 | RIGHT JOIN | 右表全部 + 左表匹配的 |
| 全外连接 | FULL JOIN | 两张表全部(MySQL不支持) |
| 交叉连接 | CROSS JOIN | 笛卡尔积(慎用) |
#### 3. 内连接(INNER JOIN)
```sql
-- 标准写法
SELECT u.name, o.order_no, o.amount
FROM user u
INNER JOIN orders o ON u.id = o.user_id;
-- 隐式写法(不推荐,可读性差)
SELECT u.name, o.order_no, o.amount
FROM user u, orders o
WHERE u.id = o.user_id;
```
#### 4. 左外连接(LEFT JOIN)
```sql
-- 查询所有用户及其订单(没有订单的用户也会显示)
SELECT u.name, o.order_no, o.amount
FROM user u
LEFT JOIN orders o ON u.id = o.user_id;
-- 结果示例:
-- 张三 | 001 | 100
-- 张三 | 002 | 200
-- 李四 | NULL | NULL (李四没有订单)
```
#### 5. 多表连接(三张以上)
```sql
-- 查询订单详情:用户 + 订单 + 商品
SELECT u.name, o.order_no, p.product_name, od.quantity
FROM user u
INNER JOIN orders o ON u.id = o.user_id
INNER JOIN order_detail od ON o.id = od.order_id
INNER JOIN product p ON od.product_id = p.id;
```
#### 6. 自连接
一张表和自己连接,用于存储层级关系(如员工-上级)。
```sql
-- 员工表:id, name, manager_id
SELECT e.name AS 员工, m.name AS 上级
FROM employee e
LEFT JOIN employee m ON e.manager_id = m.id;
```
#### 7. 子查询
```sql
-- WHERE子查询:查询成绩高于平均分的学生
SELECT name, score
FROM student
WHERE score > (SELECT AVG(score) FROM student);
-- FROM子查询:将查询结果当作临时表
SELECT t.class, AVG(t.score)
FROM (SELECT * FROM student WHERE score > 60) t
GROUP BY t.class;
-- EXISTS子查询:存在性判断
SELECT * FROM user u
WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);
```
#### 8. UNION合并查询
```sql
-- 合并两个查询结果(去重)
SELECT name FROM user
UNION
SELECT name FROM vip_user;
-- UNION ALL(不去重,性能更好)
SELECT name FROM user
UNION ALL
SELECT name FROM vip_user;
```
---
### 二、索引
#### 1. 索引的底层数据结构
MySQL默认使用**B+树**作为索引结构:
| 数据结构 | 特点 |
| -------- | ------------------------------------------ |
| B+树 | 叶子节点存储数据,非叶子节点存指针,矮胖型 |
| 哈希表 | 等值查询快,范围查询慢 |
| 红黑树 | 高度太高,磁盘IO多 |
**B+树优点:**
- 高度低(3-4层可存千万级数据)
- 叶子节点有序链表,支持范围查询
- 磁盘IO次数少
#### 2. 索引分类
| 分类 | 说明 | 特点 |
| -------- | ------------ | -------------------------- |
| 主键索引 | PRIMARY KEY | 唯一、非空、一张表只有一个 |
| 唯一索引 | UNIQUE | 列值必须唯一,允许NULL |
| 普通索引 | INDEX | 最基本的索引,无限制 |
| 复合索引 | INDEX(a,b,c) | 多列组合,遵循最左前缀 |
| 全文索引 | FULLTEXT | 用于文本搜索(MyISAM) |
| 空间索引 | SPATIAL | 用于地理数据 |
#### 3. 索引操作
```sql
-- 创建索引
CREATE INDEX idx_name ON user(name);
CREATE UNIQUE INDEX idx_email ON user(email);
CREATE INDEX idx_name_age ON user(name, age); -- 复合索引
-- 建表时指定
CREATE TABLE user (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20),
email VARCHAR(50) UNIQUE,
INDEX idx_name (name)
);
-- 删除索引
DROP INDEX idx_name ON user;
-- 查看索引
SHOW INDEX FROM user;
-- 强制使用索引
SELECT * FROM user FORCE INDEX (idx_name) WHERE name = '张三';
```
#### 4. 复合索引最左前缀原则
```sql
-- 创建复合索引 (a, b, c)
CREATE INDEX idx_abc ON table(a, b, c);
-- 能用到索引的查询
WHERE a = 1
WHERE a = 1 AND b = 2
WHERE a = 1 AND b = 2 AND c = 3
-- 用不到索引的查询
WHERE b = 2 -- 没带最左边a
WHERE a = 1 AND c = 3 -- 跳过了b,只有a能用
```
#### 5. 索引失效场景
| 场景 | 示例 | 原因 |
| ------------ | ------------------------------ | ----------------------- |
| 函数操作 | `WHERE YEAR(create_time)=2024` | 对列用了函数 |
| 隐式类型转换 | `WHERE phone=13800138000` | phone是字符串,没用引号 |
| 模糊匹配开头 | `WHERE name LIKE '%三'` | 通配符在开头 |
| OR条件 | `WHERE a=1 OR b=2` | 两边都要有索引 |
| 不等号 | `WHERE age != 18` | 不等于不走索引 |
| IS NULL | 部分情况 | 取决于NULL值比例 |
#### 6. 索引使用原则
| 原则 | 说明 |
| -------- | --------------------------------------- |
| 区分度高 | 列值越唯一越好(如手机号 > 性别) |
| 经常查询 | 建在WHERE、ORDER BY、GROUP BY、JOIN列上 |
| 不宜过多 | 单表索引不超过5-6个 |
| 小表不用 | 数据量小,全表扫描更快 |
| 避免重复 | 同样功能的索引只建一个 |
#### 7. 查看SQL执行计划
```sql
EXPLAIN SELECT * FROM user WHERE name = '张三';
```
**关键字段:**
| 字段 | 含义 | 好坏 |
| ------------- | ------------ | --------------------------------- |
| type | 连接类型 | const > ref > range > index > ALL |
| possible_keys | 可能用的索引 | - |
| key | 实际用的索引 | 看是否用了想要的 |
| rows | 扫描行数 | 越少越好 |
| Extra | 额外信息 | Using index(覆盖索引)最好 |
---
### 三、事务
#### 1. ACID详解
| 特性 | 含义 | 例子 |
| ------ | -------- | ---------------------------------- |
| 原子性 | 不可分割 | 转账:扣钱和加钱必须同时成功或失败 |
| 一致性 | 数据正确 | 转账前后总金额不变 |
| 隔离性 | 互不干扰 | 两个事务同时执行,互不影响 |
| 持久性 | 永久保存 | 提交后数据不丢失 |
#### 2. 事务并发问题
| 问题 | 说明 | 例子 |
| ---------- | ------------------------ | --------------------------- |
| 脏读 | 读到未提交的数据 | A修改未提交,B读到,A回滚 |
| 不可重复读 | 同一事务两次读取结果不同 | A两次读,中间B修改了 |
| 幻读 | 读到新增的数据 | A查询,B插入,A再查多了一条 |
#### 3. 隔离级别与问题对应
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
| ---------------- | ---- | ---------- | ----------------- |
| READ UNCOMMITTED | 可能 | 可能 | 可能 |
| READ COMMITTED | 不会 | 可能 | 可能 |
| REPEATABLE READ | 不会 | 不会 | 可能(MySQL解决) |
| SERIALIZABLE | 不会 | 不会 | 不会 |
> MySQL默认 REPEATABLE READ,通过MVCC解决了幻读问题。
#### 4. 事务操作
```sql
-- 开启事务
START TRANSACTION;
-- 或
BEGIN;
-- 执行SQL
UPDATE account SET money = money - 100 WHERE id = 1;
UPDATE account SET money = money + 100 WHERE id = 2;
-- 查看当前事务隔离级别
SELECT @@transaction_isolation;
-- 设置保存点(回滚到指定位置)
SAVEPOINT sp1;
ROLLBACK TO sp1;
-- 提交
COMMIT;
-- 回滚
ROLLBACK;
```
---
### 四、视图
#### 1. 什么是视图?
视图是**虚拟表**,不存储数据,查询时动态生成。
#### 2. 视图操作
```sql
-- 创建视图
CREATE VIEW user_order_view AS
SELECT u.name, o.order_no, o.amount
FROM user u
LEFT JOIN orders o ON u.id = o.user_id;
-- 使用视图(和表一样)
SELECT * FROM user_order_view WHERE amount > 100;
-- 查看视图
SHOW FULL TABLES WHERE Table_type = 'VIEW';
-- 删除视图
DROP VIEW user_order_view;
```
#### 3. 视图的优缺点
| 优点 | 缺点 |
| ---------------------- | ------------ |
| 简化复杂查询 | 性能可能下降 |
| 数据安全(隐藏敏感列) | 增删改有限制 |
| 逻辑封装 | 维护成本 |
---
### 五、存储过程
#### 1. 什么是存储过程?
预编译的SQL代码块,类似Java中的方法。
```sql
-- 创建存储过程
DELIMITER //
CREATE PROCEDURE get_user_by_id(IN uid INT)
BEGIN
SELECT * FROM user WHERE id = uid;
END //
DELIMITER ;
-- 调用
CALL get_user_by_id(1);
-- 删除
DROP PROCEDURE get_user_by_id;
```
#### 2. 带输出参数的存储过程
```sql
DELIMITER //
CREATE PROCEDURE get_user_count(OUT total INT)
BEGIN
SELECT COUNT(*) INTO total FROM user;
END //
DELIMITER ;
-- 调用
CALL get_user_count(@total);
SELECT @total;
```
#### 3. 存储过程优缺点
| 优点 | 缺点 |
| -------------- | ---------- |
| 减少网络传输 | 调试困难 |
| 预编译,性能好 | 移植性差 |
| 业务逻辑封装 | 维护成本高 |
> 实际开发中,业务逻辑通常放在Java代码中,存储过程用得较少。
---
### 六、触发器
#### 1. 什么是触发器?
在某个表执行INSERT、UPDATE、DELETE时**自动触发**执行的SQL。
```sql
-- 创建触发器:用户删除时,记录日志
DELIMITER //
CREATE TRIGGER user_delete_log
AFTER DELETE ON user
FOR EACH ROW
BEGIN
INSERT INTO user_log(user_id, action, time)
VALUES (OLD.id, 'DELETE', NOW());
END //
DELIMITER ;
-- 查看触发器
SHOW TRIGGERS;
-- 删除触发器
DROP TRIGGER user_delete_log;
```
> 注意:触发器使用要谨慎,会增加数据库压力,调试困难。
---
### 七、JDBC连接MySQL
#### 1. 引入依赖
```xml
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
```
#### 2. 完整代码示例
```java
import java.sql.*;
public class MySQLDemo {
// 连接参数
private static final String URL = "jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8";
private static final String USER = "root";
private static final String PASSWORD = "123456";
public static void main(String[] args) {
// 1. 加载驱动(MySQL8可选,但建议保留)
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// 2. try-with-resources自动关闭资源
String sql = "SELECT id, name, age FROM user WHERE age > ?";
try (Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
PreparedStatement ps = conn.prepareStatement(sql)) {
// 设置参数
ps.setInt(1, 18);
// 执行查询
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
int age = rs.getInt("age");
System.out.println(id + " | " + name + " | " + age);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
```
#### 3. CRUD完整操作
```java
public class UserDao {
// 增
public void add(User user) {
String sql = "INSERT INTO user(name, age, email) VALUES(?, ?, ?)";
try (Connection conn = DBUtil.getConnection();
PreparedStatement ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
ps.setString(1, user.getName());
ps.setInt(2, user.getAge());
ps.setString(3, user.getEmail());
int rows = ps.executeUpdate();
if (rows > 0) {
ResultSet rs = ps.getGeneratedKeys();
if (rs.next()) {
user.setId(rs.getInt(1)); // 获取自增ID
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
// 删
public void delete(int id) {
String sql = "DELETE FROM user WHERE id = ?";
try (Connection conn = DBUtil.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setInt(1, id);
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
// 改
public void update(User user) {
String sql = "UPDATE user SET name=?, age=?, email=? WHERE id=?";
try (Connection conn = DBUtil.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, user.getName());
ps.setInt(2, user.getAge());
ps.setString(3, user.getEmail());
ps.setInt(4, user.getId());
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
// 查(单个)
public User getById(int id) {
String sql = "SELECT * FROM user WHERE id = ?";
try (Connection conn = DBUtil.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setInt(1, id);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
User user = new User();
user.setId(rs.getInt("id"));
user.setName(rs.getString("name"));
user.setAge(rs.getInt("age"));
user.setEmail(rs.getString("email"));
return user;
}
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
// 查(列表)
public List<User> listAll() {
List<User> list = new ArrayList<>();
String sql = "SELECT * FROM user";
try (Connection conn = DBUtil.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
User user = new User();
user.setId(rs.getInt("id"));
user.setName(rs.getString("name"));
user.setAge(rs.getInt("age"));
user.setEmail(rs.getString("email"));
list.add(user);
}
} catch (SQLException e) {
e.printStackTrace();
}
return list;
}
}
```
#### 4. 连接池工具类(Druid)
```java
import com.alibaba.druid.pool.DruidDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
public class DBUtil {
private static DruidDataSource dataSource;
static {
dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=Asia/Shanghai");
dataSource.setUsername("root");
dataSource.setPassword("123456");
// 连接池配置
dataSource.setInitialSize(5); // 初始连接数
dataSource.setMinIdle(5); // 最小空闲连接
dataSource.setMaxActive(20); // 最大活跃连接
dataSource.setMaxWait(60000); // 最大等待时间(毫秒)
dataSource.setValidationQuery("SELECT 1"); // 心跳检测
dataSource.setTestOnBorrow(true); // 借用时检测
}
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
public static DataSource getDataSource() {
return dataSource;
}
}
```
#### 5. JDBC事务操作
```java
public void transfer(int fromId, int toId, double amount) {
Connection conn = null;
try {
conn = DBUtil.getConnection();
conn.setAutoCommit(false); // 开启事务
// 扣钱
String sql1 = "UPDATE account SET money = money - ? WHERE id = ?";
try (PreparedStatement ps = conn.prepareStatement(sql1)) {
ps.setDouble(1, amount);
ps.setInt(2, fromId);
ps.executeUpdate();
}
// 加钱
String sql2 = "UPDATE account SET money = money + ? WHERE id = ?";
try (PreparedStatement ps = conn.prepareStatement(sql2)) {
ps.setDouble(1, amount);
ps.setInt(2, toId);
ps.executeUpdate();
}
conn.commit(); // 提交
System.out.println("转账成功");
} catch (Exception e) {
try {
if (conn != null) {
conn.rollback(); // 回滚
}
} catch (SQLException ex) {
ex.printStackTrace();
}
e.printStackTrace();
System.out.println("转账失败");
} finally {
try {
if (conn != null) {
conn.setAutoCommit(true); // 恢复自动提交
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
```
---
### 八、SQL优化技巧
| 优化点 | 错误写法 | 正确写法 |
| -------------- | -------------------------- | -------------------------------- |
| 避免SELECT * | `SELECT * FROM user` | `SELECT id, name FROM user` |
| 用LIMIT | 全表查 | `SELECT * FROM user LIMIT 10` |
| 用EXISTS代替IN | `WHERE id IN (SELECT ...)` | `WHERE EXISTS (SELECT 1...)` |
| 批量插入 | 循环单条INSERT | `INSERT INTO VALUES (1),(2),(3)` |
| 用UNION ALL | `UNION`(去重) | 不需要去重用`UNION ALL` |
| 避免OR | `WHERE a=1 OR b=2` | 用UNION或分开查 |
---
### 九、今日练习
```sql
-- 1. 三表连接查询
SELECT u.name, o.order_no, p.product_name
FROM user u
INNER JOIN orders o ON u.id = o.user_id
INNER JOIN order_item oi ON o.id = oi.order_id
INNER JOIN product p ON oi.product_id = p.id
WHERE u.id = 1;
-- 2. 创建复合索引
CREATE INDEX idx_name_age ON user(name, age);
-- 3. 查看执行计划
EXPLAIN SELECT * FROM user WHERE name = '张三';
-- 4. 事务操作
START TRANSACTION;
UPDATE account SET money = money - 100 WHERE id = 1;
UPDATE account SET money = money + 100 WHERE id = 2;
COMMIT;
-- 5. 创建视图
CREATE VIEW rich_user AS
SELECT * FROM user WHERE money > 10000;
-- 6. 分页查询(每页10条)
SELECT * FROM user ORDER BY id LIMIT 0, 10; -- 第1页
SELECT * FROM user ORDER BY id LIMIT 10, 10; -- 第2页
```
# 股票知识
## 超级云脑
---
### 一、投资决策的三大难题
在股票投资中,我们经常面临三个核心问题:
| 问题编号 | 核心问题 | 具体描述 |
| -------- | -------------- | -------------------------------------- |
| 问题一 | 能持有吗? | 股票买完后,不知道能不能继续持有 |
| 问题二 | 有风险吗? | 股票在上涨过程中,不知道风险有多大 |
| 问题三 | 主力什么态度? | 股票遇到压力时,不知道主力是在买还是卖 |
**解决方案:** 利用人工智能(AI)分析金融大数据,用AI解决决策难题。
---
### 二、超级云脑是什么?
**定义:** 超级云脑是将人工智能与金融股票领域融合的工具,能够快速处理大量金融数据,为投资者提供行情分析和预判。
**三大优势:**
| 优势 | 说明 |
| ---------- | -------------------------------------- |
| 处理速度快 | 瞬间处理大量金融数据 |
| 能赚钱 | 通过大数据分析帮助投资者获利 |
| 天然匹配 | 金融市场本身就是大数据市场,AI正好适合 |
---
### 三、核心功能一:六色罗盘(判断安全与风险)
六色罗盘是一个从**绿色(安全)到红色(风险)** 的图示工具。
| 区域 | 含义 | 操作建议 |
| -------- | ------ | ------------------ |
| 绿色区域 | 安全区 | 相对安全,可持有 |
| 红色区域 | 风险区 | 注意风险,考虑减仓 |
**罗盘细分:**
- 强撑强压区
- 弱撑强压区
- 强撑中压区
- 弱撑中压区
- 强撑弱压区
- 弱撑弱压区
> **使用方法:** 看指针指向哪个区域,绿色安全,红色危险。
---
### 四、核心功能二:技术指标分析(判断压力与支撑)
技术指标分析告诉我们以下关键信息:
| 指标 | 含义 | 示例数据 |
| ---------------- | ---------------------------- | ------------------ |
| 中长期筹码成本价 | 大多数持股者的平均成本 | 1.648 |
| 短期资金成本价 | 近期买入资金的平均成本 | 1.589 |
| 压力位 | 股价涨到这个位置可能遇到阻力 | 3.084 |
| 支撑位 | 股价跌到这个位置可能获得支撑 | 0.505 |
| 趋势 | 股价的长期运行方向 | 中长期处于上升趋势 |
**关键判断:**
- 压力强度大 → 需要放巨量才能突破
- 获利筹码增加 + 获利了结意愿不明显 → 筹码稳定性好
---
### 五、核心功能三:资金流向(判断主力态度)
| 观察点 | 判断依据 | 结论 |
| ---------------- | ---------------- | ---------- |
| 庄家在买还是卖? | 当前多头资金占优 | 主力在买 |
| 资金是否持续? | 多头资金持续流入 | 资金在流进 |
> **结论:** 当前市场多头资金占优,且持续流入,整体资金在流进。
---
### 六、超级云脑四大分析维度
| 维度 | 要回答的问题 | 对应功能 |
| -------- | ---------------------- | ------------ |
| 安全性 | 我的股票安全吗? | 六色罗盘 |
| 压力点 | 涨到什么价位要注意? | 技术指标分析 |
| 主力态度 | 主力在买还是卖? | 资金流向分析 |
| 资金动向 | 市场资金流入还是流出? | 资金流向分析 |
---
###
Loading…
Cancel
Save