1 changed files with 778 additions and 0 deletions
@ -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 | |
|||
| 趋势 | 股价的长期运行方向 | 中长期处于上升趋势 | |
|||
|
|||
**关键判断:** |
|||
- 压力强度大 → 需要放巨量才能突破 |
|||
- 获利筹码增加 + 获利了结意愿不明显 → 筹码稳定性好 |
|||
|
|||
--- |
|||
|
|||
### 五、核心功能三:资金流向(判断主力态度) |
|||
|
|||
| 观察点 | 判断依据 | 结论 | |
|||
| ---------------- | ---------------- | ---------- | |
|||
| 庄家在买还是卖? | 当前多头资金占优 | 主力在买 | |
|||
| 资金是否持续? | 多头资金持续流入 | 资金在流进 | |
|||
|
|||
> **结论:** 当前市场多头资金占优,且持续流入,整体资金在流进。 |
|||
|
|||
--- |
|||
|
|||
### 六、超级云脑四大分析维度 |
|||
|
|||
| 维度 | 要回答的问题 | 对应功能 | |
|||
| -------- | ---------------------- | ------------ | |
|||
| 安全性 | 我的股票安全吗? | 六色罗盘 | |
|||
| 压力点 | 涨到什么价位要注意? | 技术指标分析 | |
|||
| 主力态度 | 主力在买还是卖? | 资金流向分析 | |
|||
| 资金动向 | 市场资金流入还是流出? | 资金流向分析 | |
|||
|
|||
--- |
|||
|
|||
### |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue