数据库高级_软件测试

数据库设计

E-R模型

  • E : 实体: 描述实际的对象,具有相同特征。-- 表
  • R : 联系: 实体之间的关系, 表和表之间的关系
  • 属性: 某方面的特性 – 字段

– 联系:

  • 一对一:
  • 一对多 :多表进行维护, 多这张表某字段来源于 一这张表。
  • 多对多 : 多对多, 找第三张表, 帮助维护他们关系

命令行客户端

  • 连接服务端

    • 打开dos 窗口
      1. 找到Mysql的安装路径
        1. 安装mysql - progromfiles/mysql
        2. 安装PHPstudy : d:/phpstudy/mysql
      2. 在mysql的bin目录下, 文件夹输入 cmd
    • 命令行输入
      • mysql -uroot -p
      • 输入密码
      • 回车
  • 操作数据库
    ---- 命令行结束要用 ; 结束-----

    • 查看所有的数据库信息
      • show databases;
    • 选择使用数据库
      • use 数据库名称
      • use test13
    • 查看当前你使用的数据库
      • select database()
    • 新建数据库
      • create database test1111 charset=utf8;
      • charset: 设置编码格式, utf8 gbk
    • 删除数据库
      • drop database 数据库名称
      • drop database test1111;
  • 操作数据表

    • 查看当前数据库所有表的信息
    • show tables;
    • 查看表结构的信息
      • desc 表名
      • desc students;
    • 查看表的建表语句
      • show create table 表名
      • show create table students;
  • 备份与恢复

    • 备份

      • CMD用管理员权限打开。
      • 到达Mysql的 bin 目录下
        • cd bin目录的路径

          • PHPSTUDEY:
            • d: 回车
            • cd d:/phpstudy/mysql/bin
        • 回车

      • 输入备份命令
        • mysqldump -uroot -p 数据库名称 > test1111.sql
        • mysqldump -uroot -p test13 >test1111.sql
    • 数据库恢复

        1. 新建一个数据库 (编码格式)。
        2. 执行恢复的命令
          1. mysql -uroot -p 新数据库名称 < sql文件名称
            mysql -uroot -p test1111 < test1111.sql

内置函数

  • 字符串函数

    • 字符串拼接 : concat(str1,str2,str3);
    • 截取部分字符
      • select left(‘hellomorning’,4); – 左边四个
      • select right(‘hellomorning’,4); – 右边四个
      • select substring(‘hellomorning’,2,3); – 从第二个字符找3个。
    • 去掉空格
      • ltrim 去掉左边空格
      • rtirm 去掉右边空格
  • 数学函数

    • 四舍五入 round(数字,位数)
    • 求幂次方 pow(x,y)
    • 求随机值 rand()
    • 求π PI();
  • 日期时间函数

    • 获取当前日期
      • Select current_date()
    • 获取当前的时间
      • select current_time()
    • 获取当前的时间+日期
      • select now()
    • 更改日期的样式
      • select dateformat( 日期 , 样式)

流程控制

case语法

根据不同的值, 给出不同的结果.


-- 根据性别不同进行赋值!
select *,case sex
	when '男' then '帅哥'
	when '女' then  '美女' 
	else '保密' end as res
	
from students;

-- 加上一个姓 孙美女  李帅哥!
select *,case sex
	when '男' then concat(left(name,1), ' 帅哥')
	when '女' then  concat(left(name,1),' 美女')
	else '保密' end as res

自定义函数

语法:

create function 函数名称 (参数列表)returns 数据类型
begin
	sql 语句 (retrun )
end
eg:
命令行操作:  delimiter $$
create function rl(str varchar(100)) returns varchar(100)
begin
	return rtrim(ltrim(str));
end

delimiter ;

存储过程

  • 执行一系列的SQL语句, 完成数据的准备工作, 数据的处理工作。

语法:

delimiter //
create procedure 存储过程()
begin
	sql语句
end
//
delimiter ;
eg:
-- 命令行要设置  不是分号运行
delimiter $$
-- 创建存储过程
create procedure proc_st2()
begin
	-- 执行sql语句
	select * from students;
	
end

delimiter ;
  • 重复的 sql 语句的集合,放到存储过程和函数,方便复用
  • 存储过程和函数都存在服务端
  • 减少网络交互,减少网络访问流量

视图

介绍: 将复杂的查询结果存在服务端, 下次直接使用。

语法:
--1 。 创建视图
create view v_视图名称 as
	select 语句
eg:
create view v_sd as
	select s.*,d.deptid as did, d.deptname
	from employees s
	inner join departments d on s.deptid=d.deptid

注意:视图中查询语句返回的结果不能重名的字段
查看视图:查看表会将所有的视图也列出来
show tables;

删除视图
drop view 视图名字;
视图优点

  1. 重复查询, 可以重用。
  2. 放在服务端。
  3. 减少了网络的传输,减少了网络的访问

事务

介绍: 执行一些列的操作, 要么成功, 要么失败恢复初始状态。

  • 全部成功

1、开启事务

‘begin;’

2、修改数据的操作,大乔减少5岁

update students set age=age-5 where name='大乔';

3、提交事务

commit

  • 全部失败

1、开启事务

begin;

2、修改数据的操作

update students set age=age-5 where name='大乔';

3、回滚事务

rollback

索引

语法:

  • 查看索引
    show index from 表名

  • 创建索引

    • 方式一:建表时创建索引
      create table create_index(
      id int primary key,
      name varchar(10) unique,
      age int,
      key (age)
      );

      注意事项:
      key(字段名) – 创建索引
      主键 不能重复 – 自带索引
      name unique 不能重复 – 带索引

    • 方式二:对于已经存在的表,添加索引
      create index 索引的名称 on 病名(字段(长度))

      create index age_index on create_index(age);
      create index name_index on create_index(name(10));
      给某个字段创建了索引,查询时按照那个字段写条件,速度才会快

    • 删除索引:
      drop index 索引名称 on 表名;

索引大大提高了查询速度,同时却会降低更新表的速度

外键

语法:

  • 设置外键约束

方式一:创建数据表的时候设置外键约束

create table stu2(
name varchar(10),
class_id int unsigned,
foreign key(class_id) references class(id)
);

方式二:对于已经存在的数据表设置外键约束

-- 给stu表创建一个外键  class_id 来源于 class 表的id
alter table stu add foreign key (class_id) references class(id);
  • 查看外键

    – 查看建表语句
    show create table stu;

  • 删除外键

    – 删除外键
    alter table stu drop foreign key stu_ibfk_1;

缺点:降低表更新的效率

修改密码

使用root用户连接mysql,密码存在mysql仓库中,在user表中。

1. password 的方法 将密码加密
select password('123456');

2.修改密码, mysql数据库  User表中
update User set password=password('123456') where User='root'

3. 刷新权限
flush privileges;

MySQL操作日志

1.查看日志功能是否打开

show variables like 'general%';

-- 返回日志功能是否开启
-- 返回日志文件的位置

2.打开日志

set global general_log=1;
-- 设置为 1 开启

3.执行SQL语句,观察日志文件的变化
4.使用完日志功能,几时关闭

set global general_log=0;
-- 设置为 0 开启

Redis数据库

1.概念

  • NOSQL :

    • 非关系型数据库
    • 没有表结构
    • 高性能
  • Redis

    • 高性能
    • 键值对形式存储
    • 数据存储在内存

2.服务端与客户端

  1. 启动
    1. redis-server
  2. 关闭
    1. Ctrl+ c
    2. ps -aux |grep ‘redis’
      kill 进程号

客户端:

  1. 连接服务端:
    1. redis-cli
    2. redis-cli --raw 解决中文乱码

Redis切换

  1. 心跳测试 ping
  2. 切换数据库 0-15
    select 0
    select 3

key-value

  • 键值对存储数据
    • 键: 相当于 数据的名称
    • 值: 相当于 存储的数据
  • 键特点:
    • 键不能重复,
    • 数据类型是字符串
  • Redis 常见五种数据类型
    • String
    • 哈希 hash
    • 链表 List
    • 无序集合 set
    • 有序集合 zset

string

介绍:

  • 最基本数据类型
  • 存储任何的数据

增加和修改

-- 增加一个值
set key vale

练习:
增加键值  悟空 
set name1 wukong

-- 增加多个
mset key1 value1 key2 value2 ..

-- 练习
增加 白龙马  唐僧 
mset name2 bailongma name3 tangseng

get key

-- 修改
set key value (已存在的键值)

-- 设置键值对过期时间
setex keyvalue
在多少秒后过期, 键值对不存在

设置10秒键值对
setex name5 10 heihei
get name5

-- 追加
append key 追加的值

孙悟空 增加 齐天大圣
set name5 sunwukong
append name5 qitiandasheng

string获取

-- 获取一个键值对的值
get key

获取地址1的值
get add1

-- 获取多个键值对的值
mget key1 key2

mget add1 add2 add3

键命令

-- 键的查看
1. 通过正则表达式 查看键
keys 正则表达式

-- 查看所有的键
keys *

--查看name 开头的keys
keys name*

--查看包含a的键?
keys *a*

2. 查看键是否存在
exists key1
-- 返回1 代表存在   返回0 代表不存在

exists key1 key2..
-- 返回结果的和
-- 查看键-- 值的数据类型
type key

练习:
type name1

--删除键 -- 
del key

--练习删除 add1
del add1

del key1 key2
--练习 删除 add2  add3
del add2 add3


--2. 设置键有效时间
expire key 时间

-- 练习 设置 user1 10s 过期时间
expire user1 10

--3 查看过期时间是剩余多少
ttl key

-- 练习
查看user1 的有效期剩余时间
ttl user1

-- >=0 返回有效期的时间
-- -2 键无效了, 不存在。
-- -1 键永久有效

hash

介绍: 键值对, 值里面是“键值对”的集合。 方便数据的处理

  • 值里面的“键值对” – 值只能是 字符串, 不能再放键值对。

语法介绍:


1. hash 增加键值
-- 增加单个属性
hset key field value

-- 练习设置老大的属性
hset laoda name liubei
hset laoda wuqi cixiongshuagngujian

-- 增加多个属性
hmset key field1 value1  field2 value2

-- 练习 设置老二的属性
hmset laoer name guanyu color hong wuqi qinglongyanyuedao

-- 修改  对于存在的键值对再次设置
hgetall laoer
2. -- 获取哈希 键值对的信息

-- 1. 获取所有的 属性
	hkeys key
	
	练习 -- 获取老大的属性名
	hkeys laoda

-- 2. 获取所有的 属性值
	hvals key
	
	练习 -- 获取老大的属性值
	hvals laoda
	
-- 3. 获取所有的 一个属性的值
	hget key field
	
	练习 -- 获取老大的姓名
	hget laoda name
	
-- 4. 获取所有的 多个属性的值
	hmget key field1 field2
	
	练习 --获取老大的姓名和颜色
	hmget laoda name color

-- 5. 获取所有的 属性和值
	hgetall key
	
	练习 --获取老大的所有信息
	hgetall laoda
- - 哈希删除
1. 删除整个键
	del key
	
2. 删除键的属性
	hdel key field1 field2
	
	-- 删除老三的姓名和颜色
	hdel laosan name color

list

介绍:

  • 双向链表
  • 按照顺序添加排序
  • 数据类型是 String
1. 增加
-- 从左侧插入
lpush key value1 value2  value3 ..

	练习--从左侧插入123
	lpush l1 1 2 3
	
-- 从右侧插入 
rpush key value1 value2 ..
	练习 --从右侧插入 4 5 6
	rpush l1 4 5 6


-- 从指定位置 前后 插入元素
linsert key before/after 元素  新元素
	
	练习 1的前面插入111 , 后面插入222
	linsert l1 before 1 111
	linsert l1 after 1 222

- 获取的三种方式
   正数从0 左侧开始 增加。
   负数从-1 右侧开始 减少。
   
-- 从左侧获取  正数
 lrange key start stop
 
 	练习: 获取前三个
 	lrange l1 0 2
-- 从右侧获取 负数
	练习 获取后三个
	lrange l1 -3 -1
	
-- 获取全部
	lrange l1 0 -1


-- 修改  根据下标指定位置的元素进行修改
lset key 下标 值

	-- 将第二个改为300
	lset l1 1 300
	-- 将倒数第二个改为500
	lset l1 -2 500
1. 删除指定元素
语法:
	lrem key count value
	count>0 从头到尾
	count<0 从尾到头
	count=0 全部移除
	
	练习: 
	--删除前2 h0
	lrem luser2 2 h0
	
	--删除后2 h1
	lrem luser2 -2 h1
	
	--删除全部h1
	lrem luser2 0 h1

set

介绍:
	1. 无序集合
	2. 元素的值是唯一的不能重复
	3. 没有修改操作

1. 增加
	sadd key member1 member1 .. 
	
	练习 --葫芦增加 大娃 二娃。。。
	sadd hulu dawa erwa  sanwa ..

2. 获取所有的成员信息
	smembers key
	
	练习 --获取葫芦里面所有的成员信息
	smembers hulu
	
3. 删除指定元素
	srem key member1 member2 ..
	
	练习 : -- 删除大娃和二娃
	srem hulu dawa erwa

zest

介绍:

  1. 有序集合
  2. 存储内容STring, 元素唯一不重复
  3. 没有修改操作
  4. 给每个元素分配分数
    1. 分数从小到大排序
    2. 可以相同 可以是负数
1. 增加
	zadd key score1 member1 score2 member2
	
	练习 -- 增加西游师徒四人
	zadd xiyou 1 tangseng 3 bajie 4 shaseng 2 wukong


2. 获取 (顺序)
	zrange key Start stop
	
	练习 --取前2个
	zrange xiyou 0 1 -- 前2
	zrange xiyou 0 -1 --全部
	zrange xiyou -2 -1--后2
	
	
3. 获取 (分数范围)
	zrangebyscore key min max
	
	练习 --获取1 2 之间元素
	zrangebyscore xiyou 1 2
	
	
4. 获取元素的分数值
	zscore key member
	
	练习 -- 获取八戒的分数
	zscore xiyou bajie
1. 删除指定元素(元素值)
	zrem key member1 member2
	
	练习 --删除沙僧
	zrem xiyou shaseng
	
2. 通过分数范围删除元素
	zremrangebyscore key min max
	
	练习 -- 删除 6-10 分数间的元素
	zremrangebyscore xiyou 6 10
package com.bjsxt.servlet; import com.bjsxt.entity.User; import com.bjsxt.service.UserService; import com.bjsxt.service.impl.UserServiceImpl; import javax.servlet.RequestDispatcher; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.*; import java.io.IOException; import java.net.URLEncoder; import java.sql.Date; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class UserServlet extends BaseServlet { // @Override // protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // //解决POST表单的中文乱码问题 // request.setCharacterEncoding("utf-8"); // //接收method属性的值 // String methodName = request.getParameter("method"); // // //根据method属性的值调用相应的方法 // if("login".equals(methodName)){ // this.login(request,response); // }else if("register".equals(methodName)){ // this.register(request,response); // }else if("logout".equals(methodName)){ // this.logout(request,response); // } // // } public void show(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取表单的数据 String userId = request.getParameter("userId"); if(userId == null){ userId = ""; } String strAge = request.getParameter("minAge"); int minAge = 0; try{ minAge = Integer.parseInt(strAge); //"12" "abc" }catch(NumberFormatException e){ e.printStackTrace(); } //调用业务层完成查询操作 UserService userService = new UserServiceImpl(); //List<User> userList = userService.findAll(); List<User> userList = userService.find(userId,minAge); //List<User> userList = null; //List<User> userList = new ArrayList<User>(); //跳转到show.jsp显示数据 request.setAttribute("userId",userId); request.setAttribute("minAge",strAge); request.setAttribute("ulist",userList); request.getRequestDispatcher("/admin/show.jsp").forward(request,response); } public void logout(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //结束当前的session request.getSession().invalidate(); //跳转回登录页面 response.sendRedirect(request.getContextPath()+"/admin/login.jsp"); } public void register(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //request.setCharacterEncoding("utf-8"); //1.接收来自视图层的表单数据 String userId = request.getParameter("userId"); String realName = request.getParameter("realName"); String pwd = request.getParameter("pwd"); String rePwd = request.getParameter("repwd"); int age = Integer.parseInt(request.getParameter("age"));// "23" String [] hobbyArr = request.getParameterValues("hobby"); String strDate = request.getParameter("enterDate");//"1999-12-23" Date enterDate = Date.valueOf(strDate); //util.Date SimpleDateFormat //判断两次密码是否相同 if(pwd == null || !pwd.equals(rePwd)){ request.setAttribute("error","两次密码必须相同"); request.getRequestDispatcher("/admin/register.jsp").forward(request,response); return; } //2.调用业务层完成注册操作并返回结果 User user = new User(userId,realName,pwd,age, Arrays.toString(hobbyArr),enterDate); UserService userService = new UserServiceImpl(); int n = userService.register(user); //3.根据结果进行页面跳转 if(n>0){ response.sendRedirect(request.getContextPath()+"/admin/login.jsp"); }else{ request.setAttribute("error","注册失败"); request.getRequestDispatcher("/admin/register.jsp").forward(request,response); } } public void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //解决POST表单的中文乱码问题 //request.setCharacterEncoding("utf-8"); //获取用户名和密码 request 内建对象 请求 String username = request.getParameter("username"); String password = request.getParameter("password"); String rememberme = request.getParameter("rememberme"); //调用下一层判断登录是否成功,并返回结果 //进行服务器端的表单验证 if(username ==null || "".equals(username)){ request.setAttribute("error","用户名不能为空JSP"); request.getRequestDispatcher("/admin/login.jsp").forward(request,response); return; } if (username.length()<=6){ request.setAttribute("error","用户名长度必须大于6JSP"); request.getRequestDispatcher("/admin/login.jsp").forward(request,response);//后面语句还会执行 return; //后面的语句不再执行 } // boolean flag = false;//默认失败 // if(username.indexOf("sxt")>=0 || username.contains("尚学堂")){ // flag = true; // } User user = null;//默认登录失败 // UserDao userDao = new UserDaoImpl(); // user = userDao.find(username,password); UserService userService = new UserServiceImpl(); user = userService.login(username,password); //userService.addOrder("shoppingCart"); //输出结果 if(user != null){ //登录成功才记住我 //1.办理会员卡 String username2 = URLEncoder.encode(username,"utf-8"); Cookie cookie1 = new Cookie("uname",username2); Cookie cookie2 = new Cookie("password",password); //2.指定会员卡的作用范围,默认范围是当前目录 /servlet/LoginServlet /admin/login.jsp //cookie1.setPath("/"); //当前服务器 cookie1.setPath("/myservlet2/"); //当前项目 cookie2.setPath("/myservlet2"); //3.指定会员卡的作用时间 if("yes".equals(rememberme)){ cookie1.setMaxAge(60*60*24*10); //默认的时间浏览器不关闭的时间;-1 表示一直有效 cookie2.setMaxAge(60*60*24*10); }else{ cookie1.setMaxAge(0); cookie2.setMaxAge(0); } //4.将会员卡带回家 response.addCookie(cookie1); response.addCookie(cookie2); //成功跳转到成功页面 //out.println("登录成功"); // /servlet/LoginServlet // /servlet/success.jsp // request.getRequestDispatcher("/admin/success.jsp").forward(request,response); HttpSession session = request.getSession(); // session.setAttribute("username",username); session.setAttribute("user",user); //response.sendRedirect("/myservlet2/admin/success.jsp"); //response.sendRedirect("https://www.bjsxt.com:443/news/11377.html"); //response.sendRedirect("http://localhost:8080/myservlet2/admin/success.jsp"); //response.sendRedirect("/myservlet2/admin/success.jsp"); //response.sendRedirect("/myservlet2/admin/success.jsp"); //response.sendRedirect(request.getContextPath()+"/admin/success.jsp"); //http://192.168.58.250:8080/myservlet2/servlet/LoginServlet //http://192.168.58.250:8080/myservlet2/admin/success.jsp //登录成功后,网站的访问人数+1 //1.获取当前的访问人数 ServletContext context = this.getServletContext(); Integer count2 = (Integer) context.getAttribute("count"); //2.人数+1 if(count2 == null){ //第一个用户 count2 = 1; }else{ count2++; } //3.再存放到application作用域中 context.setAttribute("count",count2); //http://192.168.58.250:8080/myservlet2/servlet/admin/success.jsp response.sendRedirect("../admin/success.jsp"); }else{ //失败跳转回登录页面 //out.println("登录失败"); request.setAttribute("error","用户名或者密码错误"); // RequestDispatcher rd = request.getRequestDispatcher("/admin/login.jsp"); // rd.forward(request,response); //RequestDispatcher rd = request.getRequestDispatcher("http://localhost:8080/myservlet2/admin/login.jsp"); //RequestDispatcher rd = request.getRequestDispatcher("/admin/login.jsp"); //http://192.168.58.250:8080/myservlet2/servlet/admin/login.jsp RequestDispatcher rd = request.getRequestDispatcher("../admin/login.jsp"); rd.forward(request,response); } } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值