MySQL学习记录

MySQL

数据库的概率

row:行(记录)
rank:列 (字段)
是关系数据库(由行和列组成的)
数据库由表、关系以及操作对象组成
补充:  非关系数据库:Redis MongoDB
非关系数据库的数据不是以表的形式保存的,而是以键值对的形式保存的
​
​
常见的关系数据库:SQL Server   MySQL   Oracle
DB2   SQLite

注意

如判断是否为空的时候,不要用 ==null 而是用 IS NULL

主键

1.主键必须是非空且唯一的
2.一个表只能有一个主键,主键约束确保了表中的行是唯一的
#主键可以是一列或者多列 比如成绩表可以是(课程id和学生id作为联合主键)
​
3.表中可以没有主键,但是通常情况下应当为表设置一个主键

选择原则:

  • 最少性

    尽量选择单个字段作为主键

  • 稳定性

    尽量选择数值更新少的列作为主键

外键

简单来说,就是 子表 中对应的于 主表 的列,在子表中称为外键或者引用键
​
外键用来  强制引用完整性

参照完整性:主键和外键

自定义完整性:存储过程、触发器

结构化查询语句SQL

SQL语句的分类

1.数据查询语句(DQL)    Select      数据选择查询
​
2.数据操作语句(DML)    Insert      插入
                     Update      更新
                     Delete      删除
​
3.数据定义语句(DDL)    Create      新建
                     Alter       修改结构
                     Drop        删除
                     Rename      重命名
                     Truncate    删除
​
4、数据控制语句(DCL)   Grant       授权
                     Revoke      解除授权

语句规则

1.SQL语句要以 ; 结尾,一条SQL语句可以描述一个数据库操作,在RDBMS中,SQL语句也是逐条执行的
​
2.SQL语句不区分大小写,例如SELECT 和 select是一个意思
​
3.字符串和日期值需要用引号括起来,如'abc' ,'2020-09-20'这样的,但是数值型的值,如1,2,3等这样的不需要用括号括起来

创建数据库

CREATE DATABASE [IF NOT EXISTS] 数据库名

查询数据库

show databases;
​
​
show create table 表名     #可以查到表的定义语句

删除数据库

drop database 数据库名;

连接到数据库

use 数据库名

创建表

create table 表名(
    列名 数据类型 约束;
    列名 数据类型 约束;
)

数据类型

char(n) 定长字符串:字符串长度是一定的,如果实际长度不足,将以空格来补齐。比如char(10),那么如果实际存储的字符是hello,将存储hello+5个空格
​
​
varchar(n) 不定长字符串,如果长度不足不会用空格补充,如果实际存储的是hello,则存储的字符长度为5
​
​
int     整数值
​
float   单精度浮点型
​
text    大容量文本
​
blob    二进制大对象    (存图片、视频等)

删除表

DROP TABLE 表名

通过外键约束链接到一起的表不能被删除,在删除表之前,必须先删除约束,在删除表时,我们是表的所有者或者对该表有管理员权限

复制表

复制表,且复制他的结构和数据

create table 新表名 as (select * form 被复制的表名);

只复制表的结构,不复制数据

create table 新表名 like 被复制的表名;

修改表名

alter table 表名 rename as 新的表名;
​
例: alter table stu rename as student;

添加列

alter table 表名 add column 列的定义;
​
例:alter table Product ADD COLUMN product_name VARCHAR(100);

删除列

alter table 表名 drop column 列名;
​
例:alter table students drop column sname;

创建主键(PRIMARY KEY)

类型1

create table stu(
    ID INT PRIMARY KEY,
    sname VARCHAR(5) NOT NULL,
    sex int
    )

类型2

create table stu(
        id int,
        sname varchar(5) NOT NULL,
        sex int,
        constraint pk_stu PRIMARY KEY (id)
)

类型3(复合主键)

create table stu(
        id int,
        sname varchar(5) NOT NULL,
        sex int,
        PRIMARY KEY(id,sname)
)

补充主键

用ALTER语句补充声明主键
​
ALTER TABLE stu ADD CONSTRAIN pk_stu PRIMARY KEY(id,name);

删除主键

ALTER TABLE stu DROP PRIMARY KEY;   #主键只有一个,删除即可

创建外键

CREATE TABLE IF NOT EXISTS demo_new (
    cid INT PRIMARY KEY,
    sid INT,
    FOREIGN(sid) REFEREENCES demo(sid)
    )
​

更新时外键会跟着一起更新

CREATE TABLE IF NOT EXISTS demo_new (
    cid INT PRIMARY KEY,
    sid INT,
    FOREIGN(sid) REFEREENCES demo(sid) ON UPDATE CASECADE
    )
​

更新时外键会跟着一起更新,删除的时候也会跟着一起删除

CREATE TABLE IF NOT EXISTS demo_new (
    cid INT PRIMARY KEY,
    sid INT,
    FOREIGN(sid) REFEREENCES demo(sid) ON UPDATE CASECADE ON DELETE CASECADE
    )

更新时外键会跟着一起更新,删除的时候也会不会跟着一起删除

CREATE TABLE IF NOT EXISTS demo_new (
    cid INT PRIMARY KEY,
    sid INT,
    FOREIGN(sid) REFEREENCES demo(sid) ON UPDATE CASECADE ON DELETE RESTRICT
    )

补充外键

ALTER TABLE demo_new ADD CONSTRAINT fk_demo_new FOREIGN KEY(sid)
REFERENCES demo(id)
ON DELETE CASECADE ON UPDATE CASCADE;

删除外键

ALTER TABLE 表名 DROP FOREIGN KEY 外键名称

自增长(AUTO_INCREMENT)

CREATE TABLE demo(
    #设置为自增的列必须设置为主键,并且一张表只能有一个自增列
    ID int AUTO_INCREMENT PRIMARY KEY,
    
)
​
​
insert  into demo values (DEFAULT,'tester1');

唯一约束(UNIQUE)

与主键的区别:约束唯一但是可以为空,但是主键不可以为空
​
CREATE TABLE demo(
    vip VARCHAR(50) UNIQUE
    )

检查约束

CREATE TABLE demo(
    sex SET('男','女')
    vip VARCHAR(50) UNIQUE
    )

创建默认值(DEFAULT)

CREATE TABLE demo(
    sex SET('男','女')
    vip VARCHAR(50) UNIQUE
    tel VARCHAR(11) DEFAULT '13799490088'
    )

DML语句(增,删,改)

插入

insert into 表名 (列名)  values (值)
​
​
例:insert into Students(Sname,Saddress,SGrade) values ('张三','福建厦门','6')

注意:如果在设计表的的时候就指定某列不为空,但插入数据的时候没有提供这个值,则mysql会给该列插入一个默认的值。

一次插入多个值

insert into students(Sname,SGrade,SSex) VALUES
('张课',7,1),
('张是',7,1),
('张删除',7,1),
('张对',7,1),
('张是的',7,1),
('张速度',7,1);
​

更新

UPDATE 表名 SET 列名 = 更新值  WHERE 条件
​
​
UPDATE Students SET SSEX = 0;
​
UPDATE Students
SET Scores = Scores + 5
WHERE Scores <= 95;

删除

DELETE FROM 表名 WHERE 删除条件
DELETE FROM stu;
和 TRUNCATE TABLE stu的区别
​
DELETE不会提交事务 而TRUNCATE会提交事务 没办法回滚数据。 TRUNCATE不会记录删除的日志,TRUNCATE的效率比较高。

DQL 查询语句

SELECT 列名
FROM 表名
WHERE 查询条件语句
ORDER BY 排序的列名  [DESC 或 ASC]  默认是升序 ASC    降序 DESC
​
​
​
例:SELECT stuid,age+10 FROM students;

as 可以重命名
​
​
SELECT stuid AS '学生' FROM students;

去重 DISTINCT
​
select DISTINCT sname from students;

限制行数

select 列1,列2 .... from 表 limit offset,count;
​
offset参数指定要返回的第一行的偏移量。第一行的偏移量为0,而不是1
count指定要返回的最大行数
​
​
两个参数的时候
select * from emp limit 5,6  --从偏移量为5的行开始取,取6行
​
一个参数的时候
select * from emp limit 5   -- 取前5个
​
​
取工资最高的前三个
​
select * from emp ORDER BY DESC LIMIT 3;
​
取工资第四高的
​
select * from emp ORDER BY DESC LIMIT 3,1

where

注意,在where子句中字符串和日期要用单引号括起来

select * from emp where hiredate >='1981-04'

运算符

BETWEEN AND       在两个值之间(包含)
​
IN(list)          匹配列出的值
​
LIKE              匹配一个字符模式
​
IS NULL           是空值
​
​
<>               不等于
​
​
SELECT reader.`NAME`,reader.COMPANY,borrow.BORROW_DATE FROM reader INNER JOIN borrow ON reader.READER_ID = borrow.READER_ID  AND borrow.BORROW_DATE IN (SELECT borrow.BORROW_DATE FROM reader INNER JOIN borrow 
ON reader.READER_ID = borrow.READER_ID  AND reader.`NAME`='赵正义') 
AND reader.`NAME`<>"赵正义";
​

                                                            优先级
AND             如果组合的条件都为真则返回真值                     3
​
OR              如果组合的条件 之一是真值,返回真值                 4
​
NOT             如果条件为假则返回真值                            2
​
所有比较运算                                                    1
SELECT   empno,ename,job,sal
FROM     emp
WHERE    sal>=1100
AND      job='CLERK';

BETWEEN

SELECT ename,sal
FROM emp
WHERE sal BETWEEN 1000 AND 1500;

IN 主要和括号里的一个相等就匹配成功

SELECT empno,ename,sal,mgr
FROM emp
WHERE mgr IN(7902,7566,7788);

LIKE执行通配查询

查询条件可包含文字字符和数字

% 可表示零或者多个字符

_ 可表示一个字符

SELECT ename
FROM   emp
WHERE  ename LIKE 'S%';

IS NULL

SELECT ename,mgr
FROM   emp
WHERE  mgr is NULL;

ORDER BY

ASC   升序,缺省   默认是ASC
​
DESC  降序     

数据分组和聚合函数

常见的聚合函数

COUNT:  返回结果集中行的数目
​
count(*)  返回表中的记录数
​
count(列名)  返回非空记录数
​
​
​
​
SUM:    返回结果集中所有值的总和
​
AVG:   返回结果集中所有值的平均值
​
MAX:   返回结果集中所有值的最大值
​
MIN:   返回结果集中所有值的最小值
这样会把列名中为NULL的值记为0
​
SELECT AVG(IFNULL(列名,0))
FROM 表名;
分组计算平均值
​
SELECT deptno,AVG(sal)
FROM emp
ORDER BY deptno;

Having子句

Having子句的作用是对分组进行过滤
记录被分组
使用组函数
匹配HAVING子句的组被显示
匹配HAVING子句的组被显示
HAVING子句应放在GROUP BY后面,ORDER BY之前

限定分组结果

SELECT deptno,max(sal)
FROM   emp
GROUP BY deptno
HAVING  max(sal)>2900;

SELECT job,SUM(sal) AS PAYROLL
FROM   emp
WHERE  job NOT LIKE 'SALES%'
GROUP BY  job
HAVING    SUM(sal)>5000
ORDER BY  SUM(sal);

显示组最高平均工资

SELECT max(avg(sal))
FROM   emp
GROUP BY deptno;

分组查询的区别

WHERE子句:
- 从数据源中去掉不符合其搜索条件的数据
​
GROUP BY 子句:
- 搜索数据行各个组中,统计函数为各个组计算统计值,每个组输出一行结果
​
HAVING 子句:
- 从分组计算结果中进行过滤,去掉不符合其组搜索条件的各组数据行

因为A1,B1没有参与查询所以只返回第一行,然后max返回最大的

执行顺序

子查询

#

子查询的规则

子查询要用括号括起来
​
将子查询放在比较运算符的右边
​
子查询中不要加order by 语句
​
对单行子查询使用单行运算符  = > < 
​
对多行子查询语句使用多行运算符 in 、 any 、 all
​
​
<any   小于最大值
>any   大于最小值
​
<all   小于最小值
>all   大于最小值

select empno,ename,job
from emp
where sal < ANY
(select sal
 from emp
 where job = 'CLERK')
​
只有有一个满足小于就行

多表查询

注意

所有的多表连接都必须指定连接条件,(使用where关键字指定或xxx join on指定)。不指定连接条件的时候,将形成笛卡尔积,这是没有任何意义的。
​
当要显示连接条件的所有复合数据的时候,使用内连接。如果既要显示复合条件的数据,又要显示不符合连接条件的数据,则需要使用外连接。

内连接

INNER JOIN

外连接

左外连接(LEFT JOIN)

右外连接(RIGHT JOIN)

内连接

两个书写的方法也一样的

select table1.column,table2.column
from   table1,table2
where  table1.column1 = table2.column2  #一般是主外键连接
​
​
​
​
select table1.column,table2.column
from   table1  INNER JOIN table2
on  table1.column1 = table2.column2  #一般是主外键连接

在多表连接的时候使用过滤条件

SELECT emp.empno,emp.ename,emp.deptno,
dept.deptno,dept.loc
FROM emp,dept
WHERE emp.deptno = dept.deptno and emp.ename = 'KING'
​

外连接

左连接

在LEFT JOIN 中,返回左表的所有行,即使左表中有不符合连接的条件的记录,也会在查询结果中显示,同理RIGHT JOIN就是返回右表中所有记录。
​
左右区分的使用,就是看要全部显示记录的那张表是在左边还是右边
SELECT emp.ename,dept.deptno FROM emp RIGHT JOIN dept 
ON emp.deptno = dept.deptno;
​
#就是返回右边的全部记录,包括在左表中没有对应到的记录

右连接

SELECT emp.ename,dept.deptno FROM dept LEFT JOIN emp
ON emp.deptno = dept.deptno;
​
#就是返回左边的全部记录,包括在右边中没有对应到的记录

存储过程

概念

存储过程是存储在数据库目录中的一段声明性SQL语句,存储过程写好后,可以被其他编程语言直接调用,非常方便。

变量

  • 用户自定义变量

select max(sal) into @maxsal from emp;

找到sal的最大值然后将他赋值给sal
select MAX(price) into @maxsal from book;
SELECT @maxsal;

存储过程

定义存储过程

DELIMITER //
 CREATE PROCEDURE 存储过程名字()
 BEGIN
 --存储过程代码
 END //
DELIMITER
​
​
一般写成这样也行
​
CREATE PROCEDURE 存储过程名字()
 BEGIN
 --存储过程代码
 END 

存储过程例子

DROP PROCEDURE IF EXISTS get_maxsal;
DELIMITER//
CREATE PROCEDURE get_maxsal()
    BEGIN
        SELECT max(sal) from emp;
    END//
    
    
一般写这样就行
CREATE PROCEDURE get_maxsal()
    BEGIN
        SELECT max(sal) from emp;
    END

CALL get_maxsal();   --调用存储过程

在存储过程中声明变量

声明变量的语法:
DECLARE variable_name datatype(size) DEFAULT default_value;
​
变量赋值:
SET 变量 = 变量值 -- 注意这里变量前面没有@符号
也可以用sql语句赋值:
SELECT xxx into 变量名 from xxxx

例子

DROP PROCEDURE IF EXISTS get_maxsal;
CREATE PROCEDURE get_maxsal()
    BEGIN
        DECLARE avgsal INT;
        SELECT avg(sal) into avgsal from emp;
        SELECT enmae,sal from emp where sal > avgsal;
    END
    
call get_maxsal();

参数有三种模式

在MySQL中,参数有三种模式:IN OUT 或 INOUT
​
IN  是默认模式,在存储过程中用定义IN参数,调用该存储过程的时候必须将参数传递给存储过程
​
OUT 可以再存储过程中更改OUT参数的值,并将其更改后新值传递回调用程序,由于OUT参数并没有被赋值,所以不能读取,只能赋值。
​
INOUT  INOUT参数是IN和OUT参数的组合,这意味着调用程序可以传递参数,并且存储过程可以修改INOUT参数并将新值传递回调用程序

例子

DROP PROCEDURE IF EXISIS get_sal;
CREATE PROCEDURE get_sal(IN empname VARCHAR(5),OUT empsal INT)
    BEGIN
        SELECT sal INTO emsal from emp WHERE ename = empname;
    END
​
--在存储过程中定义的参数,会在mysql中自动生成以下划线命名的参数
CALL get_sal('BLAKE',@_empsal);
SELECT @_empsal;

例子

CREATE PROCEDURE get_total(IN _dept INT , OUT _total INT)
BEGIN
     SELECT count(*) INTO _total FROM emp WHERE deptno = _dept;
 
 END
 
 CALL get_total(40,@emptotal);
 SELECT @emptotal;

流程控制

可以在存储过程中加入流程控制语句
分支
IF
CASE
​
循环
REPEAT
WHILE

IF

IF expression THEN
    statements
END IF;
​
​
​
IF expression THEN
    statements
ELSE
    else-statments
END IF;

CASE

CREATE PROCEDURE p()
    BEGIN
        DECLARE v INT DEFAULT 1
    CASE v
        WHEN 2 THEN SELECT v;
        WHEN 3 THEN SELECT 0;
    ELSE
      BEGIN
        SELECT 'hello';
      END;
    END CASE;
END;

REPEAY

REPEAT
    statement_list
UNITL search_condition
END REPEAT;

WHILE

WHILE search_condition DO
        statement_list
END WHILE;
CREATE PROCEDURE dowhile()
BEGIN
     DECLARE v1 INT DEFAULT 5;
     WHILE v1 > 0 DO
        SELECT 'hello';
        SET v1 = v1 -1;
     END WHILE;
END

事务

概念

 - 事务是作为单个逻辑单元执行的一系列操作
​
- 多个操作作为一个整体向系统提交,要么执行、要么都不执行,事务是一个不可分割的工作逻辑单元
​
- 这特别适合于多用户同时操作的数据通信系统,例如:订票、银行、保险公司以及证券交易系统等

事务的特性

  • 原子性

    组成事务处理的语句形成一个逻辑单元,不能只执行其中的一部分。换句话说,事务是不可分割的最小单位。比如:银行转账过程中,必须同时从一个账号减去转账金额,并加到另一个账户中,只改变了一个账户是不合理的。
  • 一致性

    在事务处理执行前后,数据库是一致的,也就是说,事务应该正确的转换系统状态,比如:银行转账过程中,要么转账金额从一个账户转入另一个账户,要么两个账户都不变,没有其他情况

  • 隔离性

    一个事务处理对另一事务处理没有影响,就是说任何事务都不可能看到一个处在不完整状态下的事务,比如说,银行转账过程中,在转账事务没有提交之前,另一个转账事务只能处于等待状态。

  • 持久性

    事务处理的效果能够被永久保存下来,反过来说,事务应当能够承担所有的失败,包括服务器、进程、通信以及媒体失败等等,银行转账过程中,转账后账户的状态要能被保存下来。

常见事务控制语句

BEGIN 或 START TRANSACTION;显式地开启一个事务;

COMMIT; 用于提交事务,并使已对数据库进行的所有修改称为永久性的;

ROLLBACK;用于回滚事务,回滚会结束用户的事务,并撤销正在进行的所有为提交的修改;

例子

BEGIN;
INSERT INTO dept VALUES(50,'DDDD');
INSERT INTO dept VALUES(50,'SSSS');
COMMIT;     --提交事务

触发器

触发器是一种特殊类型的存储过程,不由用户直接调用,而且可以包含复杂的SQL语句,它们主要用于强制复杂的业务规则或要求。

特点

它与表紧密相连,可以看作表定义的一部分;
​
它不能通过名称被直接调用,更不允许带参数,而是当用户对表中数据进行修改的时候,自动执行;
​
它可以用于MySQL约束,默认值和规则的完整性检查,实施更为复杂的数据完整性约束。

CREATE TRIGGER trigger_name
trigger_time trigger_event ON tbl_name FOR EACH ROW   #每一行
BEGIN
     routine_body
END
​
#trigger_time  :{BEFORE|AFTER}
#trigger_event : {INSERT|UPDATE|DELETE}

例子

向emp表中插入新数据时,如果comm大于sal,则将comm设置为跟sal一样的值
​
CREATE TRIGGER tri_comm BEFORE INSERT ON emp FOR EACH ROW
BEGIN
  if new.comm >new.sal THEN
        SET new.comm = new.sal;
  END IF;
END

删除dept表中还有员工的部门,提示错误
​
CREATE TRIGGER tri_deptno BEFORE DELETE ON dept for EACH ROW
BEGIN
   if old.deptno<>40 THEN
        SIGNAL SQLSTATE'HY000' SET MESSAGE_TEXT = '不能删除还有员工的部门信息';--必须写在一句上
   END IF;
END;

通过Python链接mysql

import pymysql
​
#建立数据库建立
db = pymysql.connect(host="192.168.xx.xx",user="root",password="xxxx",database="xxx")
​
#使用cursor()方法创建一个游标对象cursor
cursor = db.cursor()
​
#使用execute()方法执行SQL查询
cursor.execute("SELECT VERSION()") #要执行的sql语句
# 使用fetchone()方法获取单条数据
data = cursor.fetchone()
print("Database version:%s"%data)
#关闭数据库
db.close()

建表

import pymysql
​
#建立数据库建立
with pymysql.connect(host="localhost",user="root",password="123456",database="library") as db:
    #使用cursor()方法创建一个游标对象cursor
    cursor = db.cursor()
    #使用execute()方法执行SQL查询
    cursor.execute("DROP TABLE IF EXISTS mytable") #要执行的sql语句
    #获取预处理的语句创建表
    sql = """CREATE TABLE mytable (
                FIRST_NAME CHAR(20) NOT NULL,
                LAST_NAME  CHAR(20),
                AGE INT)"""
    cursor.execute(sql)

查询多条数据

import pymysql
​
#建立数据库建立
with pymysql.connect(host="localhost",user="root",password="123456",database="library") as db:
    #使用cursor()方法创建一个游标对象cursor
    cursor = db.cursor()
    #使用execute()方法执行SQL查询
    sql="SELECT*FROM emp WHERE sal>%s"%(1000) #要执行的sql语句
    try:
        cursor.execute(sql)
        results = cursor.fetchall() #还有一个cursor.fetchone()方法
        print('结果数据共{}条'.format(cursor.rowcount))
        for row in results:
            print(row)
    except:
        print('发生错误,无法查询到数据')

调用存储过程(没有使用参数)

import pymysql
​
#建立数据库建立
with pymysql.connect(host="localhost",user="root",password="123456",database="library") as db:
    #使用cursor()方法创建一个游标对象cursor
    cursor = db.cursor()
    cursor.callproc('get_maxsal') #调用callproc方法调用存储过程
    results = cursor.fetchall()
    print(cursor.rowcount)#显示行数
    print(results)

调用存储过程(带参数)

import pymysql
​
#建立数据库建立
with pymysql.connect(host="localhost",user="root",password="123456",database="library") as db:
    #使用cursor()方法创建一个游标对象cursor
    cursor = db.cursor()
    #对于out或inout参数python不支持,随便定义一个值即可
    cursor.callproc('get_sal',('BLAKE',0))
    #对于out和inout型的参数,是保存在服务器的变量中,可以通过select语句查询
    #对于的参数访问格式为 @_存储过程名_0,@_存储过程名_1,以此类推
    cursor.execute("SELECT @_gal_sal_0,@_get_sal_1")
    print(cursor.fetchall())

作业

​
-- 1.利用sql复制一份emp表,生成一个名叫emp1的表。
CREATE TABLE emp1 AS (SELECT * FROM emp);
​
-- 2.在emp1上建立一个触发器,要求在更新emp1的数据时,如果该记录的comm为null,则更新后自动变成0,如果该记录的comm小于sal,则更新后comm等于sal
​
CREATE TRIGGER tri_com BEFORE UPDATE ON emp1 FOR EACH ROW
BEGIN
        if old.comm IS NULL THEN
                SET new.comm = 0;
        ELSEIF old.comm < old.sal THEN
            SET new.comm = new.sal;
        END IF;
END
​
SELECT * FROM emp1;
​
UPDATE emp1 SET comm=110 WHERE empno=7369;
​
​
-- 3.编写一个存储过程,该存储过程接受一个部门编号作为参数,可以求出该部门的员工总数。
DROP PROCEDURE IF EXISTS pro_dep;
CREATE PROCEDURE pro_dep(IN deptno1 INT,OUT total INT)
BEGIN
        SELECT COUNT(empno) INTO total FROM emp1 WHERE deptno = deptno1;
END
​
CALL pro_dep(20,@emptotal);
SELECT @emptotal;   
        

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值