MySql学习笔记

Delphi调用存储过程:

procedure TLoadRecords.AddAppLog(appname, webaddr, ip, mac: string; var userid, opration: integer);
var
  MyQuery1: TSQLDataSet;
  SqlText: string;
begin
  Form_MySql.GetMyQuery(MyQuery1);
  if not assigned(MyQuery1) then
  begin
    exit;
  end;
  SqlText := 'Call insert_app_log(#a,#f,"#b","#c","#d","#e")';
  MyQuery1.CommandText := SqlText;
  MyQuery1.ExecSQL(true);
end;

 

function TChangePassWords.UpDataPassWord(userid: integer;passwordinfo: TChangePassword): integer;
var
  SqlText: string;
  MyQuery1: TSQLDataSet;
begin
  result := -1;
  SqlText := 'CAll update_login_user_pwd_by_userid(#a,"#b","#c","#d","#e")';
  Form_MySql.GetMyQuery(MyQuery1);
  if not assigned(MyQuery1) then
  begin
    exit;
  end;
  MyQuery1.CommandText := SqlText;
  MyQuery1.Open;
  MyQuery1.First;
  while not MyQuery1.Eof do
  begin
    result := MyQuery1.FieldByName('outparam1').AsInteger;
    exit;
  end;
end;

 

①对变量的操作
一:DECLARE语句(用来声明局部变量)
DECLARE仅被用在BEGIN ... END复合语句里,并且必须在复合语句的开头,在任何其它语句之前。
格式:DECLARE var_name[,...] type [DEFAULT value]
例如:DECLARE num int DEFAULT -1 ;
      DECLARE mch CHAR DEFAULT '';
      DECLARE str varchar(260);

注:要给变量提供一个默认值,请包含一个DEFAULT子句。
值可以被指定为一个表达式,不需要为一个常数。
如果没有DEFAULT子句,初始值为NULL。
局部变量的作用范围在它被声明的BEGIN ... END块内。
它可以被用在嵌套的块中,除了那些用相同名字声明变量的块。

二:变量SET语句
格式:SET var_name = expr [, var_name = expr]
  注:expr 【被参考变量】可能是子程序内声明的变量,或者是全局服务器变量
例如:
     DECLARE outparam1 INT DEFAULT 0;
     SET outparam1 = 1;

三:SELECT ... INTO语句
格式:SELECT col_name[,...] INTO var_name[,...] table_expr
注:这个SELECT语法把选定的列直接存储到变量。因此,只有单一的行可以被取回。
例如:SELECT id,data INTO x,y FROM test.t1 LIMIT 1;  #限制一行

重要: SQL变量名不能和列名一样。如果SELECT ... INTO这样的SQL语句包含一个对列的参考,并包含一个与列相同名字的局部变量,MySQL当前把参考解释为一个变量的名字。


②对参数的操作

如果仅仅想把数据传给 MySQL 存储过程,那就使用“in” 类型参数;如果仅仅从 MySQL 存储过程返回值,那就使用“out” 类型参数;如果需要把数据传给 MySQL 存储过程,还要经过一些计算后再传回给我们,此时,要使用“inout” 类型参数。


③创建存储过程
带(输出参数)返回值的存储过程:CALL语句可以用声明为OUT或的INOUT参数的参数给它的调用者传回值。
--删除存储过程
DROP PROCEDURE IF EXISTS proc_employee_getCount
--创建存储过程
CREATE PROCEDURE proc_employee_getCount(out n int)
BEGIN
     SELECT COUNT(*) FROM employee ;
END
--MYSQL调用存储过程
CALL proc_employee_getCount(@n);
 

带输入参数的存储过程:
--删除存储过程
DROP PROCEDURE IF EXISTS proc_employee_findById;
--创建存储过程
CREATE PROCEDURE proc_employee_findById(in n int)
BEGIN
     SELECT * FROM employee where id=n;
END

--定义变量
SET @n=1;
--调用存储过程
CALL proc_employee_findById(@n);
 

操作存储过程时应注意:
1.删除存储过程时只需要指定存储过程名即可,不带括号;
2.创建存储过程时,不管该存储过程有无参数,都需要带括号;
3.在使用SET定义变量时应遵循SET的语法规则;SET @变量名=初始值;
4.在定义存储过程参数列表时,应注意参数名与数据库中字段名区别开来,否则将出现无法预期的结果。

SHOW  CREATE  PROCEDURE(类似于SHOW CREATE TABLE,查看一个已存在的存储过程)
SHOW CREATE PROCEDURE 存储过程名
SHOW  PROCEDURE  STATUS (列出所有的存储过程)
SHOW  PROCEDURE  STATUS
 

④更改命令结束符
(因为在procedure中经常要用到默认的命令结束符--分号(;)
--所以在创建procedure的时候需要定义新的结束符以说明创建procedure的命令结束)
--这里将结束符号改成美元符号--$
delimiter $
create procedure p3(IN nameid int, OUT person_name varchar(10))
begin 
 select * from test.zzm;
 select zzm.name into person_name from test.zzm where zzm.id = nameid;
end 
 $  #命令结束符

创建MySQL存储过程p3
此存储过程的过程名是p3,该过程包含两个参数,
一个是输入类型的(以IN标示),参数名是nameid,类型是int,
一个是输出类型的(以OUT标示),参数名是person_name,类型是varchar(10)
此存储过程的作用是查询出zzm表的全部内容,会输出结果集(data set),然后
再查询表中记录的ID是nameid的字段name,将其输出到第二个输出类型的参数里面,这个查询
不会输出结果集。

 

⑤实例解析
delimiter $
create procedure select_sys_model_all()
BEGIN 
  SELECT DISTINCT sm.* ,sad.`name` as creater_name FROM sys_model sm   //sm为表sys_model的别名
  LEFT JOIN sys_admin sad   //左连接,如果左边这个表的字段Creater_id有值,则结果集中必须有该行;同理,右连接。
  ON sad.id = sm.Creater_id
  ORDER BY id;
  #SELECT * FROM sys_model;
END
$

#找出表sys_model的全部,添加到结果集
#再根据sad.id = sm.Creater_id找出表sys_model的字段sad.`name`,为结果集后边多加了一列命名为creater_name。



BINARY:在字符串比较的时候区分大小写
BINARY不是函数,是类型转换运算符,它用来强制转换它后面的字符串为一个二进制字符串。
SELECT pwd_id INTO pwdid FROM sys_user_info WHERE login_name =BINARY namepar;

SUBSTRING:截取字符串
SUBSTRING(str,pos) ,     SUBSTRING(str FROM pos)
SUBSTRING(str,pos,len) , SUBSTRING(str FROM pos FOR len)
说明:substring(被截取字段,从第几位开始截取)
      substring(被截取字段,从第几位开始截取,截取长度)
使用 FROM的格式为标准 SQL 语法。
也可能对pos使用一个负值,假若这样,则子字符串的位置起始于字符串结尾的pos 字符,而不是字符串的开头位置。
例:select substring(content,5) as abstract from my_content_t
select substring(content,5,200) as abstract from my_content_t
SET str = SUBSTRING(newpwd FROM i FOR 1);

SELECT SUBSTRING( (SELECT user.jlid FROM user WHERE user.id =1), 1, 1 ) )
这里用了子查询,首先查询user表中id为1的jlid字段的值,返回的是字符串,然后使用SUBSTRING进行截取得到字符串。

DATEDIFF() 函数返回两个日期之间的天数。
SELECT DATEDIFF('2008-12-29','2008-12-30') AS DiffDate             //值为-1

⑦LIKE语句的语法格式是:select * from 表名 where 字段名 like 对应值(子串)。
1、LIKE'Mc%' 将搜索以字母 Mc 开头的所有字符串(如 McBadden)。
2、LIKE'%inger' 将搜索以字母 inger 结尾的所有字符串(如 Ringer、Stringer)。
3、LIKE'%en%' 将搜索在任何位置包含字母 en 的所有字符串(如 Bennet、Green、McBadden)。

数据库的模糊查询传值
1.SELECT * FROM log_app_operation WHERE app_name LIKE 'WoD%';
  SELECT * FROM log_app_operation WHERE app_name LIKE CONCAT('%WoD%');
  上面两句效果一样,CONCAT在这里只连接了自己,没用的。
2.ELECT * FROM log_user_operation WHERE user_name LIKE CONCAT('%',param1,'%');
  CONCAT将三个字符串'%',param1和'%'连接成一个字符串 再与user_name字段进行模糊比较。

⑧CAST(* AS *)
将varchar转为Int可以用 cast(a as signed) 其中a为varchar类型的字符串
          如cast(param1 as SIGNED INTEGER)
          如CAST(c.sex AS CHAR)
cast的as后可用的类型:
1.二进制,同带binary前缀的效果 : BINARY
2.字符型,同可带参数 : CHAR()
3.日期 : DATE
4.时间: TIME
5.日期时间型 : DATETIME
6.浮点数 : DECIMAL
7.整数 : SIGNED
8.无符号整数 : UNSIGNED

SELECT * FROM log_app_operation WHERE type =cast(param1 as SIGNED INTEGER)

将Int转为varchar经常用concat函数,比如concat(8,'0') 得到字符串 '80'
一个数字参数被转化为与之相等的二进制字符串格式;若要避免这种情况,可使用显式类型 cast,
例如:SELECT CONCAT(CAST(int_col AS CHAR), char_col)

⑨插入行
INSERT INTO log_app_operation(app_name,type,user_name,user_group,mac,ip,time,state) VALUES (appname,2,username,groupname,macpar,ippar,now(),0);


①exec 是 EXECUTE  的缩写。

功能是 执行一个存储过程.
或者是 执行一个 动态SQL

 

 

<think>嗯……用户想要查找MySQL学习笔记,而且之前已经提供了三个引用片段作为参考。让我先理解一下用户的需求和上下文。 从用户的问题历史来看,ta似乎正在系统性地学习MySQL,特别是索引、事务隔离级别这些进阶内容。三个引用片段分别涉及多列索引的使用限制(引用1)、索引优化的重要性(引用2)和事务隔离级别的分类(引用3),这些都是MySQL的核心知识点。 用户明确说“我想查找MySQL学习笔记”,但没说具体方向。考虑到ta之前关注的索引和隔离级别,笔记应该覆盖这些深度内容,同时包含基础语法以便复习。可能需要整理成系统化的知识框架。 引用1提到多列索引的字段顺序很重要——这个必须强调,因为跳过第一个字段会使索引失效。引用2指出数据清洗要在update前完成,还提到B-Tree索引的结构原理,这些都应该整合进笔记。引用3关于事务隔离级别的描述很专业,但“未提交读/提交读/可重复读/可串行化”的对比需要更清晰的表格呈现。 用户没有指定笔记形式,但学习笔记最好结构化。我打算分成七部分:基础架构、数据类型、索引(重点展开)、事务、锁机制、优化技巧、备份恢复。其中索引部分要突出引用1的字段顺序限制和引用2的B-Tree原理;事务部分详解引用3的隔离级别。 需要警惕一个细节:引用3提到“可重复读使用MVCC+X锁实现”,但MySQL的InnoDB在可重复读级别下默认用MVCC避免幻读,实际只在写操作加锁。这点要修正说明,避免误导用户。 对了,用户可能还需要对比不同存储引擎(比如InnoDB和MyISAM的事务支持差异),但引用内容没涉及。为免信息过载,先聚焦已有引用关联的知识点,结尾用开放性问题引导用户提出细化需求比较稳妥。 </think>以下是一份系统的MySQL学习笔记整理,涵盖核心概念与实践要点,结合了您提供的引用内容: --- ### **一、MySQL基础架构** 1. **逻辑架构** - 连接层:客户端连接管理、认证 - 服务层:查询解析、优化、缓存(8.0+移除查询缓存) - 存储引擎层:InnoDB(默认)、MyISAM等 --- ### **二、数据类型与表设计** 1. **常见数据类型** - 整型:`INT`、`BIGINT`(注意无符号范围) - 字符型:`VARCHAR`(变长)、`CHAR`(定长) - 时间型:`DATETIME`(精确到秒)、`TIMESTAMP`(时区敏感) 2. **设计原则** - 主键推荐自增整型(避免页分裂[^1]) - 避免`NULL`字段(增加索引复杂度) --- ### **三、索引机制(核心重点)** 1. **索引类型** - **B-Tree索引**(默认结构): - 数据有序存储,支持范围查询 - 适用场景:`=, >, <, BETWEEN, LIKE 'prefix%'`[^2] - 哈希索引:仅精确匹配(Memory引擎) - 全文索引:`FULLTEXT`(文本搜索) 2. **多列索引(联合索引)规则** - 最多支持16个字段 - **最左前缀原则**: ```sql /* 索引 (a,b,c) */ WHERE a=1 AND b=2 -- ✅ 使用索引 WHERE b=2 AND c=3 -- ❌ 无法使用索引(缺少a)[^1] ``` 3. **索引失效场景** - 对索引列进行运算(`WHERE id+1=10`) - 类型转换(字符串列用数字查询) - `LIKE '%suffix'`(前导通配符) --- ### **四、事务与隔离级别** | 隔离级别 | 脏读 | 不可重复读 | 幻读 | 实现机制 | |------------------|------|------------|------|-----------------------------| | 读未提交 (RU) | ✅ | ✅ | ✅ | 无锁 | | 读已提交 (RC) | ❌ | ✅ | ✅ | MVCC(无X锁)[^3] | | 可重复读 (RR) | ❌ | ❌ | ⚠️ | **MVCC+间隙锁**(防幻读) | | 串行化 (Serializable) | ❌ | ❌ | ❌ | 全表锁 | > **说明**: > - InnoDB在RR级别通过**间隙锁**解决幻读问题[^3] > - MVCC通过事务ID和Undo Log实现快照读 --- ### **五、锁机制** 1. **锁类型** - 行级锁:`Record Lock`(单行)、`Gap Lock`(间隙)、`Next-Key Lock`(行+间隙) - 表级锁:`ALTER TABLE`时自动加锁 2. **死锁处理** - 检测机制:等待图(wait-for graph) - 解决策略:回滚代价最小的事务 --- ### **六、性能优化** 1. **SQL优化原则** - 避免`SELECT *`,用覆盖索引 - 数据清洗在应用层完成(如`UPPER()`处理[^2]) - 批量操作代替循环单条处理 2. **Explain工具** - 关注`type`(访问类型):`const > ref > range > index > ALL` - `Extra`字段:`Using index`(覆盖索引)、`Using filesort`(需优化) --- ### **七、备份与恢复** - **逻辑备份**:`mysqldump --single-transaction`(不影响事务) - **物理备份**:Percona XtraBackup(热备份) ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值